├── .appveyor.yml ├── .ci └── nunit.sh ├── .github ├── ISSUE_TEMPLATE.md └── workflows │ └── dotnet.yml ├── .gitignore ├── .vscode ├── settings.json └── tasks.json ├── Directory.Build.props ├── Directory.Build.targets ├── DocsSrc ├── logo.png ├── styles │ ├── img │ │ ├── github-blue.png │ │ └── github.png │ ├── style.css │ ├── style_light.css │ └── tips.js └── templates │ ├── docpage.cshtml │ ├── reference │ ├── module.cshtml │ ├── namespaces.cshtml │ ├── part-members.cshtml │ ├── part-nested.cshtml │ └── type.cshtml │ └── template.cshtml ├── FSharp.Interop.Dynamic.sln ├── FSharp.Interop.Dynamic.sln.DotSettings ├── FSharp.Interop.Dynamic ├── Dyn.fs ├── Dyn.fsi ├── FSharp.Interop.Dynamic.fsproj ├── Operators.fs ├── Operators.fsi ├── SymbolicString.fs ├── TopLevelOperators.fs └── TopLevelOperators.fsi ├── License.txt ├── NuGet.config ├── README.md ├── Scripts ├── GenerateDocumentation.fsx ├── paket.dependencies └── paket.lock ├── Tests ├── Library1.fs ├── Main.fs ├── Obsolete.fs ├── Raw.fs └── Tests.fsproj ├── after.FSharp.Interop.Dynamic.sln.targets ├── build.fsx ├── docs ├── content │ ├── img │ │ ├── github-blue.png │ │ └── github.png │ ├── style.css │ ├── style_light.css │ └── tips.js ├── examples.html ├── images │ └── logo.png ├── index.html ├── logo.png └── reference │ ├── fsharp-interop-dynamic-calling.html │ ├── fsharp-interop-dynamic-dyn.html │ ├── fsharp-interop-dynamic-operators.html │ ├── fsharp-interop-dynamic-symbolicstring-leafinfo.html │ ├── fsharp-interop-dynamic-symbolicstring-symbol.html │ ├── fsharp-interop-dynamic-symbolicstring.html │ ├── fsharp-interop-dynamic-topleveloperators.html │ └── index.html └── monofx.props /.appveyor.yml: -------------------------------------------------------------------------------- 1 | image: Visual Studio 2019 2 | 3 | version: "{build}" #until it gets updated at install 4 | configuration: Debug 5 | 6 | environment: 7 | base_version: 5.0.1 8 | github_deploy: false 9 | is_prerelease: true 10 | package_version: $(BASE_VERSION)-alpha$(APPVEYOR_BUILD_NUMBER) 11 | COVERALLS_REPO_TOKEN: 12 | secure: WxjMN6xCAGad/rRS7HwDOhcXgXRnvrXZKYZkBK27iHGu6PcTf2YI6dlhBikAi/8n 13 | build: off 14 | test: off 15 | 16 | install: 17 | - ps: Update-AppveyorBuild -Version "$env:PACKAGE_VERSION" 18 | - ps: dotnet restore /p:Version="$Env:APPVEYOR_BUILD_VERSION" 19 | - ps: nuget install coveralls.net -Version 0.7.0 -OutputDirectory tools -ExcludeVersion 20 | - ps: choco install codecov 21 | build_script: 22 | - ps: dotnet build -c "$Env:CONFIGURATION" /p:Version="$Env:APPVEYOR_BUILD_VERSION" 23 | - ps: dotnet build -c "$Env:CONFIGURATION" /p:Version="$Env:APPVEYOR_BUILD_VERSION" /p:SymbolPackageFormat=symbols.nupkg 24 | test_script: 25 | - ps: dotnet test -c "$Env:CONFIGURATION" /p:Version="$Env:APPVEYOR_BUILD_VERSION" /p:CollectCoverage=true /p:CoverletOutputFormat=opencover 26 | - ps: if (Test-Path env:COVERALLS_REPO_TOKEN) { .\tools\coveralls.net\tools\csmacnz.coveralls.exe --opencover -i Tests/coverage.xml --useRelativePaths --repoToken $env:COVERALLS_REPO_TOKEN --commitId $env:APPVEYOR_REPO_COMMIT --commitBranch $env:APPVEYOR_REPO_BRANCH --commitAuthor $env:APPVEYOR_REPO_COMMIT_AUTHOR --commitEmail $env:APPVEYOR_REPO_COMMIT_AUTHOR_EMAIL --commitMessage $env:APPVEYOR_REPO_COMMIT_MESSAGE --jobId $env:APPVEYOR_BUILD_NUMBER --serviceName appveyor} 27 | - ps: codecov -f Tests/coverage.xml 28 | 29 | artifacts: 30 | - path: 'FSharp.Interop.Dynamic\**\*.*nupkg' 31 | name: NuGet 32 | - path: 'Tests\coverage.*' 33 | name: Coverlet 34 | deploy: 35 | - provider: NuGet 36 | server: https://www.myget.org/F/dynamitey-ci/api/v2/package 37 | api_key: 38 | secure: yKbBrG0QiTfXUvND1/cMMNHxH1Bgal5g7c0pWGwqvjCtKGTtWkpvE2KlZb6E2ZgB 39 | skip_symbols: false 40 | symbol_server: https://www.myget.org/F/dynamitey-ci/symbols/api/v2/package 41 | artifact: /.*\.nupkg/ 42 | - provider: GitHub 43 | artifact: /.*\.[s]?nupkg/ # upload all NuGet packages to release assets 44 | tag: v$(PACKAGE_VERSION) 45 | description: 'Release description' 46 | auth_token: 47 | secure: sAkwkj/uWppL6/hBqda0g4SQ4OZ1cUDSe3Sf7jiHovAdQlizMunbVA8FQL5tPw6U #jay's public repo token 48 | draft: true 49 | prerelease: $(is_prerelease) 50 | on: 51 | github_deploy: true 52 | 53 | 54 | for: 55 | - branches: 56 | only: 57 | - /deploy-v.*-beta.*/ 58 | environment: 59 | package_version: $(BASE_VERSION)-beta$(APPVEYOR_BUILD_NUMBER) 60 | is_prerelease: true 61 | github_deploy: true 62 | - branches: 63 | only: 64 | - /deploy-v[\d,.]*/ 65 | configuration: Release 66 | environment: 67 | package_version: $(BASE_VERSION).$(APPVEYOR_BUILD_NUMBER) 68 | is_prerelease: false 69 | github_deploy: true 70 | -------------------------------------------------------------------------------- /.ci/nunit.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -x 2 | 3 | mono --runtime=v4.0 .nuget/NuGet.exe install NUnit.Runners -Version 2.6.4 -o packages 4 | 5 | runTest(){ 6 | mono --runtime=v4.0 packages/NUnit.Runners.2.6.4/tools/nunit-console.exe -noxml -nodots -labels -stoponerror $@ 7 | if [ $? -ne 0 ] 8 | then 9 | exit 1 10 | fi 11 | } 12 | 13 | runTest $1 -exclude=Performance 14 | 15 | exit $? -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### Description 2 | 3 | Please provide a succinct description of your issue. 4 | 5 | ### Repro steps 6 | 7 | Please provide the steps required to reproduce the problem 8 | 9 | 1. Step A 10 | 11 | 2. Step B 12 | 13 | ### Expected behavior 14 | 15 | Please provide a description of the behavior you expect. 16 | 17 | ### Actual behavior 18 | 19 | Please provide a description of the actual behavior you observe. 20 | 21 | ### Known workarounds 22 | 23 | Please provide a description of any known workarounds. 24 | 25 | ### Related information 26 | 27 | * Operating system 28 | * Branch 29 | * .NET Runtime, CoreCLR or Mono Version 30 | * Performance information, links to performance testing scripts 31 | -------------------------------------------------------------------------------- /.github/workflows/dotnet.yml: -------------------------------------------------------------------------------- 1 | name: .NET Core CI 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | name: ${{ matrix.os }}/dotnet ${{ matrix.dotnet }} 8 | runs-on: ${{ matrix.os }} 9 | strategy: 10 | matrix: 11 | os: [ubuntu-latest, windows-latest, macOS-latest] 12 | dotnet: [2.1.802, 3.0.100] 13 | include: 14 | - dotnet: 2.1.802 15 | target: netcoreapp2.1 16 | - dotnet: 3.0.100 17 | target: netcoreapp3.0 18 | steps: 19 | - uses: actions/checkout@v1 20 | - name: Setup .NET Core 21 | uses: actions/setup-dotnet@v1 22 | with: 23 | dotnet-version: ${{ matrix.dotnet }} 24 | - name: Restore NuGet 25 | env: 26 | TestingTarget: ${{ matrix.target }} 27 | run: dotnet restore 28 | - name: Build with dotnet ${{ matrix.dotnet }} 29 | env: 30 | TestingTarget: ${{ matrix.target }} 31 | run: dotnet build 32 | - name: Test with xUnit 33 | env: 34 | TestingTarget: ${{ matrix.target }} 35 | run: dotnet test --no-build 36 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.sln.docstates 8 | 9 | # Build results 10 | 11 | [Dd]ebug/ 12 | [Rr]elease/ 13 | x64/ 14 | build/ 15 | [Bb]in/ 16 | [Oo]bj/ 17 | 18 | # MSTest test Results 19 | [Tt]est[Rr]esult*/ 20 | [Bb]uild[Ll]og.* 21 | 22 | *_i.c 23 | *_p.c 24 | *.ilk 25 | *.meta 26 | *.obj 27 | *.pch 28 | *.pdb 29 | *.pgc 30 | *.pgd 31 | *.rsp 32 | *.sbr 33 | *.tlb 34 | *.tli 35 | *.tlh 36 | *.tmp 37 | *.tmp_proj 38 | *.log 39 | *.vspscc 40 | *.vssscc 41 | .builds 42 | *.pidb 43 | *.log 44 | *.scc 45 | 46 | # Visual C++ cache files 47 | ipch/ 48 | *.aps 49 | *.ncb 50 | *.opensdf 51 | *.sdf 52 | *.cachefile 53 | 54 | # Visual Studio profiler 55 | *.psess 56 | *.vsp 57 | *.vspx 58 | 59 | # Guidance Automation Toolkit 60 | *.gpState 61 | 62 | # ReSharper is a .NET coding add-in 63 | _ReSharper*/ 64 | *.[Rr]e[Ss]harper 65 | 66 | # TeamCity is a build add-in 67 | _TeamCity* 68 | 69 | # DotCover is a Code Coverage Tool 70 | *.dotCover 71 | 72 | # NCrunch 73 | *.ncrunch* 74 | .*crunch*.local.xml 75 | 76 | # Installshield output folder 77 | [Ee]xpress/ 78 | 79 | # DocProject is a documentation generator add-in 80 | DocProject/buildhelp/ 81 | DocProject/Help/*.HxT 82 | DocProject/Help/*.HxC 83 | DocProject/Help/*.hhc 84 | DocProject/Help/*.hhk 85 | DocProject/Help/*.hhp 86 | DocProject/Help/Html2 87 | DocProject/Help/html 88 | 89 | # Click-Once directory 90 | publish/ 91 | 92 | # Publish Web Output 93 | *.Publish.xml 94 | *.pubxml 95 | 96 | # NuGet Packages Directory 97 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 98 | packages/ 99 | 100 | # Windows Azure Build Output 101 | csx 102 | *.build.csdef 103 | 104 | # Windows Store app package directory 105 | AppPackages/ 106 | 107 | # Others 108 | sql/ 109 | *.Cache 110 | ClientBin/ 111 | [Ss]tyle[Cc]op.* 112 | ~$* 113 | *~ 114 | *.dbmdl 115 | *.[Pp]ublish.xml 116 | *.pfx 117 | *.publishsettings 118 | 119 | # RIA/Silverlight projects 120 | Generated_Code/ 121 | 122 | # Backup & report files from converting an old project file to a newer 123 | # Visual Studio version. Backup files are not needed, because we have git ;-) 124 | _UpgradeReport_Files/ 125 | Backup*/ 126 | UpgradeLog*.XML 127 | UpgradeLog*.htm 128 | 129 | # SQL Server files 130 | App_Data/*.mdf 131 | App_Data/*.ldf 132 | 133 | # ========================= 134 | # Windows detritus 135 | # ========================= 136 | 137 | # Windows image file caches 138 | Thumbs.db 139 | ehthumbs.db 140 | 141 | # Folder config file 142 | Desktop.ini 143 | 144 | # Recycle Bin used on file shares 145 | $RECYCLE.BIN/ 146 | 147 | # Mac crap 148 | .DS_Store 149 | 150 | # JetBrains Rider 151 | .idea/**/.idea/* 152 | .idea/**/*.iml 153 | 154 | !.idea/**/runConfigurations/ 155 | !.idea/**/runConfigurations/* 156 | 157 | .fake/ 158 | .nuget/NuGet.exe 159 | *.userprefs 160 | .ionide/ -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "0.1.0", 5 | "command": "./build.fsx", 6 | "isShellCommand": true, 7 | "args": [], 8 | "showOutput": "always", 9 | "problemMatcher":"$msCompile" 10 | } -------------------------------------------------------------------------------- /Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | True 4 | 5 | 6 | -------------------------------------------------------------------------------- /Directory.Build.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /DocsSrc/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsprojects/FSharp.Interop.Dynamic/c967f0fd067f28c9ca8c9d0ee085d7d3c4166714/DocsSrc/logo.png -------------------------------------------------------------------------------- /DocsSrc/styles/img/github-blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsprojects/FSharp.Interop.Dynamic/c967f0fd067f28c9ca8c9d0ee085d7d3c4166714/DocsSrc/styles/img/github-blue.png -------------------------------------------------------------------------------- /DocsSrc/styles/img/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsprojects/FSharp.Interop.Dynamic/c967f0fd067f28c9ca8c9d0ee085d7d3c4166714/DocsSrc/styles/img/github.png -------------------------------------------------------------------------------- /DocsSrc/styles/style.css: -------------------------------------------------------------------------------- 1 | @import url(https://cdn.rawgit.com/tonsky/FiraCode/1.205/distr/fira_code.css); 2 | @import url(https://fonts.googleapis.com/css?family=Droid+Sans|Droid+Sans+Mono|Open+Sans:400,600,700); 3 | 4 | /*-------------------------------------------------------------------------- 5 | Formatting for F# code snippets 6 | /*--------------------------------------------------------------------------*/ 7 | 8 | /* strings --- and stlyes for other string related formats */ 9 | span.s { color:#E0E268; } 10 | /* printf formatters */ 11 | span.pf { color:#E0C57F; } 12 | /* escaped chars */ 13 | span.e { color:#EA8675; } 14 | 15 | /* identifiers --- and styles for more specific identifier types */ 16 | span.id { color:#d1d1d1; } 17 | /* module */ 18 | span.m { color:#43AEC6; } 19 | /* reference type */ 20 | span.rt { color:#43AEC6; } 21 | /* value type */ 22 | span.vt { color:#43AEC6; } 23 | /* interface */ 24 | span.if{ color:#43AEC6; } 25 | /* type argument */ 26 | span.ta { color:#43AEC6; } 27 | /* disposable */ 28 | span.d { color:#43AEC6; } 29 | /* property */ 30 | span.prop { color:#43AEC6; } 31 | /* punctuation */ 32 | span.p { color:#43AEC6; } 33 | /* function */ 34 | span.f { color:#e1e1e1; } 35 | /* active pattern */ 36 | span.pat { color:#4ec9b0; } 37 | /* union case */ 38 | span.u { color:#4ec9b0; } 39 | /* enumeration */ 40 | span.e { color:#4ec9b0; } 41 | /* keywords */ 42 | span.k { color:#FAB11D; } 43 | /* comment */ 44 | span.c { color:#808080; } 45 | /* operators */ 46 | span.o { color:#af75c1; } 47 | /* numbers */ 48 | span.n { color:#96C71D; } 49 | /* line number */ 50 | span.l { color:#80b0b0; } 51 | /* mutable var or ref cell */ 52 | span.v { color:#d1d1d1; font-weight: bold; } 53 | /* inactive code */ 54 | span.inactive { color:#808080; } 55 | /* preprocessor */ 56 | span.prep { color:#af75c1; } 57 | /* fsi output */ 58 | span.fsi { color:#808080; } 59 | 60 | /* omitted */ 61 | span.omitted { 62 | background:#3c4e52; 63 | border-radius:5px; 64 | color:#808080; 65 | padding:0px 0px 1px 0px; 66 | } 67 | /* tool tip */ 68 | div.tip { 69 | background:#475b5f; 70 | border-radius:4px; 71 | font:11pt 'Droid Sans', arial, sans-serif; 72 | padding:6px 8px 6px 8px; 73 | display:none; 74 | color:#d1d1d1; 75 | pointer-events:none; 76 | } 77 | table.pre pre { 78 | padding:0px; 79 | margin:0px; 80 | border:none; 81 | } 82 | table.pre, pre.fssnip, pre { 83 | line-height:13pt; 84 | border:1px solid #d8d8d8; 85 | border-collapse:separate; 86 | white-space:pre; 87 | font: 9pt 'Fira Code','Droid Sans Mono',consolas,monospace; 88 | width:90%; 89 | margin:10px 20px 20px 20px; 90 | background-color:#212d30; 91 | padding:10px; 92 | border-radius:5px; 93 | color:#d1d1d1; 94 | max-width: none; 95 | } 96 | pre.fssnip code { 97 | font: 9pt 'Fira Code','Droid Sans Mono',consolas,monospace; 98 | } 99 | table.pre pre { 100 | padding:0px; 101 | margin:0px; 102 | border-radius:0px; 103 | width: 100%; 104 | } 105 | table.pre td { 106 | padding:0px; 107 | white-space:normal; 108 | margin:0px; 109 | } 110 | table.pre td.lines { 111 | width:30px; 112 | } 113 | 114 | /*-------------------------------------------------------------------------- 115 | Formatting for page & standard document content 116 | /*--------------------------------------------------------------------------*/ 117 | 118 | body { 119 | font-family: 'Open Sans', serif; 120 | padding-top: 0px; 121 | padding-bottom: 40px; 122 | } 123 | 124 | pre { 125 | word-wrap: inherit; 126 | } 127 | 128 | /* Format the heading - nicer spacing etc. */ 129 | .masthead { 130 | overflow: hidden; 131 | } 132 | .masthead .muted a { 133 | text-decoration:none; 134 | color:#999999; 135 | } 136 | .masthead ul, .masthead li { 137 | margin-bottom:0px; 138 | } 139 | .masthead .nav li { 140 | margin-top: 15px; 141 | font-size:110%; 142 | } 143 | .masthead h3 { 144 | margin-bottom:5px; 145 | font-size:170%; 146 | } 147 | hr { 148 | margin:0px 0px 20px 0px; 149 | } 150 | 151 | /* Make table headings and td.title bold */ 152 | td.title, thead { 153 | font-weight:bold; 154 | } 155 | 156 | /* Format the right-side menu */ 157 | #menu { 158 | margin-top:50px; 159 | font-size:11pt; 160 | padding-left:20px; 161 | } 162 | 163 | #menu .nav-header { 164 | font-size:12pt; 165 | color:#606060; 166 | margin-top:20px; 167 | } 168 | 169 | #menu li { 170 | line-height:25px; 171 | } 172 | 173 | /* Change font sizes for headings etc. */ 174 | #main h1 { font-size: 26pt; margin:10px 0px 15px 0px; font-weight:400; } 175 | #main h2 { font-size: 20pt; margin:20px 0px 0px 0px; font-weight:400; } 176 | #main h3 { font-size: 14pt; margin:15px 0px 0px 0px; font-weight:600; } 177 | #main p { font-size: 11pt; margin:5px 0px 15px 0px; } 178 | #main ul { font-size: 11pt; margin-top:10px; } 179 | #main li { font-size: 11pt; margin: 5px 0px 5px 0px; } 180 | #main strong { font-weight:700; } 181 | 182 | /*-------------------------------------------------------------------------- 183 | Formatting for API reference 184 | /*--------------------------------------------------------------------------*/ 185 | 186 | .type-list .type-name, .module-list .module-name { 187 | width:25%; 188 | font-weight:bold; 189 | } 190 | .member-list .member-name { 191 | width:35%; 192 | } 193 | #main .xmldoc h2 { 194 | font-size:14pt; 195 | margin:10px 0px 0px 0px; 196 | } 197 | #main .xmldoc h3 { 198 | font-size:12pt; 199 | margin:10px 0px 0px 0px; 200 | } 201 | .github-link { 202 | float:right; 203 | text-decoration:none; 204 | } 205 | .github-link img { 206 | border-style:none; 207 | margin-left:10px; 208 | } 209 | .github-link .hover { display:none; } 210 | .github-link:hover .hover { display:block; } 211 | .github-link .normal { display: block; } 212 | .github-link:hover .normal { display: none; } 213 | 214 | /*-------------------------------------------------------------------------- 215 | Links 216 | /*--------------------------------------------------------------------------*/ 217 | 218 | h1 a, h1 a:hover, h1 a:focus, 219 | h2 a, h2 a:hover, h2 a:focus, 220 | h3 a, h3 a:hover, h3 a:focus, 221 | h4 a, h4 a:hover, h4 a:focus, 222 | h5 a, h5 a:hover, h5 a:focus, 223 | h6 a, h6 a:hover, h6 a:focus { color : inherit; text-decoration : inherit; outline:none } 224 | 225 | /*-------------------------------------------------------------------------- 226 | Additional formatting for the homepage 227 | /*--------------------------------------------------------------------------*/ 228 | 229 | #nuget { 230 | margin-top:20px; 231 | font-size: 11pt; 232 | padding:20px; 233 | } 234 | 235 | #nuget pre { 236 | font-size:11pt; 237 | -moz-border-radius: 0px; 238 | -webkit-border-radius: 0px; 239 | border-radius: 0px; 240 | background: #404040; 241 | border-style:none; 242 | color: #e0e0e0; 243 | margin-top:15px; 244 | } 245 | -------------------------------------------------------------------------------- /DocsSrc/styles/style_light.css: -------------------------------------------------------------------------------- 1 | @import url(https://fonts.googleapis.com/css?family=Droid+Sans|Droid+Sans+Mono|Open+Sans:400,600,700); 2 | 3 | /*-------------------------------------------------------------------------- 4 | Formatting for F# code snippets 5 | /*--------------------------------------------------------------------------*/ 6 | 7 | /* identifier */ 8 | span.i { color:#000000; } 9 | /* string */ 10 | span.s { color:#a31515; } 11 | /* keywords */ 12 | span.k { color:#0000ff; } 13 | /* comment */ 14 | span.c { color:#008000; } 15 | /* operators */ 16 | span.o { color:#000000; } 17 | /* numbers */ 18 | span.n { color:#000000; } 19 | /* line number */ 20 | span.l { color:#96c2cd; } 21 | /* type or module */ 22 | span.t { color:#2b91af; } 23 | /* function */ 24 | span.f { color:#0000a0; } 25 | /* DU case or active pattern */ 26 | span.p { color:#800080; } 27 | /* mutable var or ref cell */ 28 | span.v { color:#000000; font-weight: bold; } 29 | /* printf formatters */ 30 | span.pf { color:#2b91af; } 31 | /* escaped chars */ 32 | span.e { color:#ff0080; } 33 | /* mutable var or ref cell */ 34 | 35 | 36 | /* inactive code */ 37 | span.inactive { color:#808080; } 38 | /* preprocessor */ 39 | span.prep { color:#0000ff; } 40 | /* fsi output */ 41 | span.fsi { color:#808080; } 42 | 43 | /* omitted */ 44 | span.omitted { 45 | background:#3c4e52; 46 | border-radius:5px; 47 | color:#808080; 48 | padding:0px 0px 1px 0px; 49 | } 50 | /* tool tip */ 51 | div.tip { 52 | background:#e5e5e5; 53 | border-radius:4px; 54 | font:9pt 'Droid Sans', arial, sans-serif; 55 | padding:6px 8px 6px 8px; 56 | display:none; 57 | color:#000000; 58 | pointer-events:none; 59 | } 60 | table.pre pre { 61 | padding:0px; 62 | margin:0px; 63 | border:none; 64 | } 65 | table.pre, pre.fssnip, pre { 66 | line-height:13pt; 67 | border:1px solid #d8d8d8; 68 | border-collapse:separate; 69 | white-space:pre; 70 | font: 10pt consolas,monospace; 71 | width:90%; 72 | margin:10px 20px 20px 20px; 73 | background-color:#fdfdfd; 74 | padding:10px; 75 | border-radius:5px; 76 | color:#000000; 77 | max-width: none; 78 | } 79 | pre.fssnip code { 80 | font: 9pt 'Droid Sans Mono',consolas,monospace; 81 | } 82 | table.pre pre { 83 | padding:0px; 84 | margin:0px; 85 | border-radius:0px; 86 | width: 100%; 87 | } 88 | table.pre td { 89 | padding:0px; 90 | white-space:normal; 91 | margin:0px; 92 | } 93 | table.pre td.lines { 94 | width:30px; 95 | } 96 | 97 | /*-------------------------------------------------------------------------- 98 | Formatting for page & standard document content 99 | /*--------------------------------------------------------------------------*/ 100 | 101 | body { 102 | font-family: 'Open Sans', serif; 103 | padding-top: 0px; 104 | padding-bottom: 40px; 105 | } 106 | 107 | pre { 108 | word-wrap: inherit; 109 | } 110 | 111 | /* Format the heading - nicer spacing etc. */ 112 | .masthead { 113 | overflow: hidden; 114 | } 115 | .masthead .muted a { 116 | text-decoration:none; 117 | color:#999999; 118 | } 119 | .masthead ul, .masthead li { 120 | margin-bottom:0px; 121 | } 122 | .masthead .nav li { 123 | margin-top: 15px; 124 | font-size:110%; 125 | } 126 | .masthead h3 { 127 | margin-bottom:5px; 128 | font-size:170%; 129 | } 130 | hr { 131 | margin:0px 0px 20px 0px; 132 | } 133 | 134 | /* Make table headings and td.title bold */ 135 | td.title, thead { 136 | font-weight:bold; 137 | } 138 | 139 | /* Format the right-side menu */ 140 | #menu { 141 | margin-top:50px; 142 | font-size:11pt; 143 | padding-left:20px; 144 | } 145 | 146 | #menu .nav-header { 147 | font-size:12pt; 148 | color:#606060; 149 | margin-top:20px; 150 | } 151 | 152 | #menu li { 153 | line-height:25px; 154 | } 155 | 156 | /* Change font sizes for headings etc. */ 157 | #main h1 { font-size: 26pt; margin:10px 0px 15px 0px; font-weight:400; } 158 | #main h2 { font-size: 20pt; margin:20px 0px 0px 0px; font-weight:400; } 159 | #main h3 { font-size: 14pt; margin:15px 0px 0px 0px; font-weight:600; } 160 | #main p { font-size: 11pt; margin:5px 0px 15px 0px; } 161 | #main ul { font-size: 11pt; margin-top:10px; } 162 | #main li { font-size: 11pt; margin: 5px 0px 5px 0px; } 163 | #main strong { font-weight:700; } 164 | 165 | /*-------------------------------------------------------------------------- 166 | Formatting for API reference 167 | /*--------------------------------------------------------------------------*/ 168 | 169 | .type-list .type-name, .module-list .module-name { 170 | width:25%; 171 | font-weight:bold; 172 | } 173 | .member-list .member-name { 174 | width:35%; 175 | } 176 | #main .xmldoc h2 { 177 | font-size:14pt; 178 | margin:10px 0px 0px 0px; 179 | } 180 | #main .xmldoc h3 { 181 | font-size:12pt; 182 | margin:10px 0px 0px 0px; 183 | } 184 | .github-link { 185 | float:right; 186 | text-decoration:none; 187 | } 188 | .github-link img { 189 | border-style:none; 190 | margin-left:10px; 191 | } 192 | .github-link .hover { display:none; } 193 | .github-link:hover .hover { display:block; } 194 | .github-link .normal { display: block; } 195 | .github-link:hover .normal { display: none; } 196 | 197 | /*-------------------------------------------------------------------------- 198 | Links 199 | /*--------------------------------------------------------------------------*/ 200 | 201 | h1 a, h1 a:hover, h1 a:focus, 202 | h2 a, h2 a:hover, h2 a:focus, 203 | h3 a, h3 a:hover, h3 a:focus, 204 | h4 a, h4 a:hover, h4 a:focus, 205 | h5 a, h5 a:hover, h5 a:focus, 206 | h6 a, h6 a:hover, h6 a:focus { color : inherit; text-decoration : inherit; outline:none } 207 | 208 | /*-------------------------------------------------------------------------- 209 | Additional formatting for the homepage 210 | /*--------------------------------------------------------------------------*/ 211 | 212 | #nuget { 213 | margin-top:20px; 214 | font-size: 11pt; 215 | padding:20px; 216 | } 217 | 218 | #nuget pre { 219 | font-size:11pt; 220 | -moz-border-radius: 0px; 221 | -webkit-border-radius: 0px; 222 | border-radius: 0px; 223 | background: #404040; 224 | border-style:none; 225 | color: #e0e0e0; 226 | margin-top:15px; 227 | } 228 | -------------------------------------------------------------------------------- /DocsSrc/styles/tips.js: -------------------------------------------------------------------------------- 1 | var currentTip = null; 2 | var currentTipElement = null; 3 | 4 | function hideTip(evt, name, unique) { 5 | var el = document.getElementById(name); 6 | el.style.display = "none"; 7 | currentTip = null; 8 | } 9 | 10 | function findPos(obj) { 11 | // no idea why, but it behaves differently in webbrowser component 12 | if (window.location.search == "?inapp") 13 | return [obj.offsetLeft + 10, obj.offsetTop + 30]; 14 | 15 | var curleft = 0; 16 | var curtop = obj.offsetHeight; 17 | while (obj) { 18 | curleft += obj.offsetLeft; 19 | curtop += obj.offsetTop; 20 | obj = obj.offsetParent; 21 | }; 22 | return [curleft, curtop]; 23 | } 24 | 25 | function hideUsingEsc(e) { 26 | if (!e) { e = event; } 27 | hideTip(e, currentTipElement, currentTip); 28 | } 29 | 30 | function showTip(evt, name, unique, owner) { 31 | document.onkeydown = hideUsingEsc; 32 | if (currentTip == unique) return; 33 | currentTip = unique; 34 | currentTipElement = name; 35 | 36 | var pos = findPos(owner ? owner : (evt.srcElement ? evt.srcElement : evt.target)); 37 | var posx = pos[0]; 38 | var posy = pos[1]; 39 | 40 | var el = document.getElementById(name); 41 | var parent = (document.documentElement == null) ? document.body : document.documentElement; 42 | el.style.position = "absolute"; 43 | el.style.left = posx + "px"; 44 | el.style.top = posy + "px"; 45 | el.style.display = "block"; 46 | } -------------------------------------------------------------------------------- /DocsSrc/templates/docpage.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "template"; 3 | Title = Properties["page-title"]; 4 | Description = Properties["project-summary"]; 5 | } 6 | @Properties["document"] 7 | @Properties["tooltips"] -------------------------------------------------------------------------------- /DocsSrc/templates/reference/module.cshtml: -------------------------------------------------------------------------------- 1 | @using FSharp.MetadataFormat 2 | @{ 3 | Layout = "template"; 4 | Title = Model.Module.Name + " - " + Properties["project-name"]; 5 | } 6 | 7 | @{ 8 | // Get all the members & comment for the type 9 | var members = (IEnumerable)Model.Module.AllMembers; 10 | var comment = (Comment)Model.Module.Comment; 11 | 12 | // Group all members by their category which is an inline annotation 13 | // that can be added to members using special XML comment: 14 | // 15 | // /// [category:Something] 16 | // 17 | // ...and can be used to categorize members in large modules or types 18 | // (but if this is not used, then all members end up in just one category) 19 | var byCategory = members 20 | .GroupBy(m => m.Category) 21 | .OrderBy(g => String.IsNullOrEmpty(g.Key) ? "ZZZ" : g.Key) 22 | .Select((g, n) => new { 23 | Index = n, 24 | GroupKey = g.Key, 25 | Members = g.OrderBy(m => m.Name), 26 | Name = String.IsNullOrEmpty(g.Key) ? "Other module members" : g.Key 27 | }); 28 | 29 | // Get nested modules and nested types as statically typed collections 30 | var nestModules = (IEnumerable)Model.Module.NestedModules; 31 | var nestTypes = (IEnumerable)Model.Module.NestedTypes; 32 | } 33 | 34 |

@Model.Module.Name

35 |

36 | Namespace: @Model.Namespace.Name
37 | @if(Model.ParentModule.Exists()) 38 | { 39 | Parent Module: @Model.ParentModule.Value.Name 40 | } 41 |

42 |
43 | @foreach (var sec in comment.Sections) { 44 | // XML comment for the type has multiple sections that can be labelled 45 | // with categories (to give comment for an individual category). Here, 46 | // we print only those that belong to the section. 47 | if (!byCategory.Any(g => g.GroupKey == sec.Key)) 48 | { 49 | if (sec.Key != "") { 50 |

@sec.Key

51 | } 52 | @sec.Value 53 | } 54 | } 55 |
56 | @if (byCategory.Count() > 1) 57 | { 58 | 59 |

Table of contents

60 |
    61 | @foreach (var g in byCategory) 62 | { 63 |
  • @g.Name
  • 64 | } 65 |
66 | } 67 | 68 | 69 | @if (nestTypes.Count() + nestModules.Count() > 0) 70 | { 71 |

Nested types and modules

72 |
73 | @RenderPart("part-nested", new { 74 | Types = nestTypes, 75 | Modules = nestModules 76 | }) 77 |
78 | } 79 | 80 | @foreach (var g in byCategory) 81 | { 82 | // Iterate over all the categories and print members. If there are more than one 83 | // categories, print the category heading (as

) and add XML comment from the type 84 | // that is related to this specific category. 85 | if (byCategory.Count() > 1) 86 | { 87 |

@g.Name 

88 | var info = comment.Sections.FirstOrDefault(kvp => kvp.Key == g.GroupKey); 89 | if (info.Key != null) 90 | { 91 |
92 | @info.Value 93 |
94 | } 95 | } 96 | 97 | @RenderPart("part-members", new { 98 | Header = "Functions and values", 99 | TableHeader = "Function or value", 100 | Members = g.Members.Where(m => m.Kind == MemberKind.ValueOrFunction) 101 | }) 102 | 103 | @RenderPart("part-members", new { 104 | Header = "Type extensions", 105 | TableHeader = "Type extension", 106 | Members = g.Members.Where(m => m.Kind == MemberKind.TypeExtension) 107 | }) 108 | 109 | @RenderPart("part-members", new { 110 | Header = "Active patterns", 111 | TableHeader = "Active pattern", 112 | Members = g.Members.Where(m => m.Kind == MemberKind.ActivePattern) 113 | }) 114 | } -------------------------------------------------------------------------------- /DocsSrc/templates/reference/namespaces.cshtml: -------------------------------------------------------------------------------- 1 | @using FSharp.MetadataFormat 2 | @{ 3 | Layout = "template"; 4 | Title = "Namespaces - " + Properties["project-name"]; 5 | } 6 | 7 |

@Model.Name

8 | 9 | @{ var nsIndex = 0; } 10 | @foreach (var ns in Model.Namespaces) 11 | { 12 | nsIndex++; 13 | var typedNs = (Namespace)ns; 14 | var allCategories = 15 | typedNs.Types.Select(t => t.Category) 16 | .Concat(typedNs.Modules.Select(m => m.Category)) 17 | .Distinct() 18 | .OrderBy(s => String.IsNullOrEmpty(s) ? "ZZZ" : s); 19 | var allByCategory = 20 | allCategories 21 | .Select((c, i) => new { 22 | Name = String.IsNullOrEmpty(c) ? "Other namespace members" : c, 23 | Index = String.Format("{0}_{1}", nsIndex, i), 24 | Types = typedNs.Types.Where(t => t.Category == c).ToArray(), 25 | Modules = typedNs.Modules.Where(m => m.Category == c).ToArray() }) 26 | .Where(c => c.Types.Length + c.Modules.Length > 0).ToArray(); 27 | 28 |

@ns.Name Namespace

29 | if (allByCategory.Length > 1) 30 | { 31 | 32 |
    33 | @foreach (var g in allByCategory) 34 | { 35 |
  • @g.Name
  • 36 | } 37 |
38 | } 39 | foreach(var g in allByCategory) 40 | { 41 | if (allByCategory.Length > 1) 42 | { 43 |

@g.Name

44 | } 45 |
46 | @RenderPart("part-nested", new 47 | { 48 | Types = g.Types, 49 | Modules = g.Modules 50 | }) 51 |
52 | } 53 | } 54 | -------------------------------------------------------------------------------- /DocsSrc/templates/reference/part-members.cshtml: -------------------------------------------------------------------------------- 1 | @if (Enumerable.Count(Model.Members) > 0) { 2 |

@Model.Header

3 | 4 | 5 | 6 | 7 | 8 | @foreach (var it in Model.Members) 9 | { 10 | 11 | 26 | 40 | 41 | } 42 | 43 |
@Model.TableHeaderDescription
12 | @{ var id = Html.UniqueID().ToString(); } 13 | 14 | @Html.Encode(it.Details.FormatUsage(40)) 15 | 16 |
17 | Signature: @Html.Encode(it.Details.Signature)
18 | @if (!it.Details.Modifiers.IsEmpty) { 19 | Modifiers: @it.Details.FormatModifiers
20 | } 21 | @if (!it.Details.TypeArguments.IsEmpty) { 22 | Type parameters: @it.Details.FormatTypeArguments 23 | } 24 |
25 |
27 | @if (!String.IsNullOrEmpty(it.Details.FormatSourceLocation)) 28 | { 29 | 30 | 31 | 32 | 33 | } 34 | @it.Comment.FullText 35 | @if (!String.IsNullOrEmpty(it.Details.FormatCompiledName)) 36 | { 37 | @:

CompiledName: @it.Details.FormatCompiledName

38 | } 39 |
44 | } 45 | -------------------------------------------------------------------------------- /DocsSrc/templates/reference/part-nested.cshtml: -------------------------------------------------------------------------------- 1 | @if (Enumerable.Count(Model.Types) > 0) { 2 | 3 | 4 | 5 | 6 | 7 | @foreach (var it in Model.Types) 8 | { 9 | 10 | 13 | 14 | 15 | } 16 | 17 |
TypeDescription
11 | @it.Name 12 | @it.Comment.Blurb
18 | } 19 | @if (Enumerable.Count(Model.Modules) > 0) { 20 | 21 | 22 | 23 | 24 | 25 | @foreach (var it in Model.Modules) 26 | { 27 | 28 | 31 | 32 | 33 | } 34 | 35 |
ModuleDescription
29 | @it.Name 30 | @it.Comment.Blurb
36 | } -------------------------------------------------------------------------------- /DocsSrc/templates/reference/type.cshtml: -------------------------------------------------------------------------------- 1 | @using FSharp.MetadataFormat 2 | @{ 3 | Layout = "template"; 4 | Title = Model.Type.Name + " - " + Properties["project-name"]; 5 | } 6 | 7 | @{ 8 | // Get all the members & comment for the type 9 | var members = (IEnumerable)Model.Type.AllMembers; 10 | var comment = (Comment)Model.Type.Comment; 11 | 12 | // Group all members by their category which is an inline annotation 13 | // that can be added to members using special XML comment: 14 | // 15 | // /// [category:Something] 16 | // 17 | // ...and can be used to categorize members in large modules or types 18 | // (but if this is not used, then all members end up in just one category) 19 | var byCategory = members 20 | .GroupBy(m => m.Category) 21 | .OrderBy(g => String.IsNullOrEmpty(g.Key) ? "ZZZ" : g.Key) 22 | .Select((g, n) => new { 23 | Index = n, 24 | GroupKey = g.Key, 25 | Members = g.OrderBy(m => m.Kind == MemberKind.StaticParameter ? "" : m.Name), 26 | Name = String.IsNullOrEmpty(g.Key) ? "Other type members" : g.Key 27 | }); 28 | } 29 | 30 |

@Model.Type.Name

31 |

32 | Namespace: @Model.Namespace.Name
33 | @if(Model.HasParentModule) 34 | { 35 | Parent Module: @Model.ParentModule.Value.Name 36 | } 37 |

38 |
39 | @foreach (var sec in comment.Sections) { 40 | // XML comment for the type has multiple sections that can be labelled 41 | // with categories (to give comment for an individual category). Here, 42 | // we print only those that belong to the section. 43 | if (!byCategory.Any(g => g.GroupKey == sec.Key)) { 44 | if (sec.Key != "") { 45 |

@sec.Key

46 | } 47 | @sec.Value 48 | } 49 | } 50 |
51 | @if (byCategory.Count() > 1) 52 | { 53 | 54 |

Table of contents

55 |
    56 | @foreach (var g in byCategory) 57 | { 58 |
  • @g.Name
  • 59 | } 60 |
61 | } 62 | @foreach (var g in byCategory) { 63 | // Iterate over all the categories and print members. If there are more than one 64 | // categories, print the category heading (as

) and add XML comment from the type 65 | // that is related to this specific category. 66 | if (byCategory.Count() > 1) { 67 |

@g.Name 

68 | var info = comment.Sections.FirstOrDefault(kvp => kvp.Key == g.GroupKey); 69 | if (info.Key != null) { 70 |
71 | @info.Value 72 |
73 | } 74 | } 75 | 76 | @RenderPart("part-members", new { 77 | Header = "Union Cases", 78 | TableHeader = "Union Case", 79 | Members = g.Members.Where(m => m.Kind == MemberKind.UnionCase) 80 | }) 81 | 82 | @RenderPart("part-members", new { 83 | Header = "Record Fields", 84 | TableHeader = "Record Field", 85 | Members = g.Members.Where(m => m.Kind == MemberKind.RecordField) 86 | }) 87 | 88 | @RenderPart("part-members", new { 89 | Header = "Static parameters", 90 | TableHeader = "Static parameters", 91 | Members = g.Members.Where(m => m.Kind == MemberKind.StaticParameter) 92 | }) 93 | 94 | @RenderPart("part-members", new { 95 | Header = "Constructors", 96 | TableHeader = "Constructor", 97 | Members = g.Members.Where(m => m.Kind == MemberKind.Constructor) 98 | }) 99 | 100 | @RenderPart("part-members", new { 101 | Header = "Instance members", 102 | TableHeader = "Instance member", 103 | Members = g.Members.Where(m => m.Kind == MemberKind.InstanceMember) 104 | }) 105 | 106 | @RenderPart("part-members", new { 107 | Header = "Static members", 108 | TableHeader = "Static member", 109 | Members = g.Members.Where(m => m.Kind == MemberKind.StaticMember) 110 | }) 111 | } 112 | -------------------------------------------------------------------------------- /DocsSrc/templates/template.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | @Title 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 23 | 24 | 25 |
26 | 33 |
34 |
35 |
36 | @RenderBody() 37 |
38 |
39 | 40 | 41 | 42 | 43 | 62 |
63 |
64 |
65 | Fork me on GitHub 66 | 67 | 68 | -------------------------------------------------------------------------------- /FSharp.Interop.Dynamic.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26124.0 5 | MinimumVisualStudioVersion = 15.0.26124.0 6 | Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Interop.Dynamic", "FSharp.Interop.Dynamic\FSharp.Interop.Dynamic.fsproj", "{40AC8088-ED10-4E95-ACDA-83EF68EFB078}" 7 | EndProject 8 | Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Tests", "Tests\Tests.fsproj", "{888FB16E-2B09-4C2E-9D65-EAAEEAC7D51F}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Debug|x64 = Debug|x64 14 | Debug|x86 = Debug|x86 15 | Release|Any CPU = Release|Any CPU 16 | Release|x64 = Release|x64 17 | Release|x86 = Release|x86 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 23 | {40AC8088-ED10-4E95-ACDA-83EF68EFB078}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 24 | {40AC8088-ED10-4E95-ACDA-83EF68EFB078}.Debug|Any CPU.Build.0 = Debug|Any CPU 25 | {40AC8088-ED10-4E95-ACDA-83EF68EFB078}.Debug|x64.ActiveCfg = Debug|x64 26 | {40AC8088-ED10-4E95-ACDA-83EF68EFB078}.Debug|x64.Build.0 = Debug|x64 27 | {40AC8088-ED10-4E95-ACDA-83EF68EFB078}.Debug|x86.ActiveCfg = Debug|x86 28 | {40AC8088-ED10-4E95-ACDA-83EF68EFB078}.Debug|x86.Build.0 = Debug|x86 29 | {40AC8088-ED10-4E95-ACDA-83EF68EFB078}.Release|Any CPU.ActiveCfg = Release|Any CPU 30 | {40AC8088-ED10-4E95-ACDA-83EF68EFB078}.Release|Any CPU.Build.0 = Release|Any CPU 31 | {40AC8088-ED10-4E95-ACDA-83EF68EFB078}.Release|x64.ActiveCfg = Release|x64 32 | {40AC8088-ED10-4E95-ACDA-83EF68EFB078}.Release|x64.Build.0 = Release|x64 33 | {40AC8088-ED10-4E95-ACDA-83EF68EFB078}.Release|x86.ActiveCfg = Release|x86 34 | {40AC8088-ED10-4E95-ACDA-83EF68EFB078}.Release|x86.Build.0 = Release|x86 35 | {888FB16E-2B09-4C2E-9D65-EAAEEAC7D51F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 36 | {888FB16E-2B09-4C2E-9D65-EAAEEAC7D51F}.Debug|Any CPU.Build.0 = Debug|Any CPU 37 | {888FB16E-2B09-4C2E-9D65-EAAEEAC7D51F}.Debug|x64.ActiveCfg = Debug|x64 38 | {888FB16E-2B09-4C2E-9D65-EAAEEAC7D51F}.Debug|x64.Build.0 = Debug|x64 39 | {888FB16E-2B09-4C2E-9D65-EAAEEAC7D51F}.Debug|x86.ActiveCfg = Debug|x86 40 | {888FB16E-2B09-4C2E-9D65-EAAEEAC7D51F}.Debug|x86.Build.0 = Debug|x86 41 | {888FB16E-2B09-4C2E-9D65-EAAEEAC7D51F}.Release|Any CPU.ActiveCfg = Release|Any CPU 42 | {888FB16E-2B09-4C2E-9D65-EAAEEAC7D51F}.Release|Any CPU.Build.0 = Release|Any CPU 43 | {888FB16E-2B09-4C2E-9D65-EAAEEAC7D51F}.Release|x64.ActiveCfg = Release|x64 44 | {888FB16E-2B09-4C2E-9D65-EAAEEAC7D51F}.Release|x64.Build.0 = Release|x64 45 | {888FB16E-2B09-4C2E-9D65-EAAEEAC7D51F}.Release|x86.ActiveCfg = Release|x86 46 | {888FB16E-2B09-4C2E-9D65-EAAEEAC7D51F}.Release|x86.Build.0 = Release|x86 47 | EndGlobalSection 48 | EndGlobal 49 | -------------------------------------------------------------------------------- /FSharp.Interop.Dynamic.sln.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | <data><IncludeFilters /><ExcludeFilters /></data> 3 | <data /> -------------------------------------------------------------------------------- /FSharp.Interop.Dynamic/Dyn.fs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2011 Ekon Benefits 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | 17 | namespace FSharp.Interop.Dynamic 18 | open System 19 | 20 | type Calling = 21 | | GenericMember of string * Type array 22 | | Member of string 23 | | Direct 24 | 25 | module Dyn = 26 | open Dynamitey 27 | open Microsoft.CSharp.RuntimeBinder 28 | open FSharp.Reflection 29 | 30 | let staticContext (target:Type) = InvokeContext.CreateStatic.Invoke(target) 31 | 32 | let staticTarget<'TTarget> = InvokeContext.CreateStatic.Invoke(typeof<'TTarget>) 33 | 34 | let implicitConvertTo (convertType:Type) (target:obj) : 'TResult = 35 | match target with 36 | | null -> target 37 | | t -> Dynamic.InvokeConvert(t, convertType, explicit = false) 38 | |> unbox<'TResult> 39 | 40 | 41 | let implicitConvert(target:obj) : 'TResult = 42 | implicitConvertTo typeof<'TResult> target 43 | 44 | 45 | let explicitConvertTo (convertType:Type) (target:obj) : 'TResult = 46 | Dynamic.InvokeConvert(target, convertType, explicit = true) |> unbox<'TResult> 47 | 48 | let explicitConvert (target:obj) : 'TResult = 49 | explicitConvertTo typeof<'TResult> target 50 | 51 | let namedArg (name:string) (argValue:obj) = 52 | InvokeArg(name, argValue) 53 | 54 | let memberAddAssign (memberName:string) (value:obj) (target:obj) = 55 | Dynamic.InvokeAddAssignMember(target, memberName, value) 56 | 57 | 58 | let memberSubtractAssign (memberName:string) (value:obj) (target:obj) = 59 | Dynamic.InvokeSubtractAssignMember(target, memberName, value) 60 | 61 | 62 | let invocation (target:obj) (memberName:Calling) : 'TResult = 63 | let resultType = typeof<'TResult> 64 | //Helper to dynamically call call FSharpFuncs 65 | let fsharpInvoke target' memberName' arg' = 66 | let invokeName = InvokeMemberName("Invoke", null) //FSharpFunc Invoke 67 | let invokeContext t = InvokeContext(t, typeof) //Improve cache hits by using the same context 68 | let start = match memberName' with 69 | | GenericMember (name, _) 70 | | Member name -> Dynamic.InvokeGet(target', name) 71 | | Direct -> target' 72 | Dynamic.InvokeMember(invokeContext(start), invokeName, [|arg'|]) 73 | let (|NoConversion| Conversion|) t = 74 | if t = typeof then NoConversion else Conversion 75 | let finalConvertResult finalType result :'TResult = 76 | match finalType with 77 | | x when FSharpType.IsFunction x -> // if return type is a function 78 | let rec curriedLambda target type' arg' = 79 | let result' = fsharpInvoke target Direct arg' 80 | let _,retType = FSharpType.GetFunctionElements type' 81 | if FSharpType.IsFunction retType then 82 | FSharpValue.MakeFunction(retType, curriedLambda result' retType) 83 | else 84 | result' 85 | FSharpValue.MakeFunction(finalType, curriedLambda result finalType) 86 | | NoConversion -> result 87 | | Conversion -> implicitConvert result 88 | |> unbox 89 | if not (FSharpType.IsFunction resultType) 90 | then 91 | match memberName with 92 | | GenericMember (name, _) 93 | | Member name -> Dynamic.InvokeGet(target, name) 94 | | Direct -> target 95 | |> finalConvertResult resultType 96 | else 97 | let lambda (arg:obj) = 98 | let argType,returnType = FSharpType.GetFunctionElements resultType 99 | let argArray = 100 | match argType with 101 | | a when FSharpType.IsTuple(a) -> FSharpValue.GetTupleFields(arg) 102 | | a when a = typeof -> [| |] 103 | | ____________________________ -> [|arg|] 104 | let invoker k = 105 | let memberName = 106 | memberName |> function | GenericMember (name, targs) -> 107 | InvokeMemberName(name, targs) 108 | | Member name -> 109 | InvokeMemberName(name, null) 110 | | Direct -> null 111 | Invocation(k, memberName).Invoke(target, argArray) 112 | let (|Action|Func|) t = if t = typeof then Action else Func 113 | let result = 114 | try //Either it has a member or it's something directly callable 115 | match (returnType, memberName) with 116 | | (Action, Direct) -> invoker(InvocationKind.InvokeAction) 117 | | (Action, GenericMember _) 118 | | (Action, Member _) -> invoker(InvocationKind.InvokeMemberAction) 119 | | (Func, Direct) -> invoker(InvocationKind.Invoke) 120 | | (Func, GenericMember _) 121 | | (Func, Member _) -> invoker(InvocationKind.InvokeMember) 122 | with //Last chance incase we are trying to invoke an fsharpfunc 123 | | :? RuntimeBinderException as e -> 124 | try 125 | fsharpInvoke target memberName arg 126 | with 127 | | :? RuntimeBinderException as e2 128 | -> AggregateException(e, e2) |> raise 129 | match returnType with 130 | | Action | NoConversion -> result 131 | | _____________________ -> result |> finalConvertResult returnType 132 | FSharpValue.MakeFunction(resultType, lambda) |> unbox<'TResult> 133 | 134 | let invokeDirect value (target:obj) : 'TResult = 135 | invocation target Direct value 136 | 137 | 138 | let invokeMember (memberName:string) value (target:obj) : 'TResult = 139 | invocation target (Member memberName) value 140 | 141 | 142 | let invokeGeneric (memberName:string) (typeArgs:Type seq) value (target:obj) : 'TResult = 143 | let typeArgs' = typeArgs |> Array.ofSeq 144 | let genericMember = GenericMember (memberName, typeArgs') 145 | invocation target genericMember value 146 | 147 | let get (propertyName:string) (target:obj) : 'TResult = 148 | invocation target (Member propertyName) 149 | 150 | let getChain (chainOfMembers:string seq) (target:obj) : 'TResult = 151 | let chainOfMembers' = String.concat "." chainOfMembers 152 | Dynamic.InvokeGetChain(target, chainOfMembers') |> invocation <| Direct 153 | 154 | 155 | let getIndexer (indexers: 'T seq) (target:obj): 'TResult = 156 | let indexes = indexers |> Seq.map box |> Seq.toArray 157 | Dynamic.InvokeGetIndex(target, indexes) |> invocation <| Direct 158 | 159 | let set (propertyName:string) (value:obj) (target:obj) = 160 | Dynamic.InvokeSet(target, propertyName, value) |> ignore 161 | 162 | let setChain (chainOfMembers: string seq) (value:obj) (target:obj) = 163 | let chainOfMembers' = String.concat "." chainOfMembers 164 | Dynamic.InvokeSetChain(target, chainOfMembers', value) |> ignore 165 | 166 | /// dynamically call set index 167 | let setIndexer (indexers: 'T seq) (value:obj) (target:obj) = 168 | let indexes = indexers |> Seq.map box |> Seq.toArray 169 | Dynamic.InvokeSetValueOnIndexes(target, value, indexes) |> ignore 170 | 171 | [] 172 | let getIndex (target:obj) (indexers: 'T seq) : 'TResult = 173 | target |> getIndexer indexers 174 | 175 | [] 176 | let setIndex (target:obj) (indexers: 'T seq) (value:obj) = 177 | target |> setIndexer indexers value 178 | 179 | [] 180 | let addAssignMember (target:obj) (memberName:string) (value:obj) = 181 | target |> memberAddAssign memberName value 182 | 183 | [] 184 | let subtractAssignMember (target:obj) (memberName:string) (value:obj) = 185 | target |> memberSubtractAssign memberName value 186 | 187 | [] 188 | let invoke (target:obj) (memberName:string option) : 'TResult = 189 | let memberOrDirect = match memberName with | Some mn -> Member mn | None -> Direct 190 | invocation target memberOrDirect -------------------------------------------------------------------------------- /FSharp.Interop.Dynamic/Dyn.fsi: -------------------------------------------------------------------------------- 1 | namespace FSharp.Interop.Dynamic 2 | type Calling = 3 | | GenericMember of string * System.Type array 4 | | Member of string 5 | | Direct 6 | 7 | ///Functions backing the operators and more 8 | module Dyn = begin 9 | ///allow access to static context for dynamic invocation of static methods 10 | val staticContext : target:System.Type -> Dynamitey.InvokeContext 11 | val staticTarget<'TTarget> : Dynamitey.InvokeContext 12 | ///implict convert via reflected type 13 | val implicitConvertTo : convertType:System.Type -> target:obj -> 'TResult 14 | ///implict convert via inferred type 15 | val implicitConvert : target:obj -> 'TResult 16 | 17 | ///explicit convert via reflected type 18 | val explicitConvertTo : convertType:System.Type -> target:obj -> 'TResult 19 | ///explicit convert via inferred type 20 | val explicitConvert : target:obj -> 'TResult 21 | ///allow marking args with names for dlr invoke 22 | val namedArg : name:string -> argValue:obj -> Dynamitey.InvokeArg 23 | ///Dynamically call `+=` on member 24 | val memberAddAssign : memberName:string -> value:obj -> target:obj -> unit 25 | ///Dynamically call `-=` on member 26 | val memberSubtractAssign : 27 | memberName:string -> value:obj -> target:obj -> unit 28 | /// main workhouse method; Some(methodName) or just None to invoke without name; 29 | /// infered casting with automatic implicit convert. 30 | /// target not last because result could be infered to be fsharp style curried function 31 | val invocation : target:obj -> memberName:Calling -> 'TResult 32 | ///allows result to be called like a function 33 | val invokeDirect : value:'a -> target:obj -> 'TResult 34 | ///calls member whose result can be called like a function 35 | val invokeMember : memberName:string -> value:'a -> target:obj -> 'TResult 36 | ///calls member and specify's generic parameters and whose result can be called like a function 37 | val invokeGeneric : 38 | memberName:string -> 39 | typeArgs:seq -> value:'a -> target:obj -> 'TResult 40 | val get : propertyName:string -> target:obj -> 'TResult 41 | val getChain : chainOfMembers:seq -> target:obj -> 'TResult 42 | ///dynamically call get index 43 | val getIndexer : indexers:seq<'T> -> target:obj -> 'TResult 44 | val set : propertyName:string -> value:obj -> target:obj -> unit 45 | val setChain : chainOfMembers:seq -> value:obj -> target:obj -> unit 46 | val setIndexer : indexers:seq<'T> -> value:obj -> target:obj -> unit 47 | /// *OBSOLETE* 48 | [] 49 | val getIndex : target:obj -> indexers:seq<'T> -> 'TResult 50 | /// *OBSOLETE* 51 | [] 52 | val setIndex : target:obj -> indexers:seq<'T> -> value:obj -> unit 53 | /// *OBSOLETE* 54 | [] 56 | val addAssignMember : target:obj -> memberName:string -> value:obj -> unit 57 | /// *OBSOLETE* 58 | [] 59 | val subtractAssignMember : 60 | target:obj -> memberName:string -> value:obj -> unit 61 | /// *OBSOLETE* 62 | [] 63 | val invoke : target:obj -> memberName:string option -> 'TResult 64 | end 65 | 66 | -------------------------------------------------------------------------------- /FSharp.Interop.Dynamic/FSharp.Interop.Dynamic.fsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | netstandard1.6;netstandard2.0;net45 4 | netstandard2.0 5 | dynamic operator using the DLR 6 | Ekon Benefits 7 | Jay Tuley 8 | Copyright 2011-2019 Ekon Benefits 9 | https://github.com/fsprojects/FSharp.Interop.Dynamic 10 | Apache-2.0 11 | fsharp dynamic dlr 12 | True 13 | True 14 | True 15 | true 16 | snupkg 17 | true 18 | false 19 | True 20 | true 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | all 34 | runtime; build; native; contentfiles; analyzers 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /FSharp.Interop.Dynamic/Operators.fs: -------------------------------------------------------------------------------- 1 | namespace FSharp.Interop.Dynamic 2 | 3 | module Operators= 4 | open System 5 | open Dynamitey 6 | open System.Linq.Expressions 7 | let (?%?) (left:obj) (right: obj) : 'TResult = 8 | (Dynamic.InvokeBinaryOperator(left, ExpressionType.Modulo, right)) :?> 'TResult 9 | 10 | let (?*?) (left:obj) (right: obj) : 'TResult = 11 | (Dynamic.InvokeBinaryOperator(left, ExpressionType.Multiply, right)) :?> 'TResult 12 | 13 | let (?+?) (left:obj) (right: obj) : 'TResult = 14 | (Dynamic.InvokeBinaryOperator(left, ExpressionType.Add, right)) :?> 'TResult 15 | 16 | let (?-?) (left:obj) (right: obj) : 'TResult = 17 | (Dynamic.InvokeBinaryOperator(left, ExpressionType.Subtract, right)) :?> 'TResult 18 | 19 | let (?/?) (left:obj) (right: obj) : 'TResult = 20 | (Dynamic.InvokeBinaryOperator(left, ExpressionType.Divide, right)) :?> 'TResult 21 | 22 | let (?&&&?) (left:obj) (right: obj) : 'TResult = 23 | (Dynamic.InvokeBinaryOperator(left, ExpressionType.And, right)) :?> 'TResult 24 | 25 | let (?|||?) (left:obj) (right: obj) : 'TResult = 26 | (Dynamic.InvokeBinaryOperator(left, ExpressionType.Or, right)) :?> 'TResult 27 | 28 | let (?^^^?) (left:obj) (right: obj) : 'TResult = 29 | (Dynamic.InvokeBinaryOperator(left, ExpressionType.ExclusiveOr, right)) :?> 'TResult 30 | 31 | let (?<< 'TResult 33 | 34 | let (?>>>?) (left:obj) (right: obj) : 'TResult = 35 | (Dynamic.InvokeBinaryOperator(left, ExpressionType.RightShift, right)) :?> 'TResult 36 | 37 | let (?<=?) (left:obj) (right: obj) : bool = 38 | Dynamic.InvokeBinaryOperator(left, ExpressionType.LessThanOrEqual, right) |> Dyn.explicitConvert 39 | 40 | let (?<>?) (left:obj) (right: obj) : bool = 41 | Dynamic.InvokeBinaryOperator(left, ExpressionType.NotEqual, right) |> Dyn.explicitConvert 42 | 43 | let (? Dyn.explicitConvert 45 | 46 | let (?=?) (left:obj) (right: obj) : bool = 47 | Dynamic.InvokeBinaryOperator(left, ExpressionType.Equal, right) |> Dyn.explicitConvert 48 | 49 | let (?>?) (left:obj) (right: obj) : bool = 50 | Dynamic.InvokeBinaryOperator(left, ExpressionType.GreaterThan, right) |> Dyn.explicitConvert 51 | 52 | let (?>=?) (left:obj) (right: obj) : bool = 53 | Dynamic.InvokeBinaryOperator(left, ExpressionType.GreaterThanOrEqual, right) |> Dyn.explicitConvert 54 | 55 | -------------------------------------------------------------------------------- /FSharp.Interop.Dynamic/Operators.fsi: -------------------------------------------------------------------------------- 1 | namespace FSharp.Interop.Dynamic 2 | /// Additional operators to dyanmically do normal operations 3 | module Operators = begin 4 | val ( ?%? ) : left:obj -> right:obj -> 'TResult 5 | val ( ?*? ) : left:obj -> right:obj -> 'TResult 6 | val ( ?+? ) : left:obj -> right:obj -> 'TResult 7 | val ( ?-? ) : left:obj -> right:obj -> 'TResult 8 | val ( ?/? ) : left:obj -> right:obj -> 'TResult 9 | val ( ?&&&? ) : left:obj -> right:obj -> 'TResult 10 | val ( ?|||? ) : left:obj -> right:obj -> 'TResult 11 | val ( ?^^^? ) : left:obj -> right:obj -> 'TResult 12 | val ( ?<< right:obj -> 'TResult 13 | val ( ?>>>? ) : left:obj -> right:obj -> 'TResult 14 | val ( ?<=? ) : left:obj -> right:obj -> bool 15 | val ( ?<>? ) : left:obj -> right:obj -> bool 16 | val ( ? right:obj -> bool 17 | val ( ?=? ) : left:obj -> right:obj -> bool 18 | val ( ?>? ) : left:obj -> right:obj -> bool 19 | val ( ?>=? ) : left:obj -> right:obj -> bool 20 | end 21 | 22 | -------------------------------------------------------------------------------- /FSharp.Interop.Dynamic/SymbolicString.fs: -------------------------------------------------------------------------------- 1 | namespace FSharp.Interop.Dynamic 2 | 3 | open FSharp.Quotations 4 | open FSharp.Quotations.Patterns 5 | open FSharp.Reflection 6 | module SymbolicString = 7 | 8 | let sym<'TTarget> : 'TTarget = failwith "don't call the sym function, meant for quotations only!" 9 | 10 | type LeafInfo = 11 | { ReturnType : System.Type 12 | Name : string 13 | DeclaringType: System.Type option 14 | } 15 | 16 | type Symbol = 17 | 18 | static member leafInfoOf([] value:Expr<'T>) : LeafInfo = 19 | let rec finalName value' = 20 | match value' with 21 | | ValueWithName(_, type', name) -> 22 | { ReturnType= type'; Name= name; DeclaringType = None } 23 | | NewUnionCase(caseInfo, _) -> 24 | { ReturnType= caseInfo.DeclaringType 25 | Name= caseInfo.Name 26 | DeclaringType= Some <| caseInfo.DeclaringType } 27 | | PropertyGet(_, propOrValInfo, _) -> 28 | { ReturnType= propOrValInfo.PropertyType 29 | Name= propOrValInfo.Name 30 | DeclaringType= Some <| propOrValInfo.DeclaringType } 31 | | FieldGet(_, fieldInfo) -> 32 | { ReturnType= fieldInfo.FieldType 33 | Name= fieldInfo.Name 34 | DeclaringType= Some <| fieldInfo.DeclaringType } 35 | | Call(_, methInfo, _) -> 36 | { ReturnType= methInfo.ReturnType 37 | Name= methInfo.Name 38 | DeclaringType= Some <| methInfo.DeclaringType } 39 | | Lambda(_, expr) -> finalName expr 40 | | Let(_,_, expr) -> finalName expr 41 | | ________________________________ -> invalidArg "value" (sprintf "Couldn't figure out how to make '%A' a name" value) 42 | finalName value 43 | 44 | static member nameOf([] value:Expr<'T>) : string = (value |> Symbol.leafInfoOf).Name 45 | 46 | static member typeOf([] value:Expr<'T>) : System.Type = (value |> Symbol.leafInfoOf).ReturnType 47 | -------------------------------------------------------------------------------- /FSharp.Interop.Dynamic/TopLevelOperators.fs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2011 Ekon Benefits 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | namespace FSharp.Interop.Dynamic 17 | 18 | 19 | [] 20 | module TopLevelOperators= 21 | let (?) (target : obj) (name:string) : 'TResult = 22 | Dyn.invocation target (Member name) 23 | 24 | let (?<-) (target : obj) (name : string) (value : 'TValue) : unit = 25 | target |> Dyn.set name value 26 | 27 | let (!?) (target:obj) : 'TResult = 28 | Dyn.invocation target Direct 29 | -------------------------------------------------------------------------------- /FSharp.Interop.Dynamic/TopLevelOperators.fsi: -------------------------------------------------------------------------------- 1 | namespace FSharp.Interop.Dynamic 2 | /// Main operators for dynamic invocation 3 | [] 4 | module TopLevelOperators = begin 5 | /// Dynamic get property or method invocation 6 | val ( ? ) : target:obj -> name:string -> 'TResult 7 | /// Dynamic set property 8 | val ( ?<- ) : target:obj -> name:string -> value:'TValue -> unit 9 | /// Prefix operator that allows direct dynamic invocation of the object 10 | val ( !? ) : target:obj -> 'TResult 11 | end 12 | 13 | -------------------------------------------------------------------------------- /License.txt: -------------------------------------------------------------------------------- 1 | Apache License, Version 2.0 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. 13 | 14 | "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. 15 | 16 | "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. 17 | 18 | "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. 19 | 20 | "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. 21 | 22 | "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). 23 | 24 | "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. 25 | 26 | "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." 27 | 28 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 29 | 30 | 2. Grant of Copyright License. 31 | 32 | Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 33 | 34 | 3. Grant of Patent License. 35 | 36 | Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 37 | 38 | 4. Redistribution. 39 | 40 | You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: 41 | 42 | You must give any other recipients of the Work or Derivative Works a copy of this License; and 43 | You must cause any modified files to carry prominent notices stating that You changed the files; and 44 | You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and 45 | If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. 46 | You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 47 | 48 | 5. Submission of Contributions. 49 | 50 | Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 51 | 52 | 6. Trademarks. 53 | 54 | This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 55 | 56 | 7. Disclaimer of Warranty. 57 | 58 | Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 59 | 60 | 8. Limitation of Liability. 61 | 62 | In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 63 | 64 | 9. Accepting Warranty or Additional Liability. 65 | 66 | While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. 67 | 68 | END OF TERMS AND CONDITIONS 69 | 70 | APPENDIX: How to apply the Apache License to your work 71 | 72 | To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. 73 | 74 | Copyright [yyyy] [name of copyright owner] 75 | 76 | Licensed under the Apache License, Version 2.0 (the "License"); 77 | you may not use this file except in compliance with the License. 78 | You may obtain a copy of the License at 79 | 80 | http://www.apache.org/licenses/LICENSE-2.0 81 | 82 | Unless required by applicable law or agreed to in writing, software 83 | distributed under the License is distributed on an "AS IS" BASIS, 84 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 85 | See the License for the specific language governing permissions and 86 | limitations under the License. -------------------------------------------------------------------------------- /NuGet.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FSharp.Interop.Dynamic [![NuGet Status](http://img.shields.io/nuget/v/FSharp.Interop.Dynamic.svg?style=flat)](https://www.nuget.org/packages/FSharp.Interop.Dynamic/) 2 | 3 | 4 | The F# Dynamic Operator, powered by the DLR. Compiled for .NET Standard 2.0, .NET Standard 1.6, .NET Framework 4.5 5 | 6 | Install from [NuGet](https://nuget.org/packages/FSharp.Interop.Dynamic/) 7 | ``` 8 | PM> Install-Package FSharp.Interop.Dynamic 9 | ``` 10 | 11 | # Build Status 12 | 13 | Platform | Status 14 | -------- | ------ 15 | Nuget Deployment | [![Build status](https://ci.appveyor.com/api/projects/status/tbw9put64a0p3j9o/branch/master?svg=true)](https://ci.appveyor.com/project/jbtule/fsharp-dynamic-832/branch/master) 16 | Mac/Linux/Windows | [![Action Status](https://github.com/fsprojects/FSharp.Interop.Dynamic/workflows/.NET%20Core%20CI/badge.svg)](https://github.com/fsprojects/FSharp.Interop.Dynamic/actions?workflow=.NET+Core+CI) 17 | Coverage| [![codecov](https://codecov.io/gh/fsprojects/FSharp.Interop.Dynamic/branch/master/graph/badge.svg)](https://codecov.io/gh/fsprojects/FSharp.Interop.Dynamic) [![Coverage Status](https://coveralls.io/repos/github/fsprojects/FSharp.Interop.Dynamic/badge.svg?branch=master)](https://coveralls.io/github/fsprojects/FSharp.Interop.Dynamic?branch=master) 18 | 19 | 20 | # Bleeding edge feed on MyGet 21 | 22 | [![MyGet Pre Release](https://img.shields.io/myget/dynamitey-ci/vpre/FSharp.Interop.Dynamic.svg)](https://www.myget.org/feed/dynamitey-ci/package/nuget/FSharp.Interop.Dynamic) 23 | 24 | # Usage 25 | 26 | `target?Property`, `target?Property<-value`, and `target?Method(arg,arg2)` allow you to dynamically get/set properties and call methods 27 | 28 | Also `Dyn.implicitConvert`,`Dyn.explicitConvert`, comparison operators and more. 29 | 30 | 31 | # Examples: 32 | 33 | ### System.Dynamic 34 | ```fsharp 35 | open FSharp.Interop.Dynamic 36 | let ex1 = ExpandoObject() 37 | ex1?Test<-"Hi"//Set Dynamic Property 38 | ex1?Test //Get Dynamic 39 | ``` 40 | 41 | ### MVC ViewBag 42 | 43 | ```fsharp 44 | x.ViewBag?Name<-"George" 45 | ``` 46 | 47 | ### Dynamitey 48 | 49 | ```fsharp 50 | open FSharp.Interop.Dynamic 51 | open Dynamitey.DynamicObjects 52 | 53 | let ComBinder = LateType("System.Dynamic.ComBinder, System.Dynamic, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a") 54 | 55 | let getPropertyNames (target:obj) = 56 | seq { 57 | yield! target.GetType().GetTypeInfo().GetProperties().Select(fun it -> it.Name) 58 | if (ComBinder.IsAvailable) then 59 | yield! ComBinder?GetDynamicDataMemberNames(target) 60 | } 61 | 62 | ``` 63 | 64 | 65 | ### Python Interop 66 | 67 | Translated from this example C# code: https://github.com/SciSharp/pythonnet#example 68 | 69 | ```fsharp 70 | open Python.Runtime 71 | open FSharp.Interop.Dynamic 72 | open FSharp.Interop.Dynamic.Operators 73 | 74 | do 75 | use __ = Py.GIL() 76 | 77 | let np = Py.Import("numpy") 78 | np?cos(np?pi ?*? 2) 79 | |> printfn "%O" 80 | 81 | let sin: obj -> obj = np?sin 82 | sin 5 |> printfn "%O" 83 | 84 | np?cos 5 ?+? sin 5 85 | |> printfn "%O" 86 | 87 | let a: obj = np?array([| 1.; 2.; 3. |]) 88 | printfn "%O" a?dtype 89 | 90 | let b: obj = np?array([| 6.; 5.; 4. |], Dyn.namedArg "dtype" np?int32) 91 | printfn "%O" b?dtype 92 | 93 | a ?*? b 94 | |> printfn "%O" 95 | ``` 96 | 97 | Output 98 | 99 | ``` 100 | 1.0 101 | -0.9589242746631385 102 | -0.6752620891999122 103 | float64 104 | int32 105 | [ 6. 10. 12.] 106 | ``` 107 | 108 | ### SignalR (.net framework version) 109 | 110 | ```fsharp 111 | open FSharp.Interop.Dynamic 112 | type MyHub = 113 | inherit Hub 114 | member x.Send (name : string) (message : string) = 115 | base.Clients.All?addMessage(name,message) |> ignore 116 | ``` 117 | 118 | # Caveats: 119 | 120 | The `DLR` is incompatible with interface explicit members, so are these operators, [just like C#'s `dynamic` keyword](http://stackoverflow.com/questions/22514892/iterate-through-a-dictionary-inserted-in-a-asp-net-mvc4-pages-viewdata-via-f-c). 121 | 122 | [.NET Core 2.0.0 to 2.0.2 had a major bug in the C# dynamic keyword with nested classes inside of generic classes.](https://github.com/fsprojects/FSharp.Interop.Dynamic/issues/11). You will know it from a substring argument length exception. .NET Framework 4.0+, .NET Core 1.x and .NET Core 2.0.3+ and later are unaffected. 123 | 124 | ## Maintainer(s) 125 | 126 | - [@jbtule](https://github.com/jbtule) 127 | - [@forki](https://github.com/forki) 128 | 129 | The default maintainer account for projects under "fsprojects" is [@fsprojectsgit](https://github.com/fsprojectsgit) - F# Community Project Incubation Space (repo management) 130 | -------------------------------------------------------------------------------- /Scripts/GenerateDocumentation.fsx: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | #if bin_sh 3 | # Doing this because arguments can't be used with /usr/bin/env on linux, just mac 4 | exec fsharpi --define:mono_posix --exec $0 $* 5 | #endif 6 | 7 | #if mono_posix 8 | #r "Mono.Posix.dll" 9 | open Mono.Unix.Native 10 | let applyExecutionPermissionUnix path = 11 | let _,stat = Syscall.lstat(path) 12 | Syscall.chmod(path, FilePermissions.S_IXUSR ||| stat.st_mode) |> ignore 13 | #else 14 | let applyExecutionPermissionUnix _ = () 15 | #endif 16 | 17 | open System 18 | open System.IO 19 | open System.Diagnostics 20 | 21 | Environment.CurrentDirectory <- __SOURCE_DIRECTORY__ 22 | 23 | let createDir d= Directory.CreateDirectory(d) |> ignore 24 | 25 | let paketPath = Path.Combine("bin", "paket.exe") 26 | if not (File.Exists paketPath) then 27 | let url = "http://fsprojects.github.io/Paket/stable" 28 | use wc = new Net.WebClient() 29 | let tmp = Path.GetTempFileName() 30 | let stable = wc.DownloadString(url) 31 | wc.DownloadFile(stable, tmp) 32 | createDir "bin" 33 | File.Move(tmp, paketPath) 34 | let exec (exePath:string) (args:string seq) = 35 | let processStart (psi:ProcessStartInfo) = 36 | let ps = Process.Start(psi) 37 | ps.WaitForExit () 38 | ps.ExitCode 39 | applyExecutionPermissionUnix exePath 40 | let exitCode = ProcessStartInfo( 41 | exePath, 42 | args |> String.concat " ", 43 | UseShellExecute = false) 44 | |> processStart 45 | if exitCode <> 0 then 46 | exit exitCode 47 | () 48 | 49 | exec paketPath ["install"] 50 | printfn "Finished Paket install." 51 | 52 | #I "packages/FSharp.Compiler.Service/lib/net45/" 53 | #r "FSharp.Compiler.Service.dll" 54 | #I "packages/FSharp.Formatting/lib/net40/" 55 | #r "RazorEngine.dll" 56 | #r "FSharp.MetadataFormat.dll" 57 | #r "FSharp.Literate.dll" 58 | #r "FSharp.CodeFormat.dll" 59 | #r "FSharp.Formatting.Razor.dll" 60 | #I "packages/FSharp.Data/lib/net45/" 61 | #r "FSharp.Data.dll" 62 | #r "System.Xml.Linq.dll" 63 | open FSharp.Formatting.Razor 64 | open FSharp.Data 65 | 66 | /// variables 67 | type FsProj = XmlProvider<"../FSharp.Interop.Dynamic/FSharp.Interop.Dynamic.fsproj"> 68 | let fsProj = FsProj.GetSample() 69 | 70 | let targetFramework = "net45" 71 | let projName = "FSharp.Interop.Dynamic" 72 | let configuration = "Release" 73 | let root = Path.Combine(__SOURCE_DIRECTORY__, "..") 74 | let srcDir = Path.Combine(root) 75 | let testDir = Path.Combine(root, "Tests") 76 | let docContent = Path.Combine(root, "DocsSrc") 77 | let outputDir = Path.Combine(root, "docs") 78 | 79 | let binDir =Path.Combine(srcDir, 80 | projName, 81 | "bin", 82 | configuration, 83 | targetFramework) 84 | 85 | let getDllNamed name = 86 | Path.Combine(binDir, sprintf "%s.dll" name) 87 | 88 | let dll = getDllNamed projName 89 | 90 | 91 | 92 | 93 | ///end variables 94 | 95 | 96 | 97 | printfn "Copy Doc Content." 98 | 99 | createDir outputDir 100 | 101 | let docStyles = Path.Combine(docContent, "styles") 102 | let baseOutput = Path.Combine(outputDir, "content") 103 | createDir docStyles 104 | for dir in Directory.GetDirectories(docStyles) do 105 | let outputContentDir = Path.Combine(baseOutput, Path.GetFileName(dir)) 106 | createDir outputContentDir 107 | for file in Directory.GetFiles(dir) do 108 | File.Copy(file, Path.Combine(outputContentDir, Path.GetFileName(file)), overwrite = true) 109 | for file in Directory.GetFiles(docStyles) do 110 | File.Copy(file, Path.Combine(baseOutput, Path.GetFileName(file)), overwrite = true) 111 | let imgDir = Path.Combine(outputDir,"images") 112 | createDir imgDir 113 | let logo = Path.Combine(docContent, "logo.png") 114 | File.Copy(logo, Path.Combine(imgDir, "logo.png"), overwrite=true) 115 | 116 | 117 | let template = "docpage.cshtml" 118 | let templateDirs = [ Path.Combine(docContent, "templates"); 119 | Path.Combine(docContent, "templates", "reference") ] 120 | 121 | let projInfo = 122 | [ "project-author", fsProj.PropertyGroup.Authors 123 | "project-summary", fsProj.PropertyGroup.Description 124 | "project-github", fsProj.PropertyGroup.PackageProjectUrl 125 | "project-nuget", sprintf "https://www.nuget.org/packages/%s" projName 126 | "project-name", projName 127 | "root", sprintf "/%s" projName 128 | ] 129 | 130 | 131 | let options = sprintf "--reference:\"%s\"" dll 132 | 133 | let processMdFile input output = 134 | RazorLiterate.ProcessMarkdown( 135 | Path.Combine(root,input), 136 | templateFile = template, 137 | output = Path.Combine(outputDir, output), 138 | replacements = projInfo, 139 | compilerOptions = options, 140 | layoutRoots = templateDirs, 141 | includeSource = true) 142 | let processFsFile input output = 143 | RazorLiterate.ProcessScriptFile( 144 | input, 145 | templateFile = template, 146 | output = Path.Combine(outputDir, output), 147 | replacements = projInfo, 148 | compilerOptions = options, 149 | layoutRoots = templateDirs, 150 | includeSource = true ) 151 | 152 | //custom files 153 | printfn "Generate Readme." 154 | 155 | processMdFile (Path.Combine(root,"README.md")) "index.html" 156 | 157 | printfn "Generate Other Docs." 158 | 159 | processFsFile (Path.Combine(testDir,"Library1.fs")) "examples.html" 160 | 161 | //end custom files 162 | let refDir = Path.Combine(outputDir, "reference") 163 | printfn "Generate API Reference. '%s'" dll 164 | createDir(refDir) 165 | let sourceRepo = sprintf "%s/tree/master/" fsProj.PropertyGroup.PackageProjectUrl 166 | RazorMetadataFormat.Generate( dll, 167 | refDir, 168 | templateDirs, 169 | parameters = projInfo, 170 | sourceRepo = sourceRepo, 171 | sourceFolder = root, 172 | libDirs = [binDir]) 173 | 174 | printfn "Finished Generating Docs." -------------------------------------------------------------------------------- /Scripts/paket.dependencies: -------------------------------------------------------------------------------- 1 | source https://www.nuget.org/api/v2 2 | source https://ci.appveyor.com/nuget/fsharp-formatting 3 | nuget FSharp.Formatting prerelease 4 | nuget FSharp.Data -------------------------------------------------------------------------------- /Tests/Library1.fs: -------------------------------------------------------------------------------- 1 |  2 | (** 3 | # Examples of using Dynamic operator and Functions 4 | *) 5 | namespace Tests 6 | 7 | open FSharp.Interop.Dynamic 8 | open FSharp.Interop.Dynamic.Operators 9 | open FSharp.Interop.Dynamic.SymbolicString 10 | (***hide***) 11 | open Xunit 12 | open FsUnit.Xunit 13 | open System 14 | open Dynamitey 15 | open System.Dynamic 16 | open System.Collections.Generic 17 | open System.Xml.Linq 18 | open System.Numerics 19 | open Microsoft.CSharp.RuntimeBinder 20 | 21 | open System.Linq.Expressions 22 | 23 | (***hide***) 24 | type TestEvent()= 25 | let event1 = new Event, EventArgs>() 26 | [] 27 | member __.Event = event1.Publish 28 | member __.OnEvent(obj:Object, args:EventArgs)= 29 | event1.Trigger(obj,args) 30 | 31 | 32 | (***hide***) 33 | type TestFuncs()= 34 | static member Plus3:Func = 35 | Return.Arguments(fun x-> x + 3) 36 | (***hide***) 37 | type DynamicOperatorMock()= 38 | inherit DynamicObject() 39 | override __.TryBinaryOperation(binder, arg, result) = 40 | result <- binder.Operation 41 | true 42 | (***hide***) 43 | type DynamicWeirdFlakyIndexer()= 44 | inherit DynamicObject() 45 | let stuff = Dictionary() 46 | 47 | override __.TryGetIndex(_, indexes, result) = 48 | result <- stuff.[(indexes.[0], indexes.[1])] 49 | true 50 | 51 | override __.TrySetIndex(_, indexes, value) = 52 | stuff.Add((indexes.[0], indexes.[1]),value) 53 | true 54 | 55 | module Tests = 56 | 57 | 58 | 59 | 60 | (** 61 | Call a method with dlr (ideally you wouldn't know it was as a string). 62 | *) 63 | [] 64 | let ``Call method off of an object dynamically`` ()= 65 | "HelloWorld"?Substring(0,5) 66 | |> should equal "Hello" 67 | (** 68 | Call a method with a variable (ideally you wouldn't know it was as a string). 69 | *) 70 | [] 71 | let ``Call method off of an object dynamically with variable`` ()= 72 | let method = "Substring" 73 | "HelloWorld"?(method)(0,5) 74 | |> should equal "Hello" 75 | (** 76 | Set a property with dlr, Expando only responds to the dlr. 77 | *) 78 | [] 79 | let ``Test Expando Set and Get`` ()= 80 | let ex1 = ExpandoObject() 81 | ex1?Test<-"Hi"; 82 | ex1?Test |> should equal "Hi" 83 | 84 | (***hide***) 85 | [] 86 | let ``Test Direct Invoke`` ()= 87 | !?Dynamic.Curry(Dyn.staticTarget)?Format("Test {0} {1}") (1,2) |> 88 | should equal "Test 1 2" 89 | 90 | (***hide***) 91 | [] 92 | let ``Test Void Method`` ()= 93 | let array = List() 94 | array?Add("1"); 95 | array.[0] |> should equal "1" 96 | 97 | (***hide***) 98 | [] 99 | let ``Test SetAll`` ()= 100 | let e1 = ExpandoObject() 101 | !?Dynamic.InvokeSetAll (e1, [("One",1);("Two",2)]) 102 | e1?One |> should equal 1 103 | e1?Two |> should equal 2 104 | 105 | (***hide***) 106 | [] 107 | let ``Test Lambda methods`` ()= 108 | let ex1 = DynamicObjects.Dictionary() 109 | ex1?TestLam<- (fun x -> 42 + x) 110 | ex1?TestLam2<- (fun (x,y) -> y+ 42 + x) 111 | ex1?TestDel<- TestFuncs.Plus3 112 | ex1?TestLam(1) |> should equal 43 113 | ex1?TestLam2(1,2) |> should equal 45 114 | ex1?TestDel(2) |> should equal 5 115 | 116 | (***hide***) 117 | [] 118 | let ``Test FSharp Lambda Tuple arg`` ()= 119 | let dyn = (fun (x,y) z -> x + y - z) :> obj 120 | let x:int = !?dyn (3,2) 1 121 | x |> should equal 4 122 | 123 | [] 124 | let ``Test FSharp Lambda 2 arg`` ()= 125 | let dyn = (( + )) :> obj 126 | let x = !?dyn 3 2 127 | x |> should equal 5 128 | [] 129 | let ``Test FSharp Lambda 3 arg not tupled`` ()= 130 | let dyn = (fun x y z -> x + y - z) :> obj 131 | let x = !?dyn 3 2 1 132 | x |> should equal 4 133 | (***hide***) 134 | [] 135 | let ``Test FSharp Lambda 4 arg`` ()= 136 | let dyn = (fun x y z bbq -> x + y - z - bbq) :> obj in 137 | let x = !?dyn 3 2 1 5 138 | x |> should equal -1 139 | 140 | (***hide***) 141 | [] 142 | let ``Test FSharp Lambda 5 arg`` ()= 143 | let unknownfunc = (fun x y z bbq etc -> x + y - z - bbq + etc) :> obj in 144 | let go = !?unknownfunc 145 | let x = go 3 2 1 5 9 146 | x |> should equal 8 147 | 148 | (***hide***) 149 | [] 150 | let ``Test Events`` ()= 151 | let pocoObj = TestEvent() 152 | let refBool = ref false 153 | let myevent = EventHandler(fun _ _ -> (refBool := true)) 154 | 155 | //Add event dynamically 156 | pocoObj |> Dyn.memberAddAssign "Event" myevent 157 | pocoObj.OnEvent(null,null) 158 | !refBool |> should equal true 159 | 160 | //Remove event dynamically 161 | refBool :=false 162 | pocoObj |> Dyn.memberSubtractAssign "Event" myevent 163 | !refBool |> should equal false 164 | 165 | (** 166 | `!?` will invoke without a name, dynamic function or the like. 167 | `Dyn.namedArg` allows you to wrap your arguments with names as part of the invocation. 168 | *) 169 | [] 170 | let ``Test NamedArgs`` ()= 171 | let buildObj = !?Build.NewObject ( 172 | Dyn.namedArg "One" 1, 173 | Dyn.namedArg "Two" 2 174 | ) 175 | buildObj?One |> should equal 1 176 | buildObj?Two |> should equal 2 177 | 178 | (** 179 | Use the dlr to call the explict operator with a reflected type 180 | *) 181 | [] 182 | let ``Test dynamic Explicit Conversion`` ()= 183 | let ele = XElement(XName.Get("Test"),"50") 184 | ele |> Dyn.explicitConvertTo typeof |> should equal 50 185 | 186 | (** 187 | Use the dlr to call the implict operato rwith a reflected type 188 | *) 189 | [] 190 | let ``Test dynamic Implicit Conversion`` ()= 191 | let ele = 50 192 | let actual = ele |> Dyn.implicitConvertTo typeof 193 | actual |> should equal 50M 194 | 195 | (** 196 | Use the dlr to call the explict operator with inferred type from usage 197 | *) 198 | [] 199 | let ``Test Explicit Conversion`` ()= 200 | let ele = XElement(XName.Get("Test"),"50") 201 | let elet:int = Dyn.explicitConvert ele 202 | elet |> should equal 50 203 | 204 | (** 205 | Use the dlr to call the implicit operator with inferred type from usage 206 | *) 207 | [] 208 | let ``Test Implicit Conversion`` ()= 209 | let ele = 50 210 | let actual:decimal = ele |> Dyn.implicitConvert 211 | actual |> should equal 50m 212 | 213 | 214 | (***hide***) 215 | [] 216 | let ``Test Implicit Conversion Fail`` ()= 217 | let ele = XElement(XName.Get("Test"),"50") 218 | (fun () -> Dyn.implicitConvert(ele) = 50 |> ignore) 219 | |> should throw typeof 220 | 221 | (***hide***) 222 | [] 223 | let ``Test Basic indexer`` ()= 224 | let archive:obj = upcast DynamicWeirdFlakyIndexer() 225 | 226 | archive |> Dyn.setIndexer [1; 5] "A" 227 | archive |> Dyn.setIndexer ["Hello"; "World" ] "B" 228 | archive |> Dyn.setIndexer [box 1; box "World" ] "C" 229 | 230 | archive |> Dyn.getIndexer [1; 5] |> should equal "A" 231 | archive |> Dyn.getIndexer ["Hello"; "World" ] |> should equal "B" 232 | archive |> Dyn.getIndexer [box 1; box "World"] |> should equal "C" 233 | 234 | (***hide***) 235 | [] 236 | let ``Basic Operator Mock Tests`` ()= 237 | let left:obj = upcast DynamicOperatorMock() 238 | let dummy = Object() 239 | 240 | left ?%? dummy |> should equal ExpressionType.Modulo 241 | left ?*? dummy |> should equal ExpressionType.Multiply 242 | left ?+? dummy |> should equal ExpressionType.Add 243 | left ?-? dummy |> should equal ExpressionType.Subtract 244 | left ?/? dummy |> should equal ExpressionType.Divide 245 | left ?&&&? dummy |> should equal ExpressionType.And 246 | left ?|||? dummy |> should equal ExpressionType.Or 247 | left ?^^^? dummy |> should equal ExpressionType.ExclusiveOr 248 | left ?<< should equal ExpressionType.LeftShift 249 | left ?>>>? dummy |> should equal ExpressionType.RightShift 250 | (** 251 | Use operators dynamically (better without knowing the types). 252 | *) 253 | [] 254 | let ``Basic Operator Op Tests`` ()= 255 | 65 ?%? 10 |> should equal 5 256 | 5 ?*? 4 |> should equal 20 257 | 5 ?+? 4 |> should equal 9 258 | 5 ?-? 3 |> should equal 2 259 | 15 ?/? 5 |> should equal 3 260 | 261 | 5 ?&&&? 3 |> should equal 1 262 | 5 ?|||? 3 |> should equal 7 263 | 5 ?^^^? 3 |> should equal 6 264 | 23 ?<< should equal 92 265 | (-105) ?>>>? 1 |> should equal (-53) 266 | 267 | 10 ?<=? 5 |> should equal false 268 | 5 ?<=? 10 |> should equal true 269 | 10 ?<=? 10 |> should equal true 270 | 271 | 10 ?>=? 5 |> should equal true 272 | 5 ?>=? 10 |> should equal false 273 | 10 ?>=? 10 |> should equal true 274 | 275 | 10 ? should equal false 276 | 5 ? should equal true 277 | 10 ? should equal false 278 | 279 | 10 ?>? 5 |> should equal true 280 | 5 ?>? 10 |> should equal false 281 | 10 ?>? 10 |> should equal false 282 | 283 | 10 ?<>? 5 |> should equal true 284 | 10 ?<>? 10 |> should equal false 285 | 286 | 10 ?=? 5 |> should equal false 287 | 10 ?=? 10 |> should equal true 288 | -------------------------------------------------------------------------------- /Tests/Main.fs: -------------------------------------------------------------------------------- 1 | module Program 2 | #if NET46 3 | let [] main _ = 0 4 | #endif -------------------------------------------------------------------------------- /Tests/Obsolete.fs: -------------------------------------------------------------------------------- 1 | namespace Tests 2 | 3 | open FSharp.Interop.Dynamic 4 | open Xunit 5 | open FsUnit.Xunit 6 | open Tests 7 | open System 8 | open System.Dynamic 9 | 10 | #nowarn "44" 11 | 12 | module Obsolete = 13 | 14 | [] 15 | let ``Test Events`` ()= 16 | let pocoObj = TestEvent() 17 | let refBool = ref false 18 | let myevent = EventHandler(fun _ _ -> (refBool := true)) 19 | 20 | //Add event dynamically 21 | Dyn.addAssignMember pocoObj "Event" myevent 22 | pocoObj.OnEvent(null,null) 23 | !refBool |> should equal true 24 | 25 | //Remove event dynamically 26 | refBool :=false 27 | Dyn.subtractAssignMember pocoObj "Event" myevent 28 | !refBool |> should equal false 29 | 30 | [] 31 | let ``Test Basic indexer`` ()= 32 | let archive:obj = upcast DynamicWeirdFlakyIndexer() 33 | 34 | Dyn.setIndex archive [1; 5] "A" 35 | Dyn.setIndex archive ["Hello"; "World" ] "B" 36 | Dyn.setIndex archive [box 1; box "World" ] "C" 37 | 38 | Dyn.getIndex archive [1; 5] |> should equal "A" 39 | Dyn.getIndex archive ["Hello"; "World" ] |> should equal "B" 40 | Dyn.getIndex archive [box 1; box "World"] |> should equal "C" 41 | 42 | [] 43 | let ``Call method off of an object dynamically with variable`` ()= 44 | let method = "Substring" 45 | Dyn.invoke "HelloWorld" (Some method) (0,5) 46 | |> should equal "Hello" 47 | -------------------------------------------------------------------------------- /Tests/Raw.fs: -------------------------------------------------------------------------------- 1 | namespace Tests 2 | 3 | open FSharp.Interop.Dynamic 4 | open FSharp.Interop.Dynamic.Operators 5 | open FSharp.Interop.Dynamic.SymbolicString 6 | 7 | open Xunit 8 | open FsUnit.Xunit 9 | open System.Linq 10 | open System 11 | open System.Collections.Generic 12 | open System.Dynamic 13 | open Dynamitey 14 | 15 | 16 | type FieldObj (i:int) as this= 17 | [] 18 | val mutable Field : int 19 | do 20 | this.Field<- i 21 | 22 | module Raw = 23 | open System.Collections 24 | 25 | [] 26 | let ``Name of Field`` ()= 27 | let fieldName = Symbol.nameOf(sym.Field) 28 | fieldName |> should equal "Field" 29 | let target = FieldObj(7) 30 | target |> Dyn.get fieldName |> should equal 7 31 | 32 | 33 | [] 34 | let ``Name of Call`` ()= 35 | Symbol.nameOf(sym.Substring(0,0)) |> should equal "Substring" 36 | Symbol.typeOf(sym.Substring(0,0)) |> should equal typeof 37 | 38 | [] 39 | let ``Name of unapplied method`` ()= 40 | Symbol.nameOf(sym.Substring) |> should equal "Substring" 41 | Symbol.typeOf(sym.Substring) |> should equal typeof 42 | 43 | [] 44 | let ``Name of get`` ()= 45 | Symbol.nameOf(sym.Length) |> should equal "Length" 46 | Symbol.typeOf(sym.Length) |> should equal typeof 47 | 48 | [] 49 | let ``Name of end of chain`` ()= 50 | Symbol.nameOf(sym.Length.CompareTo) |> should equal "CompareTo" 51 | Symbol.typeOf(sym.Length.CompareTo) |> should equal typeof 52 | 53 | [] 54 | let ``Name of End of chain overload`` ()= 55 | Symbol.nameOf(sym.Length.ToString(sym)) |> should equal "ToString" 56 | Symbol.typeOf(sym.Length.ToString(sym)) |> should equal typeof 57 | 58 | [] 59 | let ``Name of End of chain mix and match extension`` ()= 60 | Symbol.nameOf(sym.Length.ToString(sym).Length.ToString().Any) |> should equal "Any" 61 | Symbol.typeOf(sym.Length.ToString(sym).Length.ToString().Any) |> should equal typeof 62 | [] 63 | let ``Name of var`` ()= 64 | let x = 0 65 | Symbol.nameOf(x) |> should equal "x" 66 | Symbol.typeOf(x) |> should equal typeof 67 | 68 | [] 69 | let ``Name of static generic member`` ()= 70 | Symbol.nameOf(Enumerable.Empty) |> should equal "Empty" 71 | Symbol.typeOf(Enumerable.Empty) |> should equal typeof> 72 | [] 73 | let ``Name of DU`` ()= 74 | let x = 0 75 | Symbol.nameOf(Option.Some) |> should equal "Some" 76 | Symbol.typeOf(Option.Some) |> should equal typeof> 77 | [] 78 | let ``Call method off of an object dynamically`` ()= 79 | let name = Symbol.nameOf(sym.Substring(0,0)) 80 | let actual = "HelloWorld" |> Dyn.invokeMember name (0,5) 81 | actual |> should equal "Hello" 82 | 83 | [] 84 | let ``implict convert null`` () = 85 | let actual:string = (null |> Dyn.implicitConvertTo typeof) 86 | actual |> should equal null 87 | 88 | [] 89 | let ``implict convert null option`` () = 90 | let actual:string option = (null |> Dyn.implicitConvertTo typeof) 91 | actual |> should equal None 92 | [] 93 | let ``implict convert null fail`` () = 94 | let actual ():int = null |> Dyn.implicitConvertTo typeof 95 | actual >> ignore |> shouldFail 96 | 97 | [] 98 | let ``implict convert null fail fsharp type`` () = 99 | let actual ():Calling = (null |> Dyn.implicitConvertTo typeof) 100 | actual >> ignore |> shouldFail 101 | 102 | [] 103 | let ``set dynamic chain`` () = 104 | let expected = "1"; 105 | let target = ExpandoObject(); 106 | let target2 = ExpandoObject(); 107 | let target3 = ExpandoObject(); 108 | target?Test <- target2; 109 | target2?Test2 <- target3; 110 | 111 | 112 | target |> Dyn.setChain ["Test"; "Test2"; "Test3"] expected; 113 | 114 | target?Test?Test2?Test3 |> should equal expected 115 | 116 | [] 117 | let ``set dynamic get chain`` () = 118 | let expected = "1"; 119 | let target = ExpandoObject(); 120 | let target2 = ExpandoObject(); 121 | let target3 = ExpandoObject(); 122 | target?Test <- target2; 123 | target2?Test2 <- target3; 124 | target3?Test3 <- expected; 125 | 126 | let actual = target |> Dyn.getChain ["Test"; "Test2"; "Test3"]; 127 | 128 | actual |> should equal expected 129 | 130 | [] 131 | let ``set dynamic get`` () = 132 | let expected = "A"; 133 | let target = ExpandoObject(); 134 | target?prop <- expected 135 | let actual = target |> Dyn.get "prop" 136 | actual |> should equal expected 137 | 138 | [] 139 | let ``set dynamic set`` () = 140 | let expected = "A"; 141 | let target = ExpandoObject(); 142 | target |> Dyn.set "prop" expected 143 | let actual = target?prop 144 | actual |> should equal expected 145 | 146 | [] 147 | let ``call static generic method`` () = 148 | let expected = Enumerable.Empty() 149 | let target = Dyn.staticTarget 150 | let actual: int seq = target |> Dyn.invokeGeneric "Empty" [typeof] () 151 | actual |> should equal expected 152 | 153 | 154 | [] 155 | let ``call static generic method typeof`` () = 156 | let expected = Enumerable.Empty() 157 | let target = Dyn.staticContext (typeof) 158 | let actual: int seq = target |> Dyn.invokeGeneric "Empty" [typeof] () 159 | actual |> should equal expected -------------------------------------------------------------------------------- /Tests/Tests.fsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | netcoreapp3.0;netcoreapp2.1;net46 4 | netcoreapp2.1 5 | $(TestingTarget) 6 | Exe 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /after.FSharp.Interop.Dynamic.sln.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /build.fsx: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | #if bin_sh 3 | # Doing this because arguments can't be used with /usr/bin/env on linux, just mac 4 | exec fsharpi --define:mono_posix --exec $0 $* 5 | #endif 6 | #if FSharp_MakeFile 7 | 8 | (* 9 | * Single File Crossplatform FSharp Makefile Bootstrapper 10 | * Apache licensed - Copyright 2014 Jay Tuley 11 | * v 2.0 https://gist.github.com/jbtule/11181987 12 | * 13 | * How to use: 14 | * On Windows `fsi --exec build.fsx 15 | * *Note:* if you have trouble first run "%vs120comntools%\vsvars32.bat" or use the "Developer Command Prompt for VS201X" 16 | * or install https://github.com/Iristyle/Posh-VsVars#posh-vsvars 17 | * 18 | * On Mac Or Linux `./build.fsx ` 19 | * *Note:* But if you have trouble then use `sh build.fsx ` 20 | * 21 | *) 22 | 23 | #I "packages/FAKE/tools" 24 | #r "FakeLib.dll" 25 | #r "System.Xml.Linq.dll" 26 | 27 | open Fake 28 | open Fake.DotNet.Testing.NUnit3 29 | open Fake.DotNet 30 | open System.Xml.Linq 31 | open System.Xml.XPath 32 | 33 | let sln = "./FSharp.Interop.Dynamic.sln" 34 | 35 | let commonBuild target = 36 | let buildMode = getBuildParamOrDefault "configuration" "Release" 37 | let vsuffix = getBuildParamOrDefault "vsuffix" "" 38 | 39 | let versionPrefix = "Version.props" 40 | |> System.IO.File.ReadAllText 41 | |> XDocument.Parse 42 | |> (fun x -> x.XPathEvaluate("//VersionPrefix/text()")) 43 | |> (fun x-> x :?> seq) 44 | |> Seq.exactlyOne 45 | |> sprintf "%A" 46 | 47 | let vProp = 48 | if System.Text.RegularExpressions.Regex.IsMatch(vsuffix, "^\d+$") then 49 | "Version", versionPrefix + "." + vsuffix 50 | else 51 | "VersionSuffix", vsuffix 52 | 53 | 54 | let setParams (defaults:MsBuild.MSBuildParams) = 55 | { defaults with 56 | ToolsVersion = Some("15.0") 57 | Verbosity = Some(MsBuild.MSBuildVerbosity.Quiet) 58 | Targets = [target] 59 | Properties = 60 | [ 61 | "Configuration", buildMode 62 | vProp 63 | ] 64 | } 65 | MsBuild.build setParams sln |> DoNothing 66 | 67 | Target "Restore" (fun () -> 68 | trace " --- Restore Packages --- " 69 | 70 | //because nuget doesn't know how to find msbuild15 on linux 71 | let restoreProj = fun args -> 72 | directExec (fun info -> 73 | info.FileName <- "msbuild" 74 | info.Arguments <- "/t:restore " + args) |> ignore 75 | 76 | sln |> restoreProj 77 | ) 78 | 79 | Target "Clean" (fun () -> 80 | trace " --- Cleaning stuff --- " 81 | commonBuild "Clean" 82 | ) 83 | 84 | Target "Build" (fun () -> 85 | trace " --- Building the libs --- " 86 | commonBuild "Build" 87 | ) 88 | 89 | Target "Test" (fun () -> 90 | trace " --- Test the libs --- " 91 | let sendToAppveyer outFile = 92 | let appveyor = environVarOrNone "APPVEYOR_JOB_ID" 93 | match appveyor with 94 | | Some(jobid) -> 95 | use webClient = new System.Net.WebClient() 96 | webClient.UploadFile(sprintf "https://ci.appveyor.com/api/testresults/nunit/%s" jobid, outFile) |> ignore 97 | | None -> () 98 | 99 | let buildMode = getBuildParamOrDefault "configuration" "Release" 100 | 101 | let testDirFromMoniker moniker = sprintf "./Tests/bin/%s/%s/" buildMode moniker 102 | let outputFileFromMoniker moniker = (testDirFromMoniker moniker) + (sprintf "TestResults.%s.xml" moniker) 103 | 104 | let testDir = testDirFromMoniker "net45" 105 | let outputFile = outputFileFromMoniker "net45" 106 | 107 | !! (testDir + "Tests.exe") 108 | |> NUnit3 (fun p -> 109 | { p with 110 | Labels = All 111 | ResultSpecs = [outputFile] }) 112 | 113 | sendToAppveyer outputFile 114 | try 115 | DotNetCli.Test 116 | (fun p -> 117 | { p with 118 | Framework = "netcoreapp2.0" 119 | Project = "Tests/Tests.fsproj" 120 | Configuration = buildMode 121 | AdditionalArgs =["--no-build";"--no-restore";"--logger=trx;LogFileName=testresults.trx"] 122 | }) 123 | 124 | finally 125 | let appveyor = environVarOrNone "APPVEYOR_JOB_ID" 126 | match appveyor with 127 | | Some(jobid) -> 128 | use webClient = new System.Net.WebClient() 129 | webClient.UploadFile(sprintf "https://ci.appveyor.com/api/testresults/mstest/%s" jobid,"./Tests/TestResults/testresults.trx") |> ignore 130 | | None -> () 131 | ) 132 | 133 | "Restore" 134 | ==> "Build" 135 | ==> "Test" 136 | 137 | RunTargetOrDefault "Test" 138 | 139 | 140 | #else 141 | 142 | open System 143 | open System.IO 144 | open System.Diagnostics 145 | 146 | (* helper functions *) 147 | #if mono_posix 148 | #r "Mono.Posix.dll" 149 | open Mono.Unix.Native 150 | let applyExecutionPermissionUnix path = 151 | let _,stat = Syscall.lstat(path) 152 | Syscall.chmod(path, FilePermissions.S_IXUSR ||| stat.st_mode) |> ignore 153 | #else 154 | let applyExecutionPermissionUnix path = () 155 | #endif 156 | 157 | let doesNotExist path = 158 | path |> Path.GetFullPath |> File.Exists |> not 159 | 160 | let execAt (workingDir:string) (exePath:string) (args:string seq) = 161 | let processStart (psi:ProcessStartInfo) = 162 | let ps = Process.Start(psi) 163 | ps.WaitForExit () 164 | ps.ExitCode 165 | let fullExePath = exePath |> Path.GetFullPath 166 | applyExecutionPermissionUnix fullExePath 167 | let exitCode = ProcessStartInfo( 168 | fullExePath, 169 | args |> String.concat " ", 170 | WorkingDirectory = (workingDir |> Path.GetFullPath), 171 | UseShellExecute = false) 172 | |> processStart 173 | if exitCode <> 0 then 174 | exit exitCode 175 | () 176 | 177 | let exec = execAt Environment.CurrentDirectory 178 | 179 | let downloadNugetTo path = 180 | let fullPath = path |> Path.GetFullPath; 181 | if doesNotExist fullPath then 182 | printf "Downloading NuGet..." 183 | use webClient = new System.Net.WebClient() 184 | fullPath |> Path.GetDirectoryName |> Directory.CreateDirectory |> ignore 185 | webClient.DownloadFile("https://dist.nuget.org/win-x86-commandline/latest/nuget.exe", path |> Path.GetFullPath) 186 | printfn "Done." 187 | 188 | let passedArgs = fsi.CommandLineArgs.[1..] |> Array.toList 189 | 190 | (* execution script customize below *) 191 | 192 | let makeFsx = fsi.CommandLineArgs.[0] 193 | 194 | let nugetExe = ".nuget/NuGet.exe" 195 | let fakeExe = "packages/FAKE/tools/FAKE.exe" 196 | 197 | downloadNugetTo nugetExe 198 | 199 | if doesNotExist fakeExe then 200 | exec nugetExe ["install"; "fake"; "-Version 5.0.0-alpha010" ; "-OutputDirectory packages"; "-ExcludeVersion"; "-PreRelease"] 201 | 202 | exec fakeExe ([makeFsx; "-d:FSharp_MakeFile"] @ passedArgs) 203 | 204 | #endif 205 | -------------------------------------------------------------------------------- /docs/content/img/github-blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsprojects/FSharp.Interop.Dynamic/c967f0fd067f28c9ca8c9d0ee085d7d3c4166714/docs/content/img/github-blue.png -------------------------------------------------------------------------------- /docs/content/img/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsprojects/FSharp.Interop.Dynamic/c967f0fd067f28c9ca8c9d0ee085d7d3c4166714/docs/content/img/github.png -------------------------------------------------------------------------------- /docs/content/style.css: -------------------------------------------------------------------------------- 1 | @import url(https://cdn.rawgit.com/tonsky/FiraCode/1.205/distr/fira_code.css); 2 | @import url(https://fonts.googleapis.com/css?family=Droid+Sans|Droid+Sans+Mono|Open+Sans:400,600,700); 3 | 4 | /*-------------------------------------------------------------------------- 5 | Formatting for F# code snippets 6 | /*--------------------------------------------------------------------------*/ 7 | 8 | /* strings --- and stlyes for other string related formats */ 9 | span.s { color:#E0E268; } 10 | /* printf formatters */ 11 | span.pf { color:#E0C57F; } 12 | /* escaped chars */ 13 | span.e { color:#EA8675; } 14 | 15 | /* identifiers --- and styles for more specific identifier types */ 16 | span.id { color:#d1d1d1; } 17 | /* module */ 18 | span.m { color:#43AEC6; } 19 | /* reference type */ 20 | span.rt { color:#43AEC6; } 21 | /* value type */ 22 | span.vt { color:#43AEC6; } 23 | /* interface */ 24 | span.if{ color:#43AEC6; } 25 | /* type argument */ 26 | span.ta { color:#43AEC6; } 27 | /* disposable */ 28 | span.d { color:#43AEC6; } 29 | /* property */ 30 | span.prop { color:#43AEC6; } 31 | /* punctuation */ 32 | span.p { color:#43AEC6; } 33 | /* function */ 34 | span.f { color:#e1e1e1; } 35 | /* active pattern */ 36 | span.pat { color:#4ec9b0; } 37 | /* union case */ 38 | span.u { color:#4ec9b0; } 39 | /* enumeration */ 40 | span.e { color:#4ec9b0; } 41 | /* keywords */ 42 | span.k { color:#FAB11D; } 43 | /* comment */ 44 | span.c { color:#808080; } 45 | /* operators */ 46 | span.o { color:#af75c1; } 47 | /* numbers */ 48 | span.n { color:#96C71D; } 49 | /* line number */ 50 | span.l { color:#80b0b0; } 51 | /* mutable var or ref cell */ 52 | span.v { color:#d1d1d1; font-weight: bold; } 53 | /* inactive code */ 54 | span.inactive { color:#808080; } 55 | /* preprocessor */ 56 | span.prep { color:#af75c1; } 57 | /* fsi output */ 58 | span.fsi { color:#808080; } 59 | 60 | /* omitted */ 61 | span.omitted { 62 | background:#3c4e52; 63 | border-radius:5px; 64 | color:#808080; 65 | padding:0px 0px 1px 0px; 66 | } 67 | /* tool tip */ 68 | div.tip { 69 | background:#475b5f; 70 | border-radius:4px; 71 | font:11pt 'Droid Sans', arial, sans-serif; 72 | padding:6px 8px 6px 8px; 73 | display:none; 74 | color:#d1d1d1; 75 | pointer-events:none; 76 | } 77 | table.pre pre { 78 | padding:0px; 79 | margin:0px; 80 | border:none; 81 | } 82 | table.pre, pre.fssnip, pre { 83 | line-height:13pt; 84 | border:1px solid #d8d8d8; 85 | border-collapse:separate; 86 | white-space:pre; 87 | font: 9pt 'Fira Code','Droid Sans Mono',consolas,monospace; 88 | width:90%; 89 | margin:10px 20px 20px 20px; 90 | background-color:#212d30; 91 | padding:10px; 92 | border-radius:5px; 93 | color:#d1d1d1; 94 | max-width: none; 95 | } 96 | pre.fssnip code { 97 | font: 9pt 'Fira Code','Droid Sans Mono',consolas,monospace; 98 | } 99 | table.pre pre { 100 | padding:0px; 101 | margin:0px; 102 | border-radius:0px; 103 | width: 100%; 104 | } 105 | table.pre td { 106 | padding:0px; 107 | white-space:normal; 108 | margin:0px; 109 | } 110 | table.pre td.lines { 111 | width:30px; 112 | } 113 | 114 | /*-------------------------------------------------------------------------- 115 | Formatting for page & standard document content 116 | /*--------------------------------------------------------------------------*/ 117 | 118 | body { 119 | font-family: 'Open Sans', serif; 120 | padding-top: 0px; 121 | padding-bottom: 40px; 122 | } 123 | 124 | pre { 125 | word-wrap: inherit; 126 | } 127 | 128 | /* Format the heading - nicer spacing etc. */ 129 | .masthead { 130 | overflow: hidden; 131 | } 132 | .masthead .muted a { 133 | text-decoration:none; 134 | color:#999999; 135 | } 136 | .masthead ul, .masthead li { 137 | margin-bottom:0px; 138 | } 139 | .masthead .nav li { 140 | margin-top: 15px; 141 | font-size:110%; 142 | } 143 | .masthead h3 { 144 | margin-bottom:5px; 145 | font-size:170%; 146 | } 147 | hr { 148 | margin:0px 0px 20px 0px; 149 | } 150 | 151 | /* Make table headings and td.title bold */ 152 | td.title, thead { 153 | font-weight:bold; 154 | } 155 | 156 | /* Format the right-side menu */ 157 | #menu { 158 | margin-top:50px; 159 | font-size:11pt; 160 | padding-left:20px; 161 | } 162 | 163 | #menu .nav-header { 164 | font-size:12pt; 165 | color:#606060; 166 | margin-top:20px; 167 | } 168 | 169 | #menu li { 170 | line-height:25px; 171 | } 172 | 173 | /* Change font sizes for headings etc. */ 174 | #main h1 { font-size: 26pt; margin:10px 0px 15px 0px; font-weight:400; } 175 | #main h2 { font-size: 20pt; margin:20px 0px 0px 0px; font-weight:400; } 176 | #main h3 { font-size: 14pt; margin:15px 0px 0px 0px; font-weight:600; } 177 | #main p { font-size: 11pt; margin:5px 0px 15px 0px; } 178 | #main ul { font-size: 11pt; margin-top:10px; } 179 | #main li { font-size: 11pt; margin: 5px 0px 5px 0px; } 180 | #main strong { font-weight:700; } 181 | 182 | /*-------------------------------------------------------------------------- 183 | Formatting for API reference 184 | /*--------------------------------------------------------------------------*/ 185 | 186 | .type-list .type-name, .module-list .module-name { 187 | width:25%; 188 | font-weight:bold; 189 | } 190 | .member-list .member-name { 191 | width:35%; 192 | } 193 | #main .xmldoc h2 { 194 | font-size:14pt; 195 | margin:10px 0px 0px 0px; 196 | } 197 | #main .xmldoc h3 { 198 | font-size:12pt; 199 | margin:10px 0px 0px 0px; 200 | } 201 | .github-link { 202 | float:right; 203 | text-decoration:none; 204 | } 205 | .github-link img { 206 | border-style:none; 207 | margin-left:10px; 208 | } 209 | .github-link .hover { display:none; } 210 | .github-link:hover .hover { display:block; } 211 | .github-link .normal { display: block; } 212 | .github-link:hover .normal { display: none; } 213 | 214 | /*-------------------------------------------------------------------------- 215 | Links 216 | /*--------------------------------------------------------------------------*/ 217 | 218 | h1 a, h1 a:hover, h1 a:focus, 219 | h2 a, h2 a:hover, h2 a:focus, 220 | h3 a, h3 a:hover, h3 a:focus, 221 | h4 a, h4 a:hover, h4 a:focus, 222 | h5 a, h5 a:hover, h5 a:focus, 223 | h6 a, h6 a:hover, h6 a:focus { color : inherit; text-decoration : inherit; outline:none } 224 | 225 | /*-------------------------------------------------------------------------- 226 | Additional formatting for the homepage 227 | /*--------------------------------------------------------------------------*/ 228 | 229 | #nuget { 230 | margin-top:20px; 231 | font-size: 11pt; 232 | padding:20px; 233 | } 234 | 235 | #nuget pre { 236 | font-size:11pt; 237 | -moz-border-radius: 0px; 238 | -webkit-border-radius: 0px; 239 | border-radius: 0px; 240 | background: #404040; 241 | border-style:none; 242 | color: #e0e0e0; 243 | margin-top:15px; 244 | } 245 | -------------------------------------------------------------------------------- /docs/content/style_light.css: -------------------------------------------------------------------------------- 1 | @import url(https://fonts.googleapis.com/css?family=Droid+Sans|Droid+Sans+Mono|Open+Sans:400,600,700); 2 | 3 | /*-------------------------------------------------------------------------- 4 | Formatting for F# code snippets 5 | /*--------------------------------------------------------------------------*/ 6 | 7 | /* identifier */ 8 | span.i { color:#000000; } 9 | /* string */ 10 | span.s { color:#a31515; } 11 | /* keywords */ 12 | span.k { color:#0000ff; } 13 | /* comment */ 14 | span.c { color:#008000; } 15 | /* operators */ 16 | span.o { color:#000000; } 17 | /* numbers */ 18 | span.n { color:#000000; } 19 | /* line number */ 20 | span.l { color:#96c2cd; } 21 | /* type or module */ 22 | span.t { color:#2b91af; } 23 | /* function */ 24 | span.f { color:#0000a0; } 25 | /* DU case or active pattern */ 26 | span.p { color:#800080; } 27 | /* mutable var or ref cell */ 28 | span.v { color:#000000; font-weight: bold; } 29 | /* printf formatters */ 30 | span.pf { color:#2b91af; } 31 | /* escaped chars */ 32 | span.e { color:#ff0080; } 33 | /* mutable var or ref cell */ 34 | 35 | 36 | /* inactive code */ 37 | span.inactive { color:#808080; } 38 | /* preprocessor */ 39 | span.prep { color:#0000ff; } 40 | /* fsi output */ 41 | span.fsi { color:#808080; } 42 | 43 | /* omitted */ 44 | span.omitted { 45 | background:#3c4e52; 46 | border-radius:5px; 47 | color:#808080; 48 | padding:0px 0px 1px 0px; 49 | } 50 | /* tool tip */ 51 | div.tip { 52 | background:#e5e5e5; 53 | border-radius:4px; 54 | font:9pt 'Droid Sans', arial, sans-serif; 55 | padding:6px 8px 6px 8px; 56 | display:none; 57 | color:#000000; 58 | pointer-events:none; 59 | } 60 | table.pre pre { 61 | padding:0px; 62 | margin:0px; 63 | border:none; 64 | } 65 | table.pre, pre.fssnip, pre { 66 | line-height:13pt; 67 | border:1px solid #d8d8d8; 68 | border-collapse:separate; 69 | white-space:pre; 70 | font: 10pt consolas,monospace; 71 | width:90%; 72 | margin:10px 20px 20px 20px; 73 | background-color:#fdfdfd; 74 | padding:10px; 75 | border-radius:5px; 76 | color:#000000; 77 | max-width: none; 78 | } 79 | pre.fssnip code { 80 | font: 9pt 'Droid Sans Mono',consolas,monospace; 81 | } 82 | table.pre pre { 83 | padding:0px; 84 | margin:0px; 85 | border-radius:0px; 86 | width: 100%; 87 | } 88 | table.pre td { 89 | padding:0px; 90 | white-space:normal; 91 | margin:0px; 92 | } 93 | table.pre td.lines { 94 | width:30px; 95 | } 96 | 97 | /*-------------------------------------------------------------------------- 98 | Formatting for page & standard document content 99 | /*--------------------------------------------------------------------------*/ 100 | 101 | body { 102 | font-family: 'Open Sans', serif; 103 | padding-top: 0px; 104 | padding-bottom: 40px; 105 | } 106 | 107 | pre { 108 | word-wrap: inherit; 109 | } 110 | 111 | /* Format the heading - nicer spacing etc. */ 112 | .masthead { 113 | overflow: hidden; 114 | } 115 | .masthead .muted a { 116 | text-decoration:none; 117 | color:#999999; 118 | } 119 | .masthead ul, .masthead li { 120 | margin-bottom:0px; 121 | } 122 | .masthead .nav li { 123 | margin-top: 15px; 124 | font-size:110%; 125 | } 126 | .masthead h3 { 127 | margin-bottom:5px; 128 | font-size:170%; 129 | } 130 | hr { 131 | margin:0px 0px 20px 0px; 132 | } 133 | 134 | /* Make table headings and td.title bold */ 135 | td.title, thead { 136 | font-weight:bold; 137 | } 138 | 139 | /* Format the right-side menu */ 140 | #menu { 141 | margin-top:50px; 142 | font-size:11pt; 143 | padding-left:20px; 144 | } 145 | 146 | #menu .nav-header { 147 | font-size:12pt; 148 | color:#606060; 149 | margin-top:20px; 150 | } 151 | 152 | #menu li { 153 | line-height:25px; 154 | } 155 | 156 | /* Change font sizes for headings etc. */ 157 | #main h1 { font-size: 26pt; margin:10px 0px 15px 0px; font-weight:400; } 158 | #main h2 { font-size: 20pt; margin:20px 0px 0px 0px; font-weight:400; } 159 | #main h3 { font-size: 14pt; margin:15px 0px 0px 0px; font-weight:600; } 160 | #main p { font-size: 11pt; margin:5px 0px 15px 0px; } 161 | #main ul { font-size: 11pt; margin-top:10px; } 162 | #main li { font-size: 11pt; margin: 5px 0px 5px 0px; } 163 | #main strong { font-weight:700; } 164 | 165 | /*-------------------------------------------------------------------------- 166 | Formatting for API reference 167 | /*--------------------------------------------------------------------------*/ 168 | 169 | .type-list .type-name, .module-list .module-name { 170 | width:25%; 171 | font-weight:bold; 172 | } 173 | .member-list .member-name { 174 | width:35%; 175 | } 176 | #main .xmldoc h2 { 177 | font-size:14pt; 178 | margin:10px 0px 0px 0px; 179 | } 180 | #main .xmldoc h3 { 181 | font-size:12pt; 182 | margin:10px 0px 0px 0px; 183 | } 184 | .github-link { 185 | float:right; 186 | text-decoration:none; 187 | } 188 | .github-link img { 189 | border-style:none; 190 | margin-left:10px; 191 | } 192 | .github-link .hover { display:none; } 193 | .github-link:hover .hover { display:block; } 194 | .github-link .normal { display: block; } 195 | .github-link:hover .normal { display: none; } 196 | 197 | /*-------------------------------------------------------------------------- 198 | Links 199 | /*--------------------------------------------------------------------------*/ 200 | 201 | h1 a, h1 a:hover, h1 a:focus, 202 | h2 a, h2 a:hover, h2 a:focus, 203 | h3 a, h3 a:hover, h3 a:focus, 204 | h4 a, h4 a:hover, h4 a:focus, 205 | h5 a, h5 a:hover, h5 a:focus, 206 | h6 a, h6 a:hover, h6 a:focus { color : inherit; text-decoration : inherit; outline:none } 207 | 208 | /*-------------------------------------------------------------------------- 209 | Additional formatting for the homepage 210 | /*--------------------------------------------------------------------------*/ 211 | 212 | #nuget { 213 | margin-top:20px; 214 | font-size: 11pt; 215 | padding:20px; 216 | } 217 | 218 | #nuget pre { 219 | font-size:11pt; 220 | -moz-border-radius: 0px; 221 | -webkit-border-radius: 0px; 222 | border-radius: 0px; 223 | background: #404040; 224 | border-style:none; 225 | color: #e0e0e0; 226 | margin-top:15px; 227 | } 228 | -------------------------------------------------------------------------------- /docs/content/tips.js: -------------------------------------------------------------------------------- 1 | var currentTip = null; 2 | var currentTipElement = null; 3 | 4 | function hideTip(evt, name, unique) { 5 | var el = document.getElementById(name); 6 | el.style.display = "none"; 7 | currentTip = null; 8 | } 9 | 10 | function findPos(obj) { 11 | // no idea why, but it behaves differently in webbrowser component 12 | if (window.location.search == "?inapp") 13 | return [obj.offsetLeft + 10, obj.offsetTop + 30]; 14 | 15 | var curleft = 0; 16 | var curtop = obj.offsetHeight; 17 | while (obj) { 18 | curleft += obj.offsetLeft; 19 | curtop += obj.offsetTop; 20 | obj = obj.offsetParent; 21 | }; 22 | return [curleft, curtop]; 23 | } 24 | 25 | function hideUsingEsc(e) { 26 | if (!e) { e = event; } 27 | hideTip(e, currentTipElement, currentTip); 28 | } 29 | 30 | function showTip(evt, name, unique, owner) { 31 | document.onkeydown = hideUsingEsc; 32 | if (currentTip == unique) return; 33 | currentTip = unique; 34 | currentTipElement = name; 35 | 36 | var pos = findPos(owner ? owner : (evt.srcElement ? evt.srcElement : evt.target)); 37 | var posx = pos[0]; 38 | var posy = pos[1]; 39 | 40 | var el = document.getElementById(name); 41 | var parent = (document.documentElement == null) ? document.body : document.documentElement; 42 | el.style.position = "absolute"; 43 | el.style.left = posx + "px"; 44 | el.style.top = posy + "px"; 45 | el.style.display = "block"; 46 | } -------------------------------------------------------------------------------- /docs/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsprojects/FSharp.Interop.Dynamic/c967f0fd067f28c9ca8c9d0ee085d7d3c4166714/docs/images/logo.png -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | FSharp.Interop.Dynamic <a href="https://www.nuget.org/packages/FSharp.Interop.Dynamic/"><img src="http://img.shields.io/nuget/v/FSharp.Interop.Dynamic.svg?style=flat" alt="NuGet Status" /></a> 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 24 | 25 | 26 |
27 |
28 | 32 |

FSharp.Interop.Dynamic

33 |
34 |
35 |
36 |
37 | 38 |

FSharp.Interop.Dynamic NuGet Status

39 |

The F# Dynamic Operator, powered by the DLR. Compiled for .NET Standard 2.0, .NET Standard 1.6, .NET Framework 4.5

40 |

Install from NuGet

41 | 43 | 45 | 46 |
1: 
 42 | 
PM> Install-Package FSharp.Interop.Dynamic
 44 | 
47 |

Build Status

48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 |

Platform

Status

Nuget Deployment

Build status

Mac/Linux/Windows

Action Status

Coverage

codecov Coverage Status

70 | 71 |

Bleeding edge feed on MyGet

72 |

MyGet Pre Release

73 |

Usage

74 |

target?Property, target?Property<-value, and target?Method(arg,arg2) allow you to dynamically get/set properties and call methods

75 |

Also Dyn.implicitConvert,Dyn.explicitConvert, comparison operators and more.

76 |

Examples:

77 |

System.Dynamic

78 | 83 | 88 | 89 |
1: 
 79 | 2: 
 80 | 3: 
 81 | 4: 
 82 | 
open FSharp.Interop.Dynamic
 84 | let ex1 = ExpandoObject()
 85 | ex1?Test<-"Hi"//Set Dynamic Property
 86 | ex1?Test //Get Dynamic
 87 | 
90 |

MVC ViewBag

91 | 93 | 95 | 96 |
1: 
 92 | 
x.ViewBag?Name<-"George"
 94 | 
97 |

Dynamitey

98 | 110 | 122 | 123 |
 1: 
 99 |  2: 
100 |  3: 
101 |  4: 
102 |  5: 
103 |  6: 
104 |  7: 
105 |  8: 
106 |  9: 
107 | 10: 
108 | 11: 
109 | 
open FSharp.Interop.Dynamic
111 | open Dynamitey.DynamicObjects
112 | 
113 | let ComBinder = LateType("System.Dynamic.ComBinder, System.Dynamic, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
114 | 
115 | let getPropertyNames (target:obj) =
116 |   seq {
117 |     yield! target.GetType().GetTypeInfo().GetProperties().Select(fun it -> it.Name)
118 |     if (ComBinder.IsAvailable) then
119 |       yield! ComBinder?GetDynamicDataMemberNames(target)
120 |   }
121 | 
124 |

Python Interop

125 | 136 | 147 | 148 |
 1: 
126 |  2: 
127 |  3: 
128 |  4: 
129 |  5: 
130 |  6: 
131 |  7: 
132 |  8: 
133 |  9: 
134 | 10: 
135 | 
open Python.Runtime
137 | open FSharp.Interop.Dynamic
138 | open FSharp.Interop.Dynamic.Operators
139 | do
140 |   use __ = Py.GIL()
141 |   let math = Py.Import(
142 |   math?cos(math?pi ?*? 2) |> printfn 
143 |   let sin = math?sin
144 |   sin 5 |> printfn 
145 |   math?cos(5) ?+? sin(5) |> printfn 
146 | 
149 |

SignalR (.net framework version)

150 | 156 | 162 | 163 |
1: 
151 | 2: 
152 | 3: 
153 | 4: 
154 | 5: 
155 | 
open FSharp.Interop.Dynamic
157 | type MyHub =
158 |     inherit Hub
159 |     member x.Send (name : string) (message : string) =
160 |         base.Clients.All?addMessage(name,message) |> ignore
161 | 
164 |

Caveats:

165 |

The DLR is incompatible with interface explicit members, so are these operators, just like C#'s dynamic keyword.

166 |

.NET Core 2.0.0 to 2.0.2 had a major bug in the C# dynamic keyword with nested classes inside of generic classes.. You will know it from a substring argument length exception. .NET Framework 4.0+, .NET Core 1.x and .NET Core 2.0.3+ and later are unaffected.

167 |

Maintainer(s)

168 | 172 |

The default maintainer account for projects under "fsprojects" is @fsprojectsgit - F# Community Project Incubation Space (repo management)

173 | 174 |
Multiple items
namespace FSharp

--------------------
namespace Microsoft.FSharp
175 |
namespace FSharp.Interop
176 |
namespace FSharp.Interop.Dynamic
177 |
val ex1 : obj
178 |
val ComBinder : obj
179 |
val getPropertyNames : target:obj -> seq<'a>
180 |
val target : obj
181 |
type obj = System.Object
182 |
Multiple items
val seq : sequence:seq<'T> -> seq<'T>

--------------------
type seq<'T> = System.Collections.Generic.IEnumerable<'T>
183 |
System.Object.GetType() : System.Type
184 |
module Operators

from FSharp.Interop.Dynamic
185 |
val __ : 'a (requires 'a :> System.IDisposable)
186 |
val math : 'a
187 |
val cos : value:'T -> 'T (requires member Cos)
188 |
val printfn : format:Printf.TextWriterFormat<'T> -> 'T
189 |
val sin : value:'T -> 'T (requires member Sin)
190 |
Multiple items
val string : value:'T -> string

--------------------
type string = System.String
191 |
val ignore : value:'T -> unit
192 | 193 |
194 |
195 | 196 | 197 | 198 | 199 | 218 |
219 |
220 |
221 | Fork me on GitHub 222 | 223 | 224 | -------------------------------------------------------------------------------- /docs/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsprojects/FSharp.Interop.Dynamic/c967f0fd067f28c9ca8c9d0ee085d7d3c4166714/docs/logo.png -------------------------------------------------------------------------------- /docs/reference/fsharp-interop-dynamic-calling.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Calling - FSharp.Interop.Dynamic 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 23 | 24 | 25 |
26 |
27 | 31 |

FSharp.Interop.Dynamic

32 |
33 |
34 |
35 |
36 | 37 | 38 | 39 | 40 |

Calling

41 |

42 | Namespace: FSharp.Interop.Dynamic
43 |

44 |
45 |
46 |

Union Cases

47 | 48 | 49 | 50 | 51 | 52 | 53 | 62 | 69 | 70 | 71 | 80 | 87 | 88 | 89 | 98 | 105 | 106 | 107 |
Union CaseDescription
54 | 55 | 56 | Direct 57 | 58 |
59 | Signature:
60 |
61 |
63 | 64 | 65 | 66 | 67 | 68 |
72 | 73 | 74 | GenericMember(string,Type array) 75 | 76 |
77 | Signature: string * Type array
78 |
79 |
81 | 82 | 83 | 84 | 85 | 86 |
90 | 91 | 92 | Member(string) 93 | 94 |
95 | Signature: string
96 |
97 |
99 | 100 | 101 | 102 | 103 | 104 |
108 | 109 |
110 |
111 | 112 | 113 | 114 | 115 | 134 |
135 |
136 |
137 | Fork me on GitHub 138 | 139 | 140 | -------------------------------------------------------------------------------- /docs/reference/fsharp-interop-dynamic-operators.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Operators - FSharp.Interop.Dynamic 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 23 | 24 | 25 |
26 |
27 | 31 |

FSharp.Interop.Dynamic

32 |
33 |
34 |
35 |
36 | 37 | 38 | 39 | 40 |

Operators

41 |

42 | Namespace: FSharp.Interop.Dynamic
43 |

44 |
45 |

Additional operators to dyanmically do normal operations

46 | 47 |
48 | 49 | 50 | 51 |

Functions and values

52 | 53 | 54 | 55 | 56 | 57 | 58 | 67 | 75 | 76 | 77 | 86 | 94 | 95 | 96 | 105 | 113 | 114 | 115 | 124 | 132 | 133 | 134 | 143 | 151 | 152 | 153 | 162 | 170 | 171 | 172 | 181 | 189 | 190 | 191 | 200 | 208 | 209 | 210 | 219 | 227 | 228 | 229 | 238 | 246 | 247 | 248 | 257 | 265 | 266 | 267 | 276 | 284 | 285 | 286 | 295 | 303 | 304 | 305 | 314 | 322 | 323 | 324 | 333 | 341 | 342 | 343 | 352 | 360 | 361 | 362 |
Function or valueDescription
59 | 60 | 61 | ( ?%? ) left right 62 | 63 |
64 | Signature: left:obj -> right:obj -> 'TResult
65 | Type parameters: 'TResult
66 |
68 | 69 | 70 | 71 | 72 | 73 |

CompiledName: op_QmarkPercentQmark

74 |
78 | 79 | 80 | ( ?&&&? ) left right 81 | 82 |
83 | Signature: left:obj -> right:obj -> 'TResult
84 | Type parameters: 'TResult
85 |
87 | 88 | 89 | 90 | 91 | 92 |

CompiledName: op_QmarkAmpAmpAmpQmark

93 |
97 | 98 | 99 | ( ?*? ) left right 100 | 101 |
102 | Signature: left:obj -> right:obj -> 'TResult
103 | Type parameters: 'TResult
104 |
106 | 107 | 108 | 109 | 110 | 111 |

CompiledName: op_QmarkMultiplyQmark

112 |
116 | 117 | 118 | ( ?/? ) left right 119 | 120 |
121 | Signature: left:obj -> right:obj -> 'TResult
122 | Type parameters: 'TResult
123 |
125 | 126 | 127 | 128 | 129 | 130 |

CompiledName: op_QmarkDivideQmark

131 |
135 | 136 | 137 | ( ?-? ) left right 138 | 139 |
140 | Signature: left:obj -> right:obj -> 'TResult
141 | Type parameters: 'TResult
142 |
144 | 145 | 146 | 147 | 148 | 149 |

CompiledName: op_QmarkMinusQmark

150 |
154 | 155 | 156 | ( ?^^^? ) left right 157 | 158 |
159 | Signature: left:obj -> right:obj -> 'TResult
160 | Type parameters: 'TResult
161 |
163 | 164 | 165 | 166 | 167 | 168 |

CompiledName: op_QmarkHatHatHatQmark

169 |
173 | 174 | 175 | ( ?|||? ) left right 176 | 177 |
178 | Signature: left:obj -> right:obj -> 'TResult
179 | Type parameters: 'TResult
180 |
182 | 183 | 184 | 185 | 186 | 187 |

CompiledName: op_QmarkBarBarBarQmark

188 |
192 | 193 | 194 | ( ?+? ) left right 195 | 196 |
197 | Signature: left:obj -> right:obj -> 'TResult
198 | Type parameters: 'TResult
199 |
201 | 202 | 203 | 204 | 205 | 206 |

CompiledName: op_QmarkPlusQmark

207 |
211 | 212 | 213 | ( ?<? ) left right 214 | 215 |
216 | Signature: left:obj -> right:obj -> bool
217 |
218 |
220 | 221 | 222 | 223 | 224 | 225 |

CompiledName: op_QmarkLessQmark

226 |
230 | 231 | 232 | ( ?<<<? ) left right 233 | 234 |
235 | Signature: left:obj -> right:obj -> 'TResult
236 | Type parameters: 'TResult
237 |
239 | 240 | 241 | 242 | 243 | 244 |

CompiledName: op_QmarkLessLessLessQmark

245 |
249 | 250 | 251 | ( ?<=? ) left right 252 | 253 |
254 | Signature: left:obj -> right:obj -> bool
255 |
256 |
258 | 259 | 260 | 261 | 262 | 263 |

CompiledName: op_QmarkLessEqualsQmark

264 |
268 | 269 | 270 | ( ?<>? ) left right 271 | 272 |
273 | Signature: left:obj -> right:obj -> bool
274 |
275 |
277 | 278 | 279 | 280 | 281 | 282 |

CompiledName: op_QmarkLessGreaterQmark

283 |
287 | 288 | 289 | ( ?=? ) left right 290 | 291 |
292 | Signature: left:obj -> right:obj -> bool
293 |
294 |
296 | 297 | 298 | 299 | 300 | 301 |

CompiledName: op_QmarkEqualsQmark

302 |
306 | 307 | 308 | ( ?>? ) left right 309 | 310 |
311 | Signature: left:obj -> right:obj -> bool
312 |
313 |
315 | 316 | 317 | 318 | 319 | 320 |

CompiledName: op_QmarkGreaterQmark

321 |
325 | 326 | 327 | ( ?>=? ) left right 328 | 329 |
330 | Signature: left:obj -> right:obj -> bool
331 |
332 |
334 | 335 | 336 | 337 | 338 | 339 |

CompiledName: op_QmarkGreaterEqualsQmark

340 |
344 | 345 | 346 | ( ?>>>? ) left right 347 | 348 |
349 | Signature: left:obj -> right:obj -> 'TResult
350 | Type parameters: 'TResult
351 |
353 | 354 | 355 | 356 | 357 | 358 |

CompiledName: op_QmarkGreaterGreaterGreaterQmark

359 |
363 | 364 |
365 |
366 | 367 | 368 | 369 | 370 | 389 |
390 |
391 |
392 | Fork me on GitHub 393 | 394 | 395 | -------------------------------------------------------------------------------- /docs/reference/fsharp-interop-dynamic-symbolicstring-leafinfo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | LeafInfo - FSharp.Interop.Dynamic 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 23 | 24 | 25 |
26 |
27 | 31 |

FSharp.Interop.Dynamic

32 |
33 |
34 |
35 |
36 | 37 | 38 | 39 | 40 |

LeafInfo

41 |

42 | Namespace: FSharp.Interop.Dynamic
43 | Parent Module: SymbolicString 44 |

45 |
46 |
47 |

Record Fields

48 | 49 | 50 | 51 | 52 | 53 | 54 | 63 | 70 | 71 | 72 | 81 | 88 | 89 | 90 | 99 | 106 | 107 | 108 |
Record FieldDescription
55 | 56 | 57 | DeclaringType 58 | 59 |
60 | Signature: Type option
61 |
62 |
64 | 65 | 66 | 67 | 68 | 69 |
73 | 74 | 75 | Name 76 | 77 |
78 | Signature: string
79 |
80 |
82 | 83 | 84 | 85 | 86 | 87 |
91 | 92 | 93 | ReturnType 94 | 95 |
96 | Signature: Type
97 |
98 |
100 | 101 | 102 | 103 | 104 | 105 |
109 | 110 |
111 |
112 | 113 | 114 | 115 | 116 | 135 |
136 |
137 |
138 | Fork me on GitHub 139 | 140 | 141 | -------------------------------------------------------------------------------- /docs/reference/fsharp-interop-dynamic-symbolicstring-symbol.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Symbol - FSharp.Interop.Dynamic 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 23 | 24 | 25 |
26 |
27 | 31 |

FSharp.Interop.Dynamic

32 |
33 |
34 |
35 |
36 | 37 | 38 | 39 | 40 |

Symbol

41 |

42 | Namespace: FSharp.Interop.Dynamic
43 | Parent Module: SymbolicString 44 |

45 |
46 |
47 |

Static members

48 | 49 | 50 | 51 | 52 | 53 | 54 | 63 | 70 | 71 | 72 | 81 | 88 | 89 | 90 | 99 | 106 | 107 | 108 |
Static memberDescription
55 | 56 | 57 | leafInfoOf(value) 58 | 59 |
60 | Signature: value:Expr<'T> -> LeafInfo
61 | Type parameters: 'T
62 |
64 | 65 | 66 | 67 | 68 | 69 |
73 | 74 | 75 | nameOf(value) 76 | 77 |
78 | Signature: value:Expr<'T> -> string
79 | Type parameters: 'T
80 |
82 | 83 | 84 | 85 | 86 | 87 |
91 | 92 | 93 | typeOf(value) 94 | 95 |
96 | Signature: value:Expr<'T> -> Type
97 | Type parameters: 'T
98 |
100 | 101 | 102 | 103 | 104 | 105 |
109 | 110 |
111 |
112 | 113 | 114 | 115 | 116 | 135 |
136 |
137 |
138 | Fork me on GitHub 139 | 140 | 141 | -------------------------------------------------------------------------------- /docs/reference/fsharp-interop-dynamic-symbolicstring.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SymbolicString - FSharp.Interop.Dynamic 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 23 | 24 | 25 |
26 |
27 | 31 |

FSharp.Interop.Dynamic

32 |
33 |
34 |
35 |
36 | 37 | 38 | 39 | 40 |

SymbolicString

41 |

42 | Namespace: FSharp.Interop.Dynamic
43 |

44 |
45 |
46 | 47 | 48 |

Nested types and modules

49 |
50 | 51 | 52 | 53 | 54 | 55 | 56 | 59 | 60 | 61 | 62 | 65 | 66 | 67 | 68 |
TypeDescription
57 | LeafInfo 58 |
63 | Symbol 64 |
69 | 70 |
71 | 72 |

Functions and values

73 | 74 | 75 | 76 | 77 | 78 | 79 | 88 | 95 | 96 | 97 |
Function or valueDescription
80 | 81 | 82 | sym 83 | 84 |
85 | Signature: 'TTarget
86 | Type parameters: 'TTarget
87 |
89 | 90 | 91 | 92 | 93 | 94 |
98 | 99 |
100 |
101 | 102 | 103 | 104 | 105 | 124 |
125 |
126 |
127 | Fork me on GitHub 128 | 129 | 130 | -------------------------------------------------------------------------------- /docs/reference/fsharp-interop-dynamic-topleveloperators.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | TopLevelOperators - FSharp.Interop.Dynamic 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 23 | 24 | 25 |
26 |
27 | 31 |

FSharp.Interop.Dynamic

32 |
33 |
34 |
35 |
36 | 37 | 38 | 39 | 40 |

TopLevelOperators

41 |

42 | Namespace: FSharp.Interop.Dynamic
43 |

44 |
45 |

Main operators for dynamic invocation

46 | 47 |
48 | 49 | 50 | 51 |

Functions and values

52 | 53 | 54 | 55 | 56 | 57 | 58 | 67 | 77 | 78 | 79 | 88 | 98 | 99 | 100 | 109 | 119 | 120 | 121 |
Function or valueDescription
59 | 60 | 61 | ( !? ) target 62 | 63 |
64 | Signature: target:obj -> 'TResult
65 | Type parameters: 'TResult
66 |
68 | 69 | 70 | 71 | 72 |

Prefix operator that allows direct dynamic invocation of the object

73 | 74 | 75 |

CompiledName: op_BangQmark

76 |
80 | 81 | 82 | ( ? ) target name 83 | 84 |
85 | Signature: target:obj -> name:string -> 'TResult
86 | Type parameters: 'TResult
87 |
89 | 90 | 91 | 92 | 93 |

Dynamic get property or method invocation

94 | 95 | 96 |

CompiledName: op_Dynamic

97 |
101 | 102 | 103 | ( ?<- ) target name value 104 | 105 |
106 | Signature: target:obj -> name:string -> value:'TValue -> unit
107 | Type parameters: 'TValue
108 |
110 | 111 | 112 | 113 | 114 |

Dynamic set property

115 | 116 | 117 |

CompiledName: op_DynamicAssignment

118 |
122 | 123 |
124 |
125 | 126 | 127 | 128 | 129 | 148 |
149 |
150 |
151 | Fork me on GitHub 152 | 153 | 154 | -------------------------------------------------------------------------------- /docs/reference/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Namespaces - FSharp.Interop.Dynamic 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 23 | 24 | 25 |
26 |
27 | 31 |

FSharp.Interop.Dynamic

32 |
33 |
34 |
35 |
36 | 37 | 38 |

FSharp.Interop.Dynamic

39 | 40 | 41 |

FSharp.Interop.Dynamic Namespace

42 |
43 | 44 | 45 | 46 | 47 | 48 | 49 | 52 | 53 | 54 | 55 |
TypeDescription
50 | Calling 51 |
56 | 57 | 58 | 59 | 60 | 61 | 62 | 65 | 68 | 69 | 70 | 73 | 76 | 77 | 78 | 81 | 82 | 83 | 84 | 87 | 90 | 91 | 92 |
ModuleDescription
63 | Dyn 64 |

Functions backing the operators and more

66 | 67 |
71 | Operators 72 |

Additional operators to dyanmically do normal operations

74 | 75 |
79 | SymbolicString 80 |
85 | TopLevelOperators 86 |

Main operators for dynamic invocation

88 | 89 |
93 | 94 |
95 | 96 |
97 |
98 | 99 | 100 | 101 | 102 | 121 |
122 |
123 |
124 | Fork me on GitHub 125 | 126 | 127 | -------------------------------------------------------------------------------- /monofx.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | true 7 | 8 | 9 | /Library/Frameworks/Mono.framework/Versions/Current/lib/mono 10 | /usr/lib/mono 11 | /usr/local/lib/mono 12 | 13 | 14 | $(BaseFrameworkPathOverrideForMono)/4.5-api 15 | $(BaseFrameworkPathOverrideForMono)/4.5.1-api 16 | $(BaseFrameworkPathOverrideForMono)/4.5.2-api 17 | $(BaseFrameworkPathOverrideForMono)/4.6-api 18 | $(BaseFrameworkPathOverrideForMono)/4.6.1-api 19 | $(BaseFrameworkPathOverrideForMono)/4.6.2-api 20 | $(BaseFrameworkPathOverrideForMono)/4.7-api 21 | $(BaseFrameworkPathOverrideForMono)/4.7.1-api 22 | true 23 | 24 | 25 | $(FrameworkPathOverride)/Facades;$(AssemblySearchPaths) 26 | 27 | 28 | 29 | 30 | --------------------------------------------------------------------------------