diff --git a/CHANGES.txt b/CHANGES.txt
new file mode 100644
index 0000000000..7437c03ddd
--- /dev/null
+++ b/CHANGES.txt
@@ -0,0 +1,20 @@
+
+HEAD
+ * Added tests
+
+ * Merged F# 3.1 open source release
+
+ * Fixed build logic for F# 3.1
+
+3.0.30
+ * Partial fix for allowing F# 3.1 projects to compile using xbuild (also
+ requires xbuild fix)
+
+ * Remove a multitude of links in xbuild directories in favour of targets
+ files which include the canonical targets
+
+3.0.29
+
+ * Proper DESTDIR support (very useful for making custom deb/rpm packages)
+
+
diff --git a/FSharp.Compiler.Editor.nuspec b/FSharp.Compiler.Editor.nuspec
new file mode 100644
index 0000000000..a3e0c29495
--- /dev/null
+++ b/FSharp.Compiler.Editor.nuspec
@@ -0,0 +1,23 @@
+
+
+
+ FSharp.Compiler.Editor
+ 1.0.9
+ F# Compiler Editor
+ Dave Thomas, Anh-Dung Phan
+
+ http://opensource.org/licenses/Apache-2.0
+ https://github.com/fsharp/FSharp.Compiler.Service
+ false
+ The compiler editor assembly for creating refactoring and editing tools for F# programming language
+ This fork of the F# compiler contains minor modifications in visibility to allow refactoring, editing, and other tools to have access to the full F# AST and parser.
+ Reintegration with FSharp31 source
+ Copyright 2013
+ fsharp compiler editing refactoring
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Makefile.in b/Makefile.in
index be25c99dcb..36c5bdd20e 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,6 +1,6 @@
include $(topsrcdir)config.make
-all clean install do-proto do-final do-2-1 install-2-1 clean-2-0 clean-2-1 clean-4-0:
+all clean install build build-proto:
$(MAKE) -C src/fsharp $@
dist:
diff --git a/README.md b/README.md
index 8a40b2b6f8..5767da6e00 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,93 @@
+FSharp.Compiler.Service
+=======================
+
+Modified clone of F# compiler exposing additional functionality for editing clients and embedding F# as a service.
+
+## FSharp.Compiler.Editor
+
+At the moment, the main component is `FSharp.Compiler.Editor.dll`.
+It contains minor modifications in visibility to allow refactoring editing
+and other tools to have access to the full F# AST and parser. The main aim is to have a stable and
+documented fork of the main compiler that allows various tools to share this common code.
+
+This repo should be _identical_ to 'fsharp' except:
+
+ - Changes for building FSharp.Compiler.Editor.dll, notably
+ - Change the assembly name
+ - Only build FSharp.Compiler.Editor.dll
+ - No bootstrap or proto compiler is used - an installed F# compiler is assumed
+
+ - Files for publishing the nuget package for FSharp.Compiler.Editor
+
+ - Changes to compiler source code to expose new functionality
+
+ - Additions to compiler source code which improve the API for the use of F# editing clients
+
+ - Additions to compiler source code which add new functionality used by all F# editing clients
+
+ - These additions to this README.md
+
+ - Additions to the LICENCE file to record contributors, changes etc.
+
+If language or compiler addiitons are committed to fsharp/fsharp, they should be merged into this repo and a new nuget
+package released.
+
+###Nuget
+There is currently a [nuget package](https://nuget.org/packages/FSharp.Compiler.Editor/) that you can install as follows:
+
+Using the nuget package manager in windows:
+```
+PM> Install-Package FSharp.Compiler.Editor
+```
+Or from the nuget console on Osx etc:
+```
+nuget install FSharp.Compiler.Editor
+```
+
+###Building
+If you want to build this yourself then you can follow these instructions:
+
+```
+git clone https://github.com/fsharp/FSharp.Compiler.Editor
+cd FSharp.Compiler.Editor
+```
+
+Now follow the build instructions below.
+####Linux
+```
+./autogen.sh
+make
+```
+####Osx
+```
+./autogen.sh --prefix=/Library/Frameworks/Mono.framework/Versions/Current/
+make
+```
+
+###Windows
+
+```
+.\build.bat
+```
+
+The output will be located at `lib/release/4.0/FSharp.Compiler.Editor.dll`
+
+###Clients
+
+The known tools that use this component are:
+
+* [Fantomas](https://github.com/dungpa/fantomas)
+* [Fsharp-Refactor](https://github.com/Lewix/fsharp-refactor)
+* [FSharpbinding](https://github.com/fsharp/fsharpbinding)
+
+If you modify this component it is polite to check that these tools all build after your modifications.
+
+
+=============================================================================================
+Original README from F# Compiler begins below
+=============================================================================================
+
+
This is the F# compiler, core library and core tools (open source edition). It uses the Apache 2.0 license.
The `master` branch is for the latest version of F# (currently F# 3.0).
@@ -201,5 +291,4 @@ You can then go to the relevant directory and run `build.bat` and `run.bat`.
F# compiler sources dropped by Microsoft are available from [fsharppowerpack.codeplex.com](http://fsharppowerpack.codeplex.com).
-Uses bootstrapping libraries, tools and F# compiler. The `lib/bootstrap/X.0` directories contain mono-built libraries, compiler and tools that can be used to bootstrap a build. You can also supply your own via the `--with-bootstrap` option.
-
+Uses bootstrapping libraries, tools and F# compiler. The `lib/bootstrap/X.0` directories contain mono-built libraries, compiler and tools that can be used to bootstrap a build. You can also supply your own via the `--with-bootstrap` option.
\ No newline at end of file
diff --git a/build.bat b/build.bat
index 60fa42c64e..8ead95fec7 100644
--- a/build.bat
+++ b/build.bat
@@ -7,14 +7,11 @@ if %PROCESSOR_ARCHITECTURE%==x86 (
)
::Clean
-del /F /S /Q lib\proto
del /F /S /Q lib\release
::Build
pushd .
cd .\src
set ABS_PATH=%CD%
-%MSBUILD% %ABS_PATH%/fsharp-proto-build.proj
-%MSBUILD% %ABS_PATH%/fsharp-library-build.proj /p:TargetFramework=net40 /p:Configuration=Release
-%MSBUILD% %ABS_PATH%/fsharp-compiler-build.proj /p:TargetFramework=net40 /p:Configuration=Release
+%MSBUILD% "%ABS_PATH%\fsharp-compiler-build.proj" /p:TargetFramework=net40 /p:Configuration=Release
popd
diff --git a/config.make.in b/config.make.in
index 54498c6a3e..68c920d76e 100644
--- a/config.make.in
+++ b/config.make.in
@@ -9,7 +9,7 @@ monogacdir := @MONOGACDIR@
monogacdir20 := @MONOGACDIR20@
-#This is where to find MonoTouch of MonoAndroid, for "make do-2-1"
+#This is where to find MonoTouch of MonoAndroid, for "make build-monodroid"
#
#For now this is hardwired, it should be optionally detected by configure.ac
monogacdir21 := @abs_top_srcdir@/dependencies/mono/2.1
@@ -18,125 +18,48 @@ monogacdir35 := @MONOGACDIR35@
monogacdir40 := @MONOGACDIR40@
gacdir := ${libdir}mono
-gacdir20 := ${gacdir}/2.0
-gacdir40 := ${gacdir}/4.0
tooldir := $(topdir)lib/bootstrap/4.0/
+monoopts = @mono_gc_options@
MONO_OPTIONS += @mono_gc_options@
+TargetFramework = net40
CONFIG = release
+Configuration = Release
DISTVERSION = 201011
+outsuffix = $(TargetFramework)
+
+ifeq (x-$(TargetFramework),x-net20)
+VERSION = 2.3.1.0
+TARGET = 2.0
+endif
+
+ifeq (x-$(TargetFramework),x-net40)
+VERSION = 4.3.1.0
+TARGET = 4.0
+outsuffix = .
+endif
+
+ifeq (x-$(TargetFramework),x-monodroid)
+VERSION = 2.3.98.1
+TARGET = monodroid
+endif
+
+
+ifeq (x-$(TargetFramework),x-monotouch)
+VERSION = 2.3.99.1
+TARGET = monotouch
+endif
-VERSION_2_0 = 2.3.0.0
-VERSION_2_1 = 2.3.1.0
-VERSION_4_0 = 4.3.0.0
-TARGET_2_0 = 2.0
-TARGET_2_1 = 2.1
-TARGET_4_0 = 4.0
DELAY_SIGN_TOKEN = b03f5f7f11d50a3a
SIGN_TOKEN = f536804aa0eb945b
bootstrapdir = $(bootstrap)/4.0/
tmpdir = .libs/$(CONFIG)/
objdir = $(tmpdir)$(TARGET)/
-protodir = $(builddir)/lib/proto/4.0/
-outdir = $(builddir)lib/$(CONFIG)/$(TARGET)/
-
-FSSRGEN = $(tooldir)../2.0/fssrgen.exe
-FSLEX = $(tooldir)../2.0/fslex.exe
-FSYACC = $(tooldir)../2.0/fsyacc.exe
-
-
-FLAGS = \
- --doc:$(objdir)$(NAME).xml \
- --version:$(VERSION) \
- --debug:pdbonly \
- --optimize+ \
- --mlcompatibility \
- --noframework \
- --fullpaths \
- --times \
- --nowarn:9
-
-DELAY_SIGN_FLAGS = \
- --define:STRONG_NAME_AND_DELAY_SIGN_FSHARP_COMPILER_WITH_MSFT_KEY \
- --delaysign+ \
- --keyfile:$(topdir)msfinal.pub
-
-SIGN_FLAGS = \
- --define:STRONG_NAME_FSHARP_COMPILER_WITH_TEST_KEY \
- --keyfile:$(topdir)/src/fsharp/test.snk
-
-DEFINES_GENERAL = \
- --define:TRACE \
- --define:CROSS_PLATFORM_COMPILER
-
-ifeq ($(CONFIG),debug)
-DEFINES_DEBUG = \
- --define:CODE_ANALYSIS \
- --define:DEBUG
-else
-DEFINES_DEBUG =
-endif
-
-DEFINES_2_0 = \
- $(DEFINES_GENERAL) \
- $(DEFINES_DEBUG) \
- --define:FX_NO_STRUCTURAL_EQUALITY \
- --define:FX_NO_IOBSERVABLE \
- --define:FX_NO_TUPLE \
- --define:FX_ATLEAST_35 \
- --define:FX_NO_LAZY \
- --define:FX_NO_CANCELLATIONTOKEN_CLASSES \
- --define:FX_NO_MONITOR_REPORTS_LOCKTAKEN \
- --define:FX_NO_TPL_PARALLEL \
- --define:FX_NO_CUSTOMATTRIBUTEDATA \
- --define:FX_NO_TASK \
- --define:FX_NO_BIGINT
-
-DEFINES_2_1 = \
- $(DEFINES_GENERAL) \
- $(DEFINES_DEBUG) \
- --define:FX_NO_STRUCTURAL_EQUALITY \
- --define:FX_NO_CUSTOMATTRIBUTEDATA \
- --define:FX_NO_BIGINT_CULTURE_PARSE \
- --define:FX_ATLEAST_40 \
- --define:FX_ATLEAST_35 \
- --define:FX_ATLEAST_LINQ \
- --define:FX_NO_BIGINT
-
-DEFINES_4_0 = \
- $(DEFINES_GENERAL) \
- $(DEFINES_DEBUG) \
- --define:FX_NO_BIGINT_CULTURE_PARSE \
- --define:FX_ATLEAST_40 \
- --define:FX_ATLEAST_35 \
- --define:FX_ATLEAST_LINQ
-
-REFERENCES_2_0 = \
- -r:$(monogacdirXX)/Microsoft.Build.Engine.dll \
- -r:$(monogacdirXX)/Microsoft.Build.Framework.dll \
- -r:$(monogacdir35)/Microsoft.Build.Tasks.v3.5.dll \
- -r:$(monogacdir35)/Microsoft.Build.Utilities.v3.5.dll \
- -r:$(monogacdirXX)/mscorlib.dll \
- -r:$(monogacdirXX)/System.Core.dll \
- -r:$(monogacdirXX)/System.dll
-
-REFERENCES_2_1 = \
- -r:$(monogacdir21)/mscorlib.dll \
- -r:$(monogacdir21)/System.Core.dll \
- -r:$(monogacdir21)/System.dll
-
-REFERENCES_4_0 = \
- -r:$(monogacdirXX)/Microsoft.Build.Engine.dll \
- -r:$(monogacdirXX)/Microsoft.Build.Framework.dll \
- -r:$(monogacdirXX)/Microsoft.Build.Tasks.v4.0.dll \
- -r:$(monogacdirXX)/Microsoft.Build.Utilities.v4.0.dll \
- -r:$(monogacdirXX)/mscorlib.dll \
- -r:$(monogacdirXX)/System.Core.dll \
- -r:$(monogacdirXX)/System.dll \
- -r:$(monogacdirXX)/System.Numerics.dll
+protodir = $(builddir)/lib/proto
+outdir = $(builddir)lib/$(CONFIG)/$(outsuffix)/
INSTALL = $(SHELL) $(topdir)install-sh
INSTALL_DATA = $(INSTALL) -c -m 644
diff --git a/configure.ac b/configure.ac
index f74f7f80fa..e6d5da596f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -102,8 +102,9 @@ src/fsharp/FSharp.Data.TypeProviders/Makefile
src/fsharp/fsi/Makefile
src/fsharp/fsiAnyCpu/Makefile
src/fsharp/policy.2.0.FSharp.Core/Makefile
-src/fsharp/policy.4.0.FSharp.Core/Makefile
src/fsharp/policy.2.3.FSharp.Core/Makefile
+src/fsharp/policy.3.3.FSharp.Core/Makefile
+src/fsharp/policy.4.0.FSharp.Core/Makefile
src/fsharp/policy.4.3.FSharp.Core/Makefile
])
AC_OUTPUT
diff --git a/lib/bootstrap/2.0/FSharp.SRGen.targets b/lib/bootstrap/2.0/FSharp.SRGen.targets
index 81cae8a1e0..f80e70ef86 100755
--- a/lib/bootstrap/2.0/FSharp.SRGen.targets
+++ b/lib/bootstrap/2.0/FSharp.SRGen.targets
@@ -13,6 +13,10 @@ Copyright (C) Microsoft Corporation. Apache 2.0 License.
+
+ ProcessFsSrGen;$(PrepareForBuildDependsOn)
+
+
ProcessFsSrGen;$(BuildDependsOn)
diff --git a/lib/bootstrap/4.0/Microsoft.FSharp-proto.targets b/lib/bootstrap/4.0/Microsoft.FSharp-proto.targets
new file mode 100644
index 0000000000..34cd68ae10
--- /dev/null
+++ b/lib/bootstrap/4.0/Microsoft.FSharp-proto.targets
@@ -0,0 +1,194 @@
+
+
+
+
+
+
+
+
+
+
+ $(MSBuildExtensionsPath32)\FSharp\1.0\
+
+ $(FSharpTargetsDir)\Microsoft.FSharp-proto.targets
+ $(MSBuildAllProjects);$(FSharpTargetsFullPath)
+ .fs
+ F#
+ $(Optimize)
+
+ RootNamespace
+
+
+
+
+
+
+
+
+
+ <_Temporary Remove="@(_Temporary)" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_Temporary Remove="@(_Temporary)" />
+
+
+
+
+
+
+
+
+ <_DebugSymbolsIntermediatePathTemporary Include="$(PdbFile)"/>
+
+ <_DebugSymbolsIntermediatePath Include="@(_DebugSymbolsIntermediatePathTemporary->'%(RootDir)%(Directory)%(Filename).pdb')"/>
+
+
+
+ _ComputeNonExistentFileProperty
+
+
+
+
+
+
+
+
+
+
+
+
+ <_CoreCompileResourceInputs Remove="@(_CoreCompileResourceInputs)" />
+
+
+
+
+
+
+
+
diff --git a/lib/bootstrap/4.0/Microsoft.FSharp.targets b/lib/bootstrap/4.0/Microsoft.FSharp.targets
new file mode 100644
index 0000000000..32507166ed
--- /dev/null
+++ b/lib/bootstrap/4.0/Microsoft.FSharp.targets
@@ -0,0 +1,256 @@
+
+
+
+
+
+
+
+
+
+
+ true
+ true
+
+
+
+
+
+ $(MSBuildAllProjects);$(MSBuildThisFileFullPath)
+ .fs
+ F#
+ Managed
+ $(Optimize)
+ Software\Microsoft\Microsoft SDKs\$(TargetFrameworkIdentifier)
+
+ RootNamespace
+ false
+ $(Prefer32Bit)
+
+
+
+
+
+
+
+
+ false
+ true
+
+
+
+
+
+ <_Temporary Remove="@(_Temporary)" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_Temporary Remove="@(_Temporary)" />
+
+
+
+
+
+
+
+
+
+ <_DebugSymbolsIntermediatePathTemporary Include="$(PdbFile)"/>
+
+ <_DebugSymbolsIntermediatePath Include="@(_DebugSymbolsIntermediatePathTemporary->'%(RootDir)%(Directory)%(Filename).pdb')"/>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_CoreCompileResourceInputs Remove="@(_CoreCompileResourceInputs)" />
+
+
+
+
+
+
+
+
+
+
diff --git a/src/FSharpSource.targets b/src/FSharpSource.targets
index 3412b07702..04f8709a6d 100755
--- a/src/FSharpSource.targets
+++ b/src/FSharpSource.targets
@@ -8,8 +8,6 @@
truenet40
-
- 4.0$(FSharpSourcesRoot)\..\lib\bootstrap\4.0true$(OtherFlags) --times
@@ -19,15 +17,31 @@
- $(FSharpSourcesRoot)\source-build-version
- $(FSharpSourcesRoot)\source-build-version-2.3.0.0
- $(FSharpSourcesRoot)\source-build-version-4.3.0.0
- $(FSharpSourcesRoot)\source-build-version-2.3.5.0
- $(FSharpSourcesRoot)\source-build-version-2.3.5.0
-
+ 2.9.9.999
+
+ 4.3.1.0
+
+ 2.3.1.0
+ 2.3.5.1
+ 2.3.6.1
+ 2.3.98.1
+ 2.3.99.1
+ 3.3.1.0
+
+
+
+ 2.3.0.0
+ 4.3.0.0
+ 2.3.5.0
+ 2.3.6.0
+ 2.3.98.0
+ 2.3.99.0
+
+ $(OtherFlags) --version:$(AssemblyVersion)
+
@@ -78,6 +92,7 @@ Some other NuGET monikers to support in the future, see http://docs.nuget.org/do
trueDEBUG;NO_STRONG_NAMES;$(DefineConstants)
+ $(DefineConstants);FX_ATLEAST_45proto
@@ -90,7 +105,7 @@ Some other NuGET monikers to support in the future, see http://docs.nuget.org/do
v2.0
- 2.0
+ $(TargetFramework)$(DefineConstants);FX_NO_STRUCTURAL_EQUALITY$(DefineConstants);FX_NO_CANCELLATIONTOKEN_CLASSES$(DefineConstants);FX_NO_TASK
@@ -105,8 +120,13 @@ Some other NuGET monikers to support in the future, see http://docs.nuget.org/do
- v4.0
- 4.0
+ v4.0
+
+ .
+
+
+ $(TargetFramework)
+ $(DefineConstants);FX_ATLEAST_45$(DefineConstants);FX_ATLEAST_40$(DefineConstants);FX_ATLEAST_35$(DefineConstants);BE_SECURITY_TRANSPARENT
@@ -119,9 +139,9 @@ Some other NuGET monikers to support in the future, see http://docs.nuget.org/do
-
+ v2.1
- 2.1
+ $(TargetFramework)$(DefineConstants);FX_NO_STRUCTURAL_EQUALITY$(DefineConstants);FX_NO_CUSTOMATTRIBUTEDATA$(DefineConstants);FX_NO_BIGINT_CULTURE_PARSE
@@ -135,7 +155,7 @@ Some other NuGET monikers to support in the future, see http://docs.nuget.org/do
v2.1
- 2.1monotouch
+ $(TargetFramework)$(DefineConstants);FX_NO_STRUCTURAL_EQUALITY$(DefineConstants);FX_NO_CUSTOMATTRIBUTEDATA$(DefineConstants);FX_NO_BIGINT_CULTURE_PARSE
@@ -285,7 +305,7 @@ Some other NuGET monikers to support in the future, see http://docs.nuget.org/do
v3.0
- sl3
+ $(TargetFramework)$(DefineConstants);SILVERLIGHT$(DefineConstants);FX_NO_CANCELLATIONTOKEN_CLASSES$(DefineConstants);FX_NO_TASK
@@ -364,7 +384,7 @@ Some other NuGET monikers to support in the future, see http://docs.nuget.org/do
$(DefineConstants);FX_ATLEAST_LINQSilverlightv4.0
- sl4
+ $(TargetFramework)v4.0
@@ -561,7 +581,7 @@ Some other NuGET monikers to support in the future, see http://docs.nuget.org/do
v3.5
- 3.5
+ $(TargetFramework)CompactFramework$(DefineConstants);FX_ATLEAST_COMPACT_FRAMEWORK_35$(DefineConstants);FX_NO_CANCELLATIONTOKEN_CLASSES
@@ -653,6 +673,11 @@ Some other NuGET monikers to support in the future, see http://docs.nuget.org/do
false
+
+
+ fsharp30\$(TargetFrameworkOutputDirectory)
+
+
obj\$(ConfigurationOutputDirectory)\$(TargetFrameworkOutputDirectory)\
@@ -666,28 +691,51 @@ Some other NuGET monikers to support in the future, see http://docs.nuget.org/do
- $(FSharpSourcesRoot)\..\lib\proto\$(protoCLIDir)
+
+
$(FSharpSourcesRoot)\..\lib\$(ConfigurationOutputDirectory)\$(TargetFrameworkOutputDirectory)
-
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -712,17 +760,9 @@ Some other NuGET monikers to support in the future, see http://docs.nuget.org/do
Text="Configuration '$(Configuration)' is not one of the supported configurations: Debug, Release, Proto"
Condition="'$(Configuration)'!='Release' and '$(Configuration)'!='Debug' and '$(Configuration)'!='Proto'"/>
+ Text="Portable profile '$(TargetFramework)' is not yet supported"
+ Condition="'$(TargetFramework)' == 'portable-windows8+net45'"/>
+
diff --git a/src/absil/il.fs b/src/absil/il.fs
index 06a3ea9d6b..bc7e62e7c9 100755
--- a/src/absil/il.fs
+++ b/src/absil/il.fs
@@ -10,7 +10,7 @@
// You must not remove this notice, or any other, from this software.
//----------------------------------------------------------------------------
-module internal Microsoft.FSharp.Compiler.AbstractIL.IL
+module (*internal*) Microsoft.FSharp.Compiler.AbstractIL.IL
#nowarn "49"
#nowarn "343" // The type 'ILAssemblyRef' implements 'System.IComparable' explicitly but provides no corresponding override for 'Object.Equals'.
@@ -467,18 +467,29 @@ type ILAssemblyRef(data) =
assemRefLocale=locale; }
static member FromAssemblyName (aname:System.Reflection.AssemblyName) =
- let culture = None
- let locale = None
+ let locale = None
+ //match aname.CultureInfo with
+ // | null -> None
+ // | x -> Some x.Name
+ let publicKey =
+ match aname.GetPublicKey() with
+ | null | [| |] ->
+ match aname.GetPublicKeyToken() with
+ | null | [| |] -> None
+ | bytes -> Some (PublicKeyToken bytes)
+ | bytes ->
+ Some (PublicKey bytes)
+
let version =
- let v = aname.Version
- Some(uint16 v.Major,uint16 v.Minor,uint16 v.Build,uint16 v.Revision)
- let key =
- match aname.GetPublicKeyToken() with
- | null | [| |] -> None
- | bytes -> Some (PublicKeyToken bytes)
- let retargetable = (aname.Flags = System.Reflection.AssemblyNameFlags.Retargetable)
- ILAssemblyRef.Create(aname.Name,culture,key,retargetable,version,locale)
-
+ match aname.Version with
+ | null -> None
+ | v -> Some (uint16 v.Major,uint16 v.Minor,uint16 v.Build,uint16 v.Revision)
+
+ let retargetable = aname.Flags = System.Reflection.AssemblyNameFlags.Retargetable
+
+ ILAssemblyRef.Create(aname.Name,None,publicKey,retargetable,version,locale)
+
+
member aref.QualifiedName =
let b = new System.Text.StringBuilder(100)
@@ -554,7 +565,7 @@ type ILScopeRef =
| ILScopeRef.Assembly aref when aref.Name = "mscorlib" -> ""
| ILScopeRef.Assembly aref -> aref.QualifiedName
- member scoref.QualifiedNameWithNoShortMscorlib =
+ member scoref.QualifiedNameWithNoShortPrimaryAssembly =
match scoref with
| ILScopeRef.Local -> ""
| ILScopeRef.Module mref -> "module "+mref.Name
@@ -672,12 +683,12 @@ type ILTypeRef =
member tref.BasicQualifiedName =
String.concat "+" (tref.Enclosing @ [ tref.Name ])
- member tref.AddQualifiedNameExtensionWithNoShortMscorlib(basic) =
- let sco = tref.Scope.QualifiedNameWithNoShortMscorlib
+ member tref.AddQualifiedNameExtensionWithNoShortPrimaryAssembly(basic) =
+ let sco = tref.Scope.QualifiedNameWithNoShortPrimaryAssembly
if sco = "" then basic else String.concat ", " [basic;sco]
- member tref.QualifiedNameWithNoShortMscorlib =
- tref.AddQualifiedNameExtensionWithNoShortMscorlib(tref.BasicQualifiedName)
+ member tref.QualifiedNameWithNoShortPrimaryAssembly =
+ tref.AddQualifiedNameExtensionWithNoShortPrimaryAssembly(tref.BasicQualifiedName)
member tref.QualifiedName =
let basic = tref.BasicQualifiedName
@@ -706,10 +717,10 @@ and
if ILList.isEmpty x.GenericArgs then
tc
else
- tc + "[" + String.concat "," (x.GenericArgs |> ILList.map (fun arg -> "[" + arg.QualifiedNameWithNoShortMscorlib + "]")) + "]"
+ tc + "[" + String.concat "," (x.GenericArgs |> ILList.map (fun arg -> "[" + arg.QualifiedNameWithNoShortPrimaryAssembly + "]")) + "]"
- member x.AddQualifiedNameExtensionWithNoShortMscorlib(basic) =
- x.TypeRef.AddQualifiedNameExtensionWithNoShortMscorlib(basic)
+ member x.AddQualifiedNameExtensionWithNoShortPrimaryAssembly(basic) =
+ x.TypeRef.AddQualifiedNameExtensionWithNoShortPrimaryAssembly(basic)
member x.FullName=x.TypeRef.FullName
@@ -736,19 +747,19 @@ and []
| ILType.Byref _ty -> failwith "unexpected byref type"
| ILType.FunctionPointer _mref -> failwith "unexpected function pointer type"
- member x.AddQualifiedNameExtensionWithNoShortMscorlib(basic) =
+ member x.AddQualifiedNameExtensionWithNoShortPrimaryAssembly(basic) =
match x with
| ILType.TypeVar _n -> basic
- | ILType.Modified(_,_ty1,ty2) -> ty2.AddQualifiedNameExtensionWithNoShortMscorlib(basic)
- | ILType.Array (ILArrayShape(_s),ty) -> ty.AddQualifiedNameExtensionWithNoShortMscorlib(basic)
- | ILType.Value tr | ILType.Boxed tr -> tr.AddQualifiedNameExtensionWithNoShortMscorlib(basic)
+ | ILType.Modified(_,_ty1,ty2) -> ty2.AddQualifiedNameExtensionWithNoShortPrimaryAssembly(basic)
+ | ILType.Array (ILArrayShape(_s),ty) -> ty.AddQualifiedNameExtensionWithNoShortPrimaryAssembly(basic)
+ | ILType.Value tr | ILType.Boxed tr -> tr.AddQualifiedNameExtensionWithNoShortPrimaryAssembly(basic)
| ILType.Void -> failwith "void"
| ILType.Ptr _ty -> failwith "unexpected pointer type"
| ILType.Byref _ty -> failwith "unexpected byref type"
| ILType.FunctionPointer _mref -> failwith "unexpected function pointer type"
- member x.QualifiedNameWithNoShortMscorlib =
- x.AddQualifiedNameExtensionWithNoShortMscorlib(x.BasicQualifiedName)
+ member x.QualifiedNameWithNoShortPrimaryAssembly =
+ x.AddQualifiedNameExtensionWithNoShortPrimaryAssembly(x.BasicQualifiedName)
and
[]
@@ -2384,123 +2395,182 @@ let destILArrTy ty = match ty with ILType.Array(shape,ty) -> (shape,ty) | _ -> f
// Sigs of special types built-in
// --------------------------------------------------------------------
+[]
let tname_Object = "System.Object"
+[]
let tname_String = "System.String"
+[]
let tname_StringBuilder = "System.Text.StringBuilder"
+[]
let tname_AsyncCallback = "System.AsyncCallback"
+[]
let tname_IAsyncResult = "System.IAsyncResult"
+[]
let tname_IComparable = "System.IComparable"
+[]
let tname_Exception = "System.Exception"
+[]
let tname_Type = "System.Type"
+[]
let tname_Missing = "System.Reflection.Missing"
+[]
let tname_Activator = "System.Activator"
+[]
let tname_SerializationInfo = "System.Runtime.Serialization.SerializationInfo"
+[]
let tname_StreamingContext = "System.Runtime.Serialization.StreamingContext"
+[]
let tname_SecurityPermissionAttribute = "System.Security.Permissions.SecurityPermissionAttribute"
+[]
let tname_Delegate = "System.Delegate"
+[]
let tname_ValueType = "System.ValueType"
+[]
let tname_TypedReference = "System.TypedReference"
+[]
let tname_Enum = "System.Enum"
+[]
let tname_MulticastDelegate = "System.MulticastDelegate"
+[]
let tname_Array = "System.Array"
-
+[]
let tname_Int64 = "System.Int64"
+[]
let tname_UInt64 = "System.UInt64"
+[]
let tname_Int32 = "System.Int32"
+[]
let tname_UInt32 = "System.UInt32"
+[]
let tname_Int16 = "System.Int16"
+[]
let tname_UInt16 = "System.UInt16"
+[]
let tname_SByte = "System.SByte"
+[]
let tname_Byte = "System.Byte"
+[]
let tname_Single = "System.Single"
+[]
let tname_Double = "System.Double"
+[]
let tname_Bool = "System.Boolean"
+[]
let tname_Char = "System.Char"
+[]
let tname_IntPtr = "System.IntPtr"
+[]
let tname_UIntPtr = "System.UIntPtr"
+[]
let tname_RuntimeArgumentHandle = "System.RuntimeArgumentHandle"
+[]
let tname_RuntimeTypeHandle = "System.RuntimeTypeHandle"
+[]
let tname_RuntimeMethodHandle = "System.RuntimeMethodHandle"
+[]
let tname_RuntimeFieldHandle = "System.RuntimeFieldHandle"
+/// Represents the capabilities of target framework profile.
+/// Different profiles may omit some types or contain them in different assemblies
+type IPrimaryAssemblyTraits =
+
+ abstract TypedReferenceTypeScopeRef : ILScopeRef option
+ abstract RuntimeArgumentHandleTypeScopeRef : ILScopeRef option
+ abstract SerializationInfoTypeScopeRef : ILScopeRef option
+ abstract SecurityPermissionAttributeTypeScopeRef : ILScopeRef option
+ abstract IDispatchConstantAttributeScopeRef : ILScopeRef option
+ abstract IUnknownConstantAttributeScopeRef : ILScopeRef option
+ abstract ArgIteratorTypeScopeRef : ILScopeRef option
+ abstract MarshalByRefObjectScopeRef : ILScopeRef option
+ abstract ThreadStaticAttributeScopeRef : ILScopeRef option
+ abstract SpecialNameAttributeScopeRef : ILScopeRef option
+ abstract ContextStaticAttributeScopeRef : ILScopeRef option
+ abstract NonSerializedAttributeScopeRef : ILScopeRef option
+
+ abstract SystemRuntimeInteropServicesScopeRef : Lazy
+ abstract SystemLinqExpressionsScopeRef : Lazy
+ abstract SystemCollectionsScopeRef : Lazy
+ abstract SystemReflectionScopeRef : Lazy
+ abstract SystemDiagnosticsDebugScopeRef : Lazy
+ abstract ScopeRef : ILScopeRef
+
[]
type ILGlobals =
- { mscorlibScopeRef: ILScopeRef;
- mscorlibAssemblyName: string;
+ { traits : IPrimaryAssemblyTraits
+ primaryAssemblyName : string
noDebugData: bool;
- generateDebugBrowsableData: bool;
tref_Object: ILTypeRef
- ; tspec_Object: ILTypeSpec
- ; typ_Object: ILType
- ; tref_String: ILTypeRef
- ; typ_String: ILType
- ; typ_StringBuilder: ILType
- ; typ_AsyncCallback: ILType
- ; typ_IAsyncResult: ILType
- ; typ_IComparable: ILType
- ; tref_Type: ILTypeRef
- ; typ_Type: ILType
- ; typ_Missing: ILType
- ; typ_Activator: ILType
- ; typ_Delegate: ILType
- ; typ_ValueType: ILType
- ; typ_Enum: ILType
- ; tspec_TypedReference: ILTypeSpec
- ; typ_TypedReference: ILType
- ; typ_MulticastDelegate: ILType
- ; typ_Array: ILType
- ; tspec_Int64: ILTypeSpec
- ; tspec_UInt64: ILTypeSpec
- ; tspec_Int32: ILTypeSpec
- ; tspec_UInt32: ILTypeSpec
- ; tspec_Int16: ILTypeSpec
- ; tspec_UInt16: ILTypeSpec
- ; tspec_SByte: ILTypeSpec
- ; tspec_Byte: ILTypeSpec
- ; tspec_Single: ILTypeSpec
- ; tspec_Double: ILTypeSpec
- ; tspec_IntPtr: ILTypeSpec
- ; tspec_UIntPtr: ILTypeSpec
- ; tspec_Char: ILTypeSpec
- ; tspec_Bool: ILTypeSpec
- ; typ_int8: ILType
- ; typ_int16: ILType
- ; typ_int32: ILType
- ; typ_int64: ILType
- ; typ_uint8: ILType
- ; typ_uint16: ILType
- ; typ_uint32: ILType
- ; typ_uint64: ILType
- ; typ_float32: ILType
- ; typ_float64: ILType
- ; typ_bool: ILType
- ; typ_char: ILType
- ; typ_IntPtr: ILType
- ; typ_UIntPtr: ILType
- ; typ_RuntimeArgumentHandle: ILType
- ; typ_RuntimeTypeHandle: ILType
- ; typ_RuntimeMethodHandle: ILType
- ; typ_RuntimeFieldHandle: ILType
- ; typ_Byte: ILType
- ; typ_Int16: ILType
- ; typ_Int32: ILType
- ; typ_Int64: ILType
- ; typ_SByte: ILType
- ; typ_UInt16: ILType
- ; typ_UInt32: ILType
- ; typ_UInt64: ILType
- ; typ_Single: ILType
- ; typ_Double: ILType
- ; typ_Bool: ILType
- ; typ_Char: ILType
- ; typ_SerializationInfo: ILType
- ; typ_StreamingContext: ILType
- ; tref_SecurityPermissionAttribute: ILTypeRef
- ; tspec_Exception: ILTypeSpec
- ; typ_Exception: ILType
- ; mutable generatedAttribsCache: ILAttribute list
- ; mutable debuggerBrowsableNeverAttributeCache : ILAttribute option
- ; mutable debuggerTypeProxyAttributeCache : ILAttribute option }
+ tspec_Object: ILTypeSpec
+ typ_Object: ILType
+ tref_String: ILTypeRef
+ typ_String: ILType
+ typ_StringBuilder: ILType
+ typ_AsyncCallback: ILType
+ typ_IAsyncResult: ILType
+ typ_IComparable: ILType
+ tref_Type: ILTypeRef
+ typ_Type: ILType
+ typ_Missing: Lazy
+ typ_Activator: ILType
+ typ_Delegate: ILType
+ typ_ValueType: ILType
+ typ_Enum: ILType
+ tspec_TypedReference: ILTypeSpec option
+ typ_TypedReference: ILType option
+ typ_MulticastDelegate: ILType
+ typ_Array: ILType
+ tspec_Int64: ILTypeSpec
+ tspec_UInt64: ILTypeSpec
+ tspec_Int32: ILTypeSpec
+ tspec_UInt32: ILTypeSpec
+ tspec_Int16: ILTypeSpec
+ tspec_UInt16: ILTypeSpec
+ tspec_SByte: ILTypeSpec
+ tspec_Byte: ILTypeSpec
+ tspec_Single: ILTypeSpec
+ tspec_Double: ILTypeSpec
+ tspec_IntPtr: ILTypeSpec
+ tspec_UIntPtr: ILTypeSpec
+ tspec_Char: ILTypeSpec
+ tspec_Bool: ILTypeSpec
+ typ_int8: ILType
+ typ_int16: ILType
+ typ_int32: ILType
+ typ_int64: ILType
+ typ_uint8: ILType
+ typ_uint16: ILType
+ typ_uint32: ILType
+ typ_uint64: ILType
+ typ_float32: ILType
+ typ_float64: ILType
+ typ_bool: ILType
+ typ_char: ILType
+ typ_IntPtr: ILType
+ typ_UIntPtr: ILType
+ typ_RuntimeArgumentHandle: ILType option
+ typ_RuntimeTypeHandle: ILType
+ typ_RuntimeMethodHandle: ILType
+ typ_RuntimeFieldHandle: ILType
+ typ_Byte: ILType
+ typ_Int16: ILType
+ typ_Int32: ILType
+ typ_Int64: ILType
+ typ_SByte: ILType
+ typ_UInt16: ILType
+ typ_UInt32: ILType
+ typ_UInt64: ILType
+ typ_Single: ILType
+ typ_Double: ILType
+ typ_Bool: ILType
+ typ_Char: ILType
+ typ_SerializationInfo: ILType option
+ typ_StreamingContext: ILType
+ tref_SecurityPermissionAttribute: ILTypeRef option
+ tspec_Exception: ILTypeSpec
+ typ_Exception: ILType
+ mutable generatedAttribsCache: ILAttribute list
+ mutable debuggerBrowsableNeverAttributeCache : ILAttribute option
+ mutable debuggerTypeProxyAttributeCache : ILAttribute option }
override x.ToString() = ""
let mkNormalCall mspec = I_call (Normalcall, mspec, None)
@@ -2531,100 +2601,115 @@ let tname_CompilerGeneratedAttribute = "System.Runtime.CompilerServices.Compiler
let tname_DebuggableAttribute = "System.Diagnostics.DebuggableAttribute"
-let mkILGlobals mscorlibScopeRef mscorlibAssemblyNameOpt (noDebugData,generateDebugBrowsableData) =
- let mscorlibAssemblyName =
- match mscorlibAssemblyNameOpt with
- | Some name -> name
- | None -> (match mscorlibScopeRef with
- | ILScopeRef.Assembly assref -> assref.Name
- | _ -> failwith "mkILGlobals: mscorlib ILScopeRef is not an assembly ref")
- let tref_Object = mkILTyRef (mscorlibScopeRef,tname_Object)
+let mkILGlobals (traits : IPrimaryAssemblyTraits) primaryAssemblyNameOpt noDebugData =
+ let primaryAssemblyName =
+ match primaryAssemblyNameOpt with
+ | Some name -> name
+ | None ->
+ match traits.ScopeRef with
+ | ILScopeRef.Assembly assembly -> assembly.Name
+ | _ -> failwith "mkILGlobals: system runtime ILScopeRef is not an assembly ref"
+ let systemRuntimeScopeRef = traits.ScopeRef
+ let tref_Object = mkILTyRef (systemRuntimeScopeRef, tname_Object)
let tspec_Object = mkILNonGenericTySpec tref_Object
let typ_Object = mkILBoxedType tspec_Object
- let tref_String = mkILTyRef (mscorlibScopeRef,tname_String)
+ let tref_String = mkILTyRef (systemRuntimeScopeRef, tname_String)
let tspec_String = mkILNonGenericTySpec tref_String
let typ_String = mkILBoxedType tspec_String
- let tref_StringBuilder = mkILTyRef (mscorlibScopeRef,tname_StringBuilder)
+ let tref_StringBuilder = mkILTyRef (systemRuntimeScopeRef, tname_StringBuilder)
let tspec_StringBuilder = mkILNonGenericTySpec tref_StringBuilder
let typ_StringBuilder = mkILBoxedType tspec_StringBuilder
- let tref_AsyncCallback = mkILTyRef (mscorlibScopeRef,tname_AsyncCallback)
+ let tref_AsyncCallback = mkILTyRef (systemRuntimeScopeRef, tname_AsyncCallback)
let tspec_AsyncCallback = mkILNonGenericTySpec tref_AsyncCallback
let typ_AsyncCallback = mkILBoxedType tspec_AsyncCallback
- let tref_IAsyncResult = mkILTyRef (mscorlibScopeRef,tname_IAsyncResult)
+ let tref_IAsyncResult = mkILTyRef (systemRuntimeScopeRef,tname_IAsyncResult)
let tspec_IAsyncResult = mkILNonGenericTySpec tref_IAsyncResult
let typ_IAsyncResult = mkILBoxedType tspec_IAsyncResult
- let tref_IComparable = mkILTyRef (mscorlibScopeRef,tname_IComparable)
+ let tref_IComparable = mkILTyRef (systemRuntimeScopeRef,tname_IComparable)
let tspec_IComparable = mkILNonGenericTySpec tref_IComparable
let typ_IComparable = mkILBoxedType tspec_IComparable
- let tref_Exception = mkILTyRef (mscorlibScopeRef,tname_Exception)
+ let tref_Exception = mkILTyRef (systemRuntimeScopeRef,tname_Exception)
let tspec_Exception = mkILNonGenericTySpec tref_Exception
let typ_Exception = mkILBoxedType tspec_Exception
- let tref_Type = mkILTyRef(mscorlibScopeRef,tname_Type)
+ let tref_Type = mkILTyRef(systemRuntimeScopeRef,tname_Type)
let tspec_Type = mkILNonGenericTySpec tref_Type
let typ_Type = mkILBoxedType tspec_Type
- let tref_Missing = mkILTyRef(mscorlibScopeRef,tname_Missing)
- let tspec_Missing = mkILNonGenericTySpec tref_Missing
- let typ_Missing = mkILBoxedType tspec_Missing
-
+ let typ_Missing =
+ lazy(
+ let tref_Missing = mkILTyRef(traits.SystemReflectionScopeRef.Value ,tname_Missing)
+ let tspec_Missing = mkILNonGenericTySpec tref_Missing
+ mkILBoxedType tspec_Missing
+ )
- let tref_Activator = mkILTyRef(mscorlibScopeRef,tname_Activator)
+ let tref_Activator = mkILTyRef(systemRuntimeScopeRef,tname_Activator)
let tspec_Activator = mkILNonGenericTySpec tref_Activator
let typ_Activator = mkILBoxedType tspec_Activator
- let tref_SerializationInfo = mkILTyRef(mscorlibScopeRef,tname_SerializationInfo)
- let tspec_SerializationInfo = mkILNonGenericTySpec tref_SerializationInfo
- let typ_SerializationInfo = mkILBoxedType tspec_SerializationInfo
+ let typ_SerializationInfo =
+ match traits.SerializationInfoTypeScopeRef with
+ | Some scopeRef ->
+ let tref_SerializationInfo = mkILTyRef(scopeRef,tname_SerializationInfo)
+ let tspec_SerializationInfo = mkILNonGenericTySpec tref_SerializationInfo
+ Some (mkILBoxedType tspec_SerializationInfo)
+ | None -> None
- let tref_StreamingContext = mkILTyRef(mscorlibScopeRef,tname_StreamingContext)
+ let tref_StreamingContext = mkILTyRef(systemRuntimeScopeRef,tname_StreamingContext)
let tspec_StreamingContext = mkILNonGenericTySpec tref_StreamingContext
let typ_StreamingContext = ILType.Value tspec_StreamingContext
- let tref_SecurityPermissionAttribute = mkILTyRef(mscorlibScopeRef,tname_SecurityPermissionAttribute)
+ let tref_SecurityPermissionAttribute =
+ match traits.SecurityPermissionAttributeTypeScopeRef with
+ | Some scopeRef -> Some (mkILTyRef(scopeRef,tname_SecurityPermissionAttribute))
+ | None -> None
- let tref_Delegate = mkILTyRef(mscorlibScopeRef,tname_Delegate)
+ let tref_Delegate = mkILTyRef(systemRuntimeScopeRef,tname_Delegate)
let tspec_Delegate = mkILNonGenericTySpec tref_Delegate
let typ_Delegate = mkILBoxedType tspec_Delegate
- let tref_ValueType = mkILTyRef (mscorlibScopeRef,tname_ValueType)
+ let tref_ValueType = mkILTyRef (systemRuntimeScopeRef,tname_ValueType)
let tspec_ValueType = mkILNonGenericTySpec tref_ValueType
let typ_ValueType = mkILBoxedType tspec_ValueType
-
- let tref_TypedReference = mkILTyRef (mscorlibScopeRef,tname_TypedReference)
- let tspec_TypedReference = mkILNonGenericTySpec tref_TypedReference
- let typ_TypedReference = ILType.Value tspec_TypedReference
-
- let tref_Enum = mkILTyRef (mscorlibScopeRef,tname_Enum)
+
+ let tspec_TypedReference, typ_TypedReference =
+ match traits.TypedReferenceTypeScopeRef with
+ | Some scopeRef ->
+ let tref_TypedReference = mkILTyRef (scopeRef,tname_TypedReference)
+ let tspec_TypedReference = mkILNonGenericTySpec tref_TypedReference
+ Some tspec_TypedReference, Some(ILType.Value tspec_TypedReference)
+ | None -> None, None
+
+ let tref_Enum = mkILTyRef (systemRuntimeScopeRef,tname_Enum)
let tspec_Enum = mkILNonGenericTySpec tref_Enum
let typ_Enum = mkILBoxedType tspec_Enum
- let tref_MulticastDelegate = mkILTyRef (mscorlibScopeRef,tname_MulticastDelegate)
+ let tref_MulticastDelegate = mkILTyRef (systemRuntimeScopeRef,tname_MulticastDelegate)
let tspec_MulticastDelegate = mkILNonGenericTySpec tref_MulticastDelegate
let typ_MulticastDelegate = mkILBoxedType tspec_MulticastDelegate
- let typ_Array = mkILBoxedType (mkILNonGenericTySpec (mkILTyRef (mscorlibScopeRef,tname_Array)))
-
- let tref_Int64 = mkILTyRef (mscorlibScopeRef,tname_Int64)
- let tref_UInt64 = mkILTyRef (mscorlibScopeRef,tname_UInt64)
- let tref_Int32 = mkILTyRef (mscorlibScopeRef,tname_Int32)
- let tref_UInt32 = mkILTyRef (mscorlibScopeRef,tname_UInt32)
- let tref_Int16 = mkILTyRef (mscorlibScopeRef,tname_Int16)
- let tref_UInt16 = mkILTyRef (mscorlibScopeRef,tname_UInt16)
- let tref_SByte = mkILTyRef (mscorlibScopeRef,tname_SByte)
- let tref_Byte = mkILTyRef (mscorlibScopeRef,tname_Byte)
- let tref_Single = mkILTyRef (mscorlibScopeRef,tname_Single)
- let tref_Double = mkILTyRef (mscorlibScopeRef,tname_Double)
- let tref_Bool = mkILTyRef (mscorlibScopeRef,tname_Bool)
- let tref_Char = mkILTyRef (mscorlibScopeRef,tname_Char)
- let tref_IntPtr = mkILTyRef (mscorlibScopeRef,tname_IntPtr)
- let tref_UIntPtr = mkILTyRef (mscorlibScopeRef,tname_UIntPtr)
+ let typ_Array = mkILBoxedType (mkILNonGenericTySpec (mkILTyRef (systemRuntimeScopeRef,tname_Array)))
+
+ let tref_Int64 = mkILTyRef (systemRuntimeScopeRef,tname_Int64)
+ let tref_UInt64 = mkILTyRef (systemRuntimeScopeRef,tname_UInt64)
+ let tref_Int32 = mkILTyRef (systemRuntimeScopeRef,tname_Int32)
+ let tref_UInt32 = mkILTyRef (systemRuntimeScopeRef,tname_UInt32)
+ let tref_Int16 = mkILTyRef (systemRuntimeScopeRef,tname_Int16)
+ let tref_UInt16 = mkILTyRef (systemRuntimeScopeRef,tname_UInt16)
+ let tref_SByte = mkILTyRef (systemRuntimeScopeRef,tname_SByte)
+ let tref_Byte = mkILTyRef (systemRuntimeScopeRef,tname_Byte)
+ let tref_Single = mkILTyRef (systemRuntimeScopeRef,tname_Single)
+ let tref_Double = mkILTyRef (systemRuntimeScopeRef,tname_Double)
+ let tref_Bool = mkILTyRef (systemRuntimeScopeRef,tname_Bool)
+ let tref_Char = mkILTyRef (systemRuntimeScopeRef,tname_Char)
+ let tref_IntPtr = mkILTyRef (systemRuntimeScopeRef,tname_IntPtr)
+ let tref_UIntPtr = mkILTyRef (systemRuntimeScopeRef,tname_UIntPtr)
let tspec_Int64 = mkILNonGenericTySpec tref_Int64
let tspec_UInt64 = mkILNonGenericTySpec tref_UInt64
@@ -2669,128 +2754,126 @@ let mkILGlobals mscorlibScopeRef mscorlibAssemblyNameOpt (noDebugData,generateDe
let typ_Bool = ILType.Value tspec_Bool
let typ_Char = ILType.Value tspec_Char
- let tref_RuntimeArgumentHandle = mkILTyRef (mscorlibScopeRef,tname_RuntimeArgumentHandle)
- let tspec_RuntimeArgumentHandle = mkILNonGenericTySpec tref_RuntimeArgumentHandle
- let typ_RuntimeArgumentHandle = ILType.Value tspec_RuntimeArgumentHandle
- let tref_RuntimeTypeHandle = mkILTyRef (mscorlibScopeRef,tname_RuntimeTypeHandle)
+ let tref_RuntimeArgumentHandle =
+ match traits.RuntimeArgumentHandleTypeScopeRef with
+ | Some scopeRef -> Some(mkILTyRef (scopeRef,tname_RuntimeArgumentHandle))
+ | None -> None
+ let tspec_RuntimeArgumentHandle = Option.map mkILNonGenericTySpec tref_RuntimeArgumentHandle
+ let typ_RuntimeArgumentHandle = Option.map ILType.Value tspec_RuntimeArgumentHandle
+ let tref_RuntimeTypeHandle = mkILTyRef (systemRuntimeScopeRef,tname_RuntimeTypeHandle)
let tspec_RuntimeTypeHandle = mkILNonGenericTySpec tref_RuntimeTypeHandle
let typ_RuntimeTypeHandle = ILType.Value tspec_RuntimeTypeHandle
- let tref_RuntimeMethodHandle = mkILTyRef (mscorlibScopeRef,tname_RuntimeMethodHandle)
+ let tref_RuntimeMethodHandle = mkILTyRef (systemRuntimeScopeRef,tname_RuntimeMethodHandle)
let tspec_RuntimeMethodHandle = mkILNonGenericTySpec tref_RuntimeMethodHandle
let typ_RuntimeMethodHandle = ILType.Value tspec_RuntimeMethodHandle
- let tref_RuntimeFieldHandle = mkILTyRef (mscorlibScopeRef,tname_RuntimeFieldHandle)
+ let tref_RuntimeFieldHandle = mkILTyRef (systemRuntimeScopeRef,tname_RuntimeFieldHandle)
let tspec_RuntimeFieldHandle = mkILNonGenericTySpec tref_RuntimeFieldHandle
let typ_RuntimeFieldHandle = ILType.Value tspec_RuntimeFieldHandle
- { mscorlibScopeRef =mscorlibScopeRef
- ; mscorlibAssemblyName =mscorlibAssemblyName
- ; noDebugData =noDebugData
- ; generateDebugBrowsableData =generateDebugBrowsableData
- ; tref_Object =tref_Object
- ; tspec_Object =tspec_Object
- ; typ_Object =typ_Object
- ; tref_String =tref_String
- ; typ_String =typ_String
- ; typ_StringBuilder =typ_StringBuilder
- ; typ_AsyncCallback =typ_AsyncCallback
- ; typ_IAsyncResult =typ_IAsyncResult
- ; typ_IComparable =typ_IComparable
- ; typ_Activator =typ_Activator
- ; tref_Type =tref_Type
- ; typ_Type =typ_Type
- ; typ_Missing =typ_Missing
- ; typ_Delegate =typ_Delegate
- ; typ_ValueType =typ_ValueType
- ; typ_Enum =typ_Enum
- ; tspec_TypedReference =tspec_TypedReference
- ; typ_TypedReference =typ_TypedReference
- ; typ_MulticastDelegate =typ_MulticastDelegate
- ; typ_Array =typ_Array
- ; tspec_Int64 =tspec_Int64
- ; tspec_UInt64 =tspec_UInt64
- ; tspec_Int32 =tspec_Int32
- ; tspec_UInt32 =tspec_UInt32
- ; tspec_Int16 =tspec_Int16
- ; tspec_UInt16 =tspec_UInt16
- ; tspec_SByte =tspec_SByte
- ; tspec_Byte =tspec_Byte
- ; tspec_Single =tspec_Single
- ; tspec_Double =tspec_Double
- ; tspec_IntPtr =tspec_IntPtr
- ; tspec_UIntPtr =tspec_UIntPtr
- ; tspec_Char =tspec_Char
- ; tspec_Bool =tspec_Bool
- ; typ_int8 =typ_int8
- ; typ_int16 =typ_int16
- ; typ_int32 =typ_int32
- ; typ_int64 =typ_int64
- ; typ_uint8 =typ_uint8
- ; typ_uint16 =typ_uint16
- ; typ_uint32 =typ_uint32
- ; typ_uint64 =typ_uint64
- ; typ_float32 =typ_float32
- ; typ_float64 =typ_float64
- ; typ_bool =typ_bool
- ; typ_char =typ_char
- ; typ_IntPtr =typ_IntPtr
- ; typ_UIntPtr =typ_UIntPtr
- ; typ_RuntimeArgumentHandle =typ_RuntimeArgumentHandle
- ; typ_RuntimeTypeHandle =typ_RuntimeTypeHandle
- ; typ_RuntimeMethodHandle =typ_RuntimeMethodHandle
- ; typ_RuntimeFieldHandle =typ_RuntimeFieldHandle
+ { traits = traits
+ primaryAssemblyName = primaryAssemblyName
+ noDebugData = noDebugData
+ tref_Object = tref_Object
+ tspec_Object = tspec_Object
+ typ_Object = typ_Object
+ tref_String = tref_String
+ typ_String = typ_String
+ typ_StringBuilder = typ_StringBuilder
+ typ_AsyncCallback = typ_AsyncCallback
+ typ_IAsyncResult = typ_IAsyncResult
+ typ_IComparable = typ_IComparable
+ typ_Activator = typ_Activator
+ tref_Type = tref_Type
+ typ_Type = typ_Type
+ typ_Missing = typ_Missing
+ typ_Delegate = typ_Delegate
+ typ_ValueType = typ_ValueType
+ typ_Enum = typ_Enum
+ tspec_TypedReference = tspec_TypedReference
+ typ_TypedReference = typ_TypedReference
+ typ_MulticastDelegate = typ_MulticastDelegate
+ typ_Array = typ_Array
+ tspec_Int64 = tspec_Int64
+ tspec_UInt64 = tspec_UInt64
+ tspec_Int32 = tspec_Int32
+ tspec_UInt32 = tspec_UInt32
+ tspec_Int16 = tspec_Int16
+ tspec_UInt16 = tspec_UInt16
+ tspec_SByte = tspec_SByte
+ tspec_Byte = tspec_Byte
+ tspec_Single = tspec_Single
+ tspec_Double = tspec_Double
+ tspec_IntPtr = tspec_IntPtr
+ tspec_UIntPtr = tspec_UIntPtr
+ tspec_Char = tspec_Char
+ tspec_Bool = tspec_Bool
+ typ_int8 = typ_int8
+ typ_int16 = typ_int16
+ typ_int32 = typ_int32
+ typ_int64 = typ_int64
+ typ_uint8 = typ_uint8
+ typ_uint16 = typ_uint16
+ typ_uint32 = typ_uint32
+ typ_uint64 = typ_uint64
+ typ_float32 = typ_float32
+ typ_float64 = typ_float64
+ typ_bool = typ_bool
+ typ_char = typ_char
+ typ_IntPtr = typ_IntPtr
+ typ_UIntPtr =typ_UIntPtr
+ typ_RuntimeArgumentHandle = typ_RuntimeArgumentHandle
+ typ_RuntimeTypeHandle = typ_RuntimeTypeHandle
+ typ_RuntimeMethodHandle = typ_RuntimeMethodHandle
+ typ_RuntimeFieldHandle = typ_RuntimeFieldHandle
- ; typ_Byte =typ_Byte
- ; typ_Int16 =typ_Int16
- ; typ_Int32 =typ_Int32
- ; typ_Int64 =typ_Int64
- ; typ_SByte =typ_SByte
- ; typ_UInt16 =typ_UInt16
- ; typ_UInt32 =typ_UInt32
- ; typ_UInt64 =typ_UInt64
- ; typ_Single =typ_Single
- ; typ_Double =typ_Double
- ; typ_Bool =typ_Bool
- ; typ_Char =typ_Char
- ; typ_SerializationInfo=typ_SerializationInfo
- ; typ_StreamingContext=typ_StreamingContext
- ; tref_SecurityPermissionAttribute=tref_SecurityPermissionAttribute
- ; tspec_Exception =tspec_Exception
- ; typ_Exception =typ_Exception
- ; generatedAttribsCache = []
- ; debuggerBrowsableNeverAttributeCache = None
- ; debuggerTypeProxyAttributeCache = None }
+ typ_Byte = typ_Byte
+ typ_Int16 = typ_Int16
+ typ_Int32 = typ_Int32
+ typ_Int64 = typ_Int64
+ typ_SByte = typ_SByte
+ typ_UInt16 = typ_UInt16
+ typ_UInt32 = typ_UInt32
+ typ_UInt64 = typ_UInt64
+ typ_Single = typ_Single
+ typ_Double = typ_Double
+ typ_Bool = typ_Bool
+ typ_Char = typ_Char
+ typ_SerializationInfo = typ_SerializationInfo
+ typ_StreamingContext = typ_StreamingContext
+ tref_SecurityPermissionAttribute = tref_SecurityPermissionAttribute
+ tspec_Exception = tspec_Exception
+ typ_Exception = typ_Exception
+ generatedAttribsCache = []
+ debuggerBrowsableNeverAttributeCache = None
+ debuggerTypeProxyAttributeCache = None }
(* NOTE: ecma_ prefix refers to the standard "mscorlib" *)
let ecmaPublicKey = PublicKeyToken (Bytes.ofInt32Array [|0xde; 0xad; 0xbe; 0xef; 0xca; 0xfe; 0xfa; 0xce |])
-
-let ecmaMscorlibScopeRef = ILScopeRef.Assembly (ILAssemblyRef.Create("mscorlib", None, Some ecmaPublicKey, true, None, None))
-
-let ecmaILGlobals = mkILGlobals ecmaMscorlibScopeRef None (false, true)
let mkInitializeArrayMethSpec ilg =
- mkILNonGenericStaticMethSpecInTy(mkILNonGenericBoxedTy(mkILTyRef(ilg.mscorlibScopeRef,"System.Runtime.CompilerServices.RuntimeHelpers")),"InitializeArray", [ilg.typ_Array;ilg.typ_RuntimeFieldHandle], ILType.Void)
-(* e.ilg. [mkMscorlibExnNewobj "System.InvalidCastException"] *)
-let mkMscorlibExnNewobj ilg eclass =
- mkNormalNewobj (mkILNonGenericCtorMethSpec (mkILTyRef(ilg.mscorlibScopeRef,eclass),[]))
+ mkILNonGenericStaticMethSpecInTy(mkILNonGenericBoxedTy(mkILTyRef(ilg.traits.ScopeRef,"System.Runtime.CompilerServices.RuntimeHelpers")),"InitializeArray", [ilg.typ_Array;ilg.typ_RuntimeFieldHandle], ILType.Void)
+(* e.ilg. [mkPrimaryAssemblyExnNewobj "System.InvalidCastException"] *)
+let mkPrimaryAssemblyExnNewobj ilg eclass =
+ mkNormalNewobj (mkILNonGenericCtorMethSpec (mkILTyRef(ilg.traits.ScopeRef,eclass),[]))
let typ_is_boxed = function ILType.Boxed _ -> true | _ -> false
let typ_is_value = function ILType.Value _ -> true | _ -> false
-let tspec_is_mscorlib ilg (tspec:ILTypeSpec) n =
+let tspec_is_primaryAssembly ilg (tspec:ILTypeSpec) n =
let tref = tspec.TypeRef
let scoref = tref.Scope
(tref.Name = n) &&
match scoref with
- | ILScopeRef.Assembly n -> n.Name = ilg.mscorlibAssemblyName
+ | ILScopeRef.Assembly n -> n.Name = ilg.primaryAssemblyName
| ILScopeRef.Module _ -> false
| ILScopeRef.Local -> true
let typ_is_boxed_mscorlib_typ ilg (ty:ILType) n =
- typ_is_boxed ty && tspec_is_mscorlib ilg ty.TypeSpec n
+ typ_is_boxed ty && tspec_is_primaryAssembly ilg ty.TypeSpec n
let typ_is_value_mscorlib_typ ilg (ty:ILType) n =
- typ_is_value ty && tspec_is_mscorlib ilg ty.TypeSpec n
+ typ_is_value ty && tspec_is_primaryAssembly ilg ty.TypeSpec n
let isILObjectTy ilg ty = typ_is_boxed_mscorlib_typ ilg ty tname_Object
let isILStringTy ilg ty = typ_is_boxed_mscorlib_typ ilg ty tname_String
@@ -4211,22 +4294,22 @@ let encodeCustomAttrString s =
let rec encodeCustomAttrElemType x =
match x with
- | ILType.Value tspec when tspec.Name = "System.SByte" -> [| et_I1 |]
- | ILType.Value tspec when tspec.Name = "System.Byte" -> [| et_U1 |]
- | ILType.Value tspec when tspec.Name = "System.Int16" -> [| et_I2 |]
- | ILType.Value tspec when tspec.Name = "System.UInt16" -> [| et_U2 |]
- | ILType.Value tspec when tspec.Name = "System.Int32" -> [| et_I4 |]
- | ILType.Value tspec when tspec.Name = "System.UInt32" -> [| et_U4 |]
- | ILType.Value tspec when tspec.Name = "System.Int64" -> [| et_I8 |]
- | ILType.Value tspec when tspec.Name = "System.UInt64" -> [| et_U8 |]
- | ILType.Value tspec when tspec.Name = "System.Double" -> [| et_R8 |]
- | ILType.Value tspec when tspec.Name = "System.Single" -> [| et_R4 |]
- | ILType.Value tspec when tspec.Name = "System.Char" -> [| et_CHAR |]
- | ILType.Value tspec when tspec.Name = "System.Boolean" -> [| et_BOOLEAN |]
- | ILType.Boxed tspec when tspec.Name = "System.String" -> [| et_STRING |]
- | ILType.Boxed tspec when tspec.Name = "System.Object" -> [| 0x51uy |]
- | ILType.Boxed tspec when tspec.Name = "System.Type" -> [| 0x50uy |]
- | ILType.Value tspec -> Array.append [| 0x55uy |] (encodeCustomAttrString tspec.TypeRef.QualifiedNameWithNoShortMscorlib)
+ | ILType.Value tspec when tspec.Name = tname_SByte -> [| et_I1 |]
+ | ILType.Value tspec when tspec.Name = tname_Byte -> [| et_U1 |]
+ | ILType.Value tspec when tspec.Name = tname_Int16 -> [| et_I2 |]
+ | ILType.Value tspec when tspec.Name = tname_UInt16 -> [| et_U2 |]
+ | ILType.Value tspec when tspec.Name = tname_Int32 -> [| et_I4 |]
+ | ILType.Value tspec when tspec.Name = tname_UInt32 -> [| et_U4 |]
+ | ILType.Value tspec when tspec.Name = tname_Int64 -> [| et_I8 |]
+ | ILType.Value tspec when tspec.Name = tname_UInt64 -> [| et_U8 |]
+ | ILType.Value tspec when tspec.Name = tname_Double -> [| et_R8 |]
+ | ILType.Value tspec when tspec.Name = tname_Single -> [| et_R4 |]
+ | ILType.Value tspec when tspec.Name = tname_Char -> [| et_CHAR |]
+ | ILType.Value tspec when tspec.Name = tname_Bool -> [| et_BOOLEAN |]
+ | ILType.Boxed tspec when tspec.Name = tname_String -> [| et_STRING |]
+ | ILType.Boxed tspec when tspec.Name = tname_Object -> [| 0x51uy |]
+ | ILType.Boxed tspec when tspec.Name = tname_Type -> [| 0x50uy |]
+ | ILType.Value tspec -> Array.append [| 0x55uy |] (encodeCustomAttrString tspec.TypeRef.QualifiedNameWithNoShortPrimaryAssembly)
| ILType.Array (shape, elemType) when shape = ILArrayShape.SingleDimensional ->
Array.append [| et_SZARRAY |] (encodeCustomAttrElemType elemType)
| _ -> failwith "encodeCustomAttrElemType: unrecognized custom element type"
@@ -4297,14 +4380,14 @@ let rec encodeCustomAttrPrimValue ilg c =
| ILAttribElem.UInt64 x -> u64AsBytes x
| ILAttribElem.Single x -> ieee32AsBytes x
| ILAttribElem.Double x -> ieee64AsBytes x
- | ILAttribElem.Type (Some ty) -> encodeCustomAttrString ty.QualifiedNameWithNoShortMscorlib
- | ILAttribElem.TypeRef (Some tref) -> encodeCustomAttrString tref.QualifiedNameWithNoShortMscorlib
+ | ILAttribElem.Type (Some ty) -> encodeCustomAttrString ty.QualifiedNameWithNoShortPrimaryAssembly
+ | ILAttribElem.TypeRef (Some tref) -> encodeCustomAttrString tref.QualifiedNameWithNoShortPrimaryAssembly
| ILAttribElem.Array (_,elems) ->
[| yield! i32AsBytes elems.Length; for elem in elems do yield! encodeCustomAttrPrimValue ilg elem |]
and encodeCustomAttrValue ilg ty c =
match ty, c with
- | ILType.Boxed tspec, _ when tspec.Name = "System.Object" ->
+ | ILType.Boxed tspec, _ when tspec.Name = tname_Object ->
[| yield! encodeCustomAttrElemTypeForObject c; yield! encodeCustomAttrPrimValue ilg c |]
| ILType.Array (shape, elemType), ILAttribElem.Array (_,elems) when shape = ILArrayShape.SingleDimensional ->
[| yield! i32AsBytes elems.Length; for elem in elems do yield! encodeCustomAttrValue ilg elemType elem |]
@@ -4336,49 +4419,94 @@ let mkILCustomAttribMethRef (ilg: ILGlobals) (mspec:ILMethodSpec, fixedArgs: lis
let mkILCustomAttribute ilg (tref,argtys,argvs,propvs) =
mkILCustomAttribMethRef ilg (mkILNonGenericCtorMethSpec (tref,argtys),argvs,propvs)
+let MscorlibScopeRef = ILScopeRef.Assembly (ILAssemblyRef.Create("mscorlib", None, Some ecmaPublicKey, true, None, None))
+let mkMscorlibBasedTraits mscorlibRef =
+ let ecmaMscorlibScopeRef = Some mscorlibRef
+ let lazyRef = lazy mscorlibRef
+ {
+ new IPrimaryAssemblyTraits with
+ member this.ScopeRef = mscorlibRef
+ member this.SystemReflectionScopeRef = lazyRef
+ member this.TypedReferenceTypeScopeRef = ecmaMscorlibScopeRef
+ member this.RuntimeArgumentHandleTypeScopeRef = ecmaMscorlibScopeRef
+ member this.SerializationInfoTypeScopeRef = ecmaMscorlibScopeRef
+ member this.SecurityPermissionAttributeTypeScopeRef = ecmaMscorlibScopeRef
+ member this.SystemDiagnosticsDebugScopeRef = lazyRef
+ member this.SystemRuntimeInteropServicesScopeRef = lazyRef
+ member this.IDispatchConstantAttributeScopeRef = ecmaMscorlibScopeRef
+ member this.IUnknownConstantAttributeScopeRef = ecmaMscorlibScopeRef
+ member this.ContextStaticAttributeScopeRef = ecmaMscorlibScopeRef
+ member this.ThreadStaticAttributeScopeRef = ecmaMscorlibScopeRef
+ member this.SystemLinqExpressionsScopeRef = lazyRef
+ member this.SystemCollectionsScopeRef = lazyRef
+ member this.SpecialNameAttributeScopeRef = ecmaMscorlibScopeRef
+ member this.NonSerializedAttributeScopeRef = ecmaMscorlibScopeRef
+ member this.MarshalByRefObjectScopeRef = ecmaMscorlibScopeRef
+ member this.ArgIteratorTypeScopeRef = ecmaMscorlibScopeRef
+ }
+let EcmaILGlobals = mkILGlobals (mkMscorlibBasedTraits MscorlibScopeRef) None false
+
(* Q: CompilerGeneratedAttribute is new in 2.0. Unconditional generation of this attribute prevents running on 1.1 Framework. (discovered running on early mono version). *)
-let tref_CompilerGeneratedAttribute ilg = mkILTyRef (ilg.mscorlibScopeRef,tname_CompilerGeneratedAttribute)
+let tref_CompilerGeneratedAttribute ilg = mkILTyRef (ilg.traits.ScopeRef, tname_CompilerGeneratedAttribute)
+[]
let tname_DebuggerNonUserCodeAttribute = "System.Diagnostics.DebuggerNonUserCodeAttribute"
+[]
let tname_DebuggableAttribute_DebuggingModes = "DebuggingModes"
+[]
let tname_DebuggerHiddenAttribute = "System.Diagnostics.DebuggerHiddenAttribute"
+[]
let tname_DebuggerDisplayAttribute = "System.Diagnostics.DebuggerDisplayAttribute"
+[]
let tname_DebuggerTypeProxyAttribute = "System.Diagnostics.DebuggerTypeProxyAttribute"
+[]
let tname_DebuggerStepThroughAttribute = "System.Diagnostics.DebuggerStepThroughAttribute"
+[]
let tname_DebuggerBrowsableAttribute = "System.Diagnostics.DebuggerBrowsableAttribute"
+[]
let tname_DebuggerBrowsableState = "System.Diagnostics.DebuggerBrowsableState"
-let tref_DebuggerNonUserCodeAttribute ilg = mkILTyRef (ilg.mscorlibScopeRef,tname_DebuggerNonUserCodeAttribute)
-let tref_DebuggerStepThroughAttribute ilg = mkILTyRef (ilg.mscorlibScopeRef,tname_DebuggerStepThroughAttribute)
-let tref_DebuggerHiddenAttribute ilg = mkILTyRef (ilg.mscorlibScopeRef,tname_DebuggerHiddenAttribute)
-let tref_DebuggerDisplayAttribute ilg = mkILTyRef (ilg.mscorlibScopeRef,tname_DebuggerDisplayAttribute)
-let tref_DebuggerTypeProxyAttribute ilg = mkILTyRef (ilg.mscorlibScopeRef,tname_DebuggerTypeProxyAttribute)
-let tref_DebuggerBrowsableAttribute ilg = mkILTyRef (ilg.mscorlibScopeRef,tname_DebuggerBrowsableAttribute)
-let tref_DebuggableAttribute ilg = mkILTyRef (ilg.mscorlibScopeRef,tname_DebuggableAttribute)
-let tref_DebuggableAttribute_DebuggingModes ilg = mkILNestedTyRef (ilg.mscorlibScopeRef,[tname_DebuggableAttribute],tname_DebuggableAttribute_DebuggingModes)
-
-let typ_DebuggerBrowsableState ilg =
- let tref_DebuggerBrowsableState = mkILTyRef(ilg.mscorlibScopeRef,tname_DebuggerBrowsableState)
- ILType.Value (mkILNonGenericTySpec tref_DebuggerBrowsableState)
-
-let mkCompilerGeneratedAttribute ilg = mkILCustomAttribute ilg (tref_CompilerGeneratedAttribute ilg,[],[],[])
-let mkDebuggerNonUserCodeAttribute ilg = mkILCustomAttribute ilg (tref_DebuggerNonUserCodeAttribute ilg,[],[],[])
-let mkDebuggerHiddenAttribute ilg = mkILCustomAttribute ilg (tref_DebuggerHiddenAttribute ilg,[],[],[])
-let mkDebuggerDisplayAttribute ilg s = mkILCustomAttribute ilg (tref_DebuggerDisplayAttribute ilg,[ilg.typ_String],[ILAttribElem.String (Some s)],[])
-let mkDebuggerTypeProxyAttribute ilg (ty:ILType) =
- mkILCustomAttribute ilg (tref_DebuggerTypeProxyAttribute ilg,[ilg.typ_Type],[ILAttribElem.TypeRef (Some ty.TypeRef)],[])
-let mkDebuggerBrowsableAttribute ilg n = mkILCustomAttribute ilg (tref_DebuggerBrowsableAttribute ilg,[typ_DebuggerBrowsableState ilg],[ILAttribElem.Int32 n],[])
-let mkDebuggerBrowsableNeverAttribute ilg =
- match ilg.debuggerBrowsableNeverAttributeCache with
- | None ->
- let res = mkDebuggerBrowsableAttribute ilg 0
- ilg.debuggerBrowsableNeverAttributeCache <- Some res
- res
- | Some res -> res
-let mkDebuggerStepThroughAttribute ilg = mkILCustomAttribute ilg (tref_DebuggerStepThroughAttribute ilg,[],[],[])
-let mkDebuggableAttribute ilg (jitTracking, jitOptimizerDisabled) =
- mkILCustomAttribute ilg (tref_DebuggableAttribute ilg,[ilg.typ_Bool;ilg.typ_Bool], [ILAttribElem.Bool jitTracking; ILAttribElem.Bool jitOptimizerDisabled],[])
-
+let mkSystemDiagnosticsDebugTypeRef (ilg : ILGlobals) typeName = mkILTyRef (ilg.traits.SystemDiagnosticsDebugScopeRef.Value, typeName)
+let mkSystemDiagnosticsDebuggableTypeRef (ilg : ILGlobals) = mkILTyRef (ilg.traits.ScopeRef, tname_DebuggableAttribute)
+let tref_DebuggableAttribute_DebuggingModes ilg = mkILNestedTyRef (ilg.traits.ScopeRef, [tname_DebuggableAttribute],tname_DebuggableAttribute_DebuggingModes)
+
+
+type ILGlobals with
+ member this.mkDebuggerNonUserCodeAttribute() = mkILCustomAttribute this (mkSystemDiagnosticsDebugTypeRef this tname_DebuggerNonUserCodeAttribute, [], [], [])
+ member this.mkDebuggerHiddenAttribute() = mkILCustomAttribute this (mkSystemDiagnosticsDebugTypeRef this tname_DebuggerHiddenAttribute, [], [], [])
+ member this.mkDebuggerDisplayAttribute s = mkILCustomAttribute this (mkSystemDiagnosticsDebugTypeRef this tname_DebuggerDisplayAttribute, [this.typ_String],[ILAttribElem.String (Some s)],[])
+ member this.mkDebuggerTypeProxyAttribute (ty : ILType) = mkILCustomAttribute this (mkSystemDiagnosticsDebugTypeRef this tname_DebuggerTypeProxyAttribute, [this.typ_Type],[ILAttribElem.TypeRef (Some ty.TypeRef)],[])
+ member this.tref_DebuggerBrowsableAttribute n =
+ let typ_DebuggerBrowsableState =
+ let tref = mkSystemDiagnosticsDebugTypeRef this tname_DebuggerBrowsableState
+ ILType.Value (mkILNonGenericTySpec tref)
+ mkILCustomAttribute this (mkSystemDiagnosticsDebugTypeRef this tname_DebuggerBrowsableAttribute, [typ_DebuggerBrowsableState],[ILAttribElem.Int32 n],[])
+
+ member this.mkDebuggerBrowsableNeverAttribute() =
+ match this.debuggerBrowsableNeverAttributeCache with
+ | None ->
+ let res = this.tref_DebuggerBrowsableAttribute 0
+ this.debuggerBrowsableNeverAttributeCache <- Some res
+ res
+ | Some res -> res
+
+ member this.mkDebuggerStepThroughAttribute() = mkILCustomAttribute this (mkSystemDiagnosticsDebugTypeRef this tname_DebuggerStepThroughAttribute, [], [], [])
+ member this.mkDebuggableAttribute (jitTracking, jitOptimizerDisabled) =
+ mkILCustomAttribute this (mkSystemDiagnosticsDebuggableTypeRef this, [this.typ_Bool; this.typ_Bool], [ILAttribElem.Bool jitTracking; ILAttribElem.Bool jitOptimizerDisabled], [])
+
+
+ member this.mkDebuggableAttributeV2(jitTracking, ignoreSymbolStoreSequencePoints, jitOptimizerDisabled,enableEnC) =
+ let tref = mkSystemDiagnosticsDebuggableTypeRef this
+ mkILCustomAttribute this
+ (tref,[mkILNonGenericValueTy (tref_DebuggableAttribute_DebuggingModes this)],
+ [ILAttribElem.Int32(
+ (* See System.Diagnostics.DebuggableAttribute.DebuggingModes *)
+ (if jitTracking then 1 else 0) |||
+ (if jitOptimizerDisabled then 256 else 0) |||
+ (if ignoreSymbolStoreSequencePoints then 2 else 0) |||
+ (if enableEnC then 4 else 0))],[])
+
+ member this.mkCompilerGeneratedAttribute () = mkILCustomAttribute this (tref_CompilerGeneratedAttribute this, [], [], [])
// Bug 2129. Requests attributes to be added to compiler generated methods
let addGeneratedAttrs ilg (attrs: ILAttributes) =
@@ -4386,8 +4514,8 @@ let addGeneratedAttrs ilg (attrs: ILAttributes) =
match ilg.generatedAttribsCache with
| [] ->
let res = [ if not ilg.noDebugData then
- yield mkCompilerGeneratedAttribute ilg
- yield mkDebuggerNonUserCodeAttribute ilg]
+ yield ilg.mkCompilerGeneratedAttribute()
+ yield ilg.mkDebuggerNonUserCodeAttribute()]
ilg.generatedAttribsCache <- res
res
| res -> res
@@ -4397,9 +4525,7 @@ let addMethodGeneratedAttrs ilg (mdef:ILMethodDef) = {mdef with CustomAttrs
let addPropertyGeneratedAttrs ilg (pdef:ILPropertyDef) = {pdef with CustomAttrs = addGeneratedAttrs ilg pdef.CustomAttrs}
let addFieldGeneratedAttrs ilg (fdef:ILFieldDef) = {fdef with CustomAttrs = addGeneratedAttrs ilg fdef.CustomAttrs}
-let add_never_attrs ilg (attrs: ILAttributes) =
- if ilg.generateDebugBrowsableData then mkILCustomAttrs (attrs.AsList @ [mkDebuggerBrowsableNeverAttribute ilg])
- else attrs
+let add_never_attrs (ilg : ILGlobals) (attrs: ILAttributes) = mkILCustomAttrs (attrs.AsList @ [ilg.mkDebuggerBrowsableNeverAttribute()])
let addPropertyNeverAttrs ilg (pdef:ILPropertyDef) = {pdef with CustomAttrs = add_never_attrs ilg pdef.CustomAttrs}
let addFieldNeverAttrs ilg (fdef:ILFieldDef) = {fdef with CustomAttrs = add_never_attrs ilg fdef.CustomAttrs}
@@ -4417,7 +4543,7 @@ let mkPermissionSet (ilg: ILGlobals) (action,attributes: list<(ILTypeRef * (stri
[| yield (byte '.');
yield! z_unsigned_int attributes.Length;
for (tref:ILTypeRef,props) in attributes do
- yield! encodeCustomAttrString tref.QualifiedNameWithNoShortMscorlib
+ yield! encodeCustomAttrString tref.QualifiedNameWithNoShortPrimaryAssembly
let bytes =
[| yield! z_unsigned_int props.Length;
for (nm,typ,value) in props do
@@ -4677,18 +4803,8 @@ let decodeILAttribData ilg (ca: ILAttribute) scope =
let v,sigptr = parseVal ty sigptr
parseNamed ((nm,ty,isProp,v) :: acc) (n-1) sigptr
let named = parseNamed [] (int nnamed) sigptr
- fixedArgs,named
-
+ fixedArgs,named
-let mkDebuggableAttributeV2 ilg (jitTracking, ignoreSymbolStoreSequencePoints, jitOptimizerDisabled,enableEnC) =
- mkILCustomAttribute ilg
- (tref_DebuggableAttribute ilg,[mkILNonGenericValueTy (tref_DebuggableAttribute_DebuggingModes ilg)],
- [ILAttribElem.Int32(
- (* See System.Diagnostics.DebuggableAttribute.DebuggingModes *)
- (if jitTracking then 1 else 0) |||
- (if jitOptimizerDisabled then 256 else 0) |||
- (if ignoreSymbolStoreSequencePoints then 2 else 0) |||
- (if enableEnC then 4 else 0))],[])
// --------------------------------------------------------------------
// Functions to collect up all the references in a full module or
diff --git a/src/absil/il.fsi b/src/absil/il.fsi
index d3e323bcae..62323b5069 100755
--- a/src/absil/il.fsi
+++ b/src/absil/il.fsi
@@ -8,10 +8,9 @@
//
// You must not remove this notice, or any other, from this software.
//----------------------------------------------------------------------------
-
/// The "unlinked" view of .NET metadata and code. Central to
/// to Abstract IL library
-module internal Microsoft.FSharp.Compiler.AbstractIL.IL
+module (*internal*) Microsoft.FSharp.Compiler.AbstractIL.IL
open Internal.Utilities
open System.Collections.Generic
@@ -52,7 +51,7 @@ type ILList<'T> = 'T list
// format used for code.
//
// 2. The "typ_XYZ", "tspec_XYZ" and "mspec_XYZ" values which
-// can be used to reference types in the "mscorlib" assembly.
+// can be used to reference types in the "primary assembly (either System.Runtime or mscorlib)" assembly.
//
// 3. The "rescopeXYZ" functions which can be used to lift a piece of
// metadata from one assembly and transform it to a piece of metadata
@@ -135,7 +134,7 @@ type ILAssemblyRef =
member Hash: byte[] option;
member PublicKey: PublicKey option;
/// CLI says this indicates if the assembly can be retargeted (at runtime) to be from a different publisher.
- member Retargetable: bool;
+ member Retargetable: bool;
member Version: ILVersionInfo option;
member Locale: string option
interface System.IComparable
@@ -270,7 +269,7 @@ type ILArrayBounds = ILArrayBound * ILArrayBound
[]
type ILArrayShape =
- | ILArrayShape of ILArrayBounds list (* lobound/size pairs *)
+ | ILArrayShape of ILArrayBounds list // lobound/size pairs
member Rank : int
/// Bounds for a single dimensional, zero based array
static member SingleDimensional: ILArrayShape
@@ -304,7 +303,7 @@ type ILTypeRef =
member BasicQualifiedName : string
member QualifiedName: string
#if EXTENSIONTYPING
- member QualifiedNameWithNoShortMscorlib: string
+ member QualifiedNameWithNoShortPrimaryAssembly: string
#endif
interface System.IComparable
@@ -365,7 +364,7 @@ and
member GenericArgs : ILGenericArgs
member IsTyvar : bool
member BasicQualifiedName : string
- member QualifiedNameWithNoShortMscorlib : string
+ member QualifiedNameWithNoShortPrimaryAssembly : string
and []
ILCallingSignature =
@@ -592,8 +591,8 @@ type ILInstr =
// Control transfer
| I_br of ILCodeLabel
| I_jmp of ILMethodSpec
- | I_brcmp of ILComparisonInstr * ILCodeLabel * ILCodeLabel (* second label is fall-through *)
- | I_switch of (ILCodeLabel list * ILCodeLabel) (* last label is fallthrough *)
+ | I_brcmp of ILComparisonInstr * ILCodeLabel * ILCodeLabel // second label is fall-through
+ | I_switch of (ILCodeLabel list * ILCodeLabel) // last label is fallthrough
| I_ret
// Method call
@@ -1396,7 +1395,7 @@ type ILTypeDefAccess =
// really, absolutely a value type until you bind the
// super class and test it for type equality against System.ValueType.
// However, this is unbearably annoying, as it means you
-// have to load "mscorlib" and perform bind operations
+// have to load "primary runtime assembly (System.Runtime or mscorlib)" and perform bind operations
// in order to be able to determine some quite simple
// things. So we approximate by simply looking at the name
// of the superclass when loading.
@@ -1662,6 +1661,30 @@ val isTypeNameForGlobalFunctions: string -> bool
val ungenericizeTypeName: string -> string (* e.g. List`1 --> List *)
+/// Represents the capabilities of target framework profile.
+/// Different profiles may omit some types or contain them in different assemblies
+type IPrimaryAssemblyTraits =
+
+ abstract TypedReferenceTypeScopeRef : ILScopeRef option
+ abstract RuntimeArgumentHandleTypeScopeRef : ILScopeRef option
+ abstract SerializationInfoTypeScopeRef : ILScopeRef option
+ abstract SecurityPermissionAttributeTypeScopeRef : ILScopeRef option
+ abstract IDispatchConstantAttributeScopeRef : ILScopeRef option
+ abstract IUnknownConstantAttributeScopeRef : ILScopeRef option
+ abstract ArgIteratorTypeScopeRef : ILScopeRef option
+ abstract MarshalByRefObjectScopeRef : ILScopeRef option
+ abstract ThreadStaticAttributeScopeRef : ILScopeRef option
+ abstract SpecialNameAttributeScopeRef : ILScopeRef option
+ abstract ContextStaticAttributeScopeRef : ILScopeRef option
+ abstract NonSerializedAttributeScopeRef : ILScopeRef option
+
+ abstract SystemRuntimeInteropServicesScopeRef : Lazy
+ abstract SystemLinqExpressionsScopeRef : Lazy
+ abstract SystemCollectionsScopeRef : Lazy
+ abstract SystemReflectionScopeRef : Lazy
+ abstract SystemDiagnosticsDebugScopeRef : Lazy
+ abstract ScopeRef : ILScopeRef
+
// ====================================================================
// PART 2
//
@@ -1670,16 +1693,15 @@ val ungenericizeTypeName: string -> string (* e.g. List`1 --> List *)
// e.g. by filling in all appropriate record fields.
// ==================================================================== *)
-/// A table of common references to items in mscorlib. Version-neutral references
-/// can be generated using ecmaILGlobals. If you have already loaded a particular
-/// version of mscorlib you should reference items via an ILGlobals for that particular
-/// version of mscorlib built using mkILGlobals.
+/// A table of common references to items in primary assebly (System.Runtime or mscorlib).
+/// If you have already loaded a particular version of system runtime assembly you should reference items via an ILGlobals for that particular
+/// version of system runtime assembly built using mkILGlobals.
[]
type ILGlobals =
- { mscorlibScopeRef: ILScopeRef
- mscorlibAssemblyName: string
+ {
+ traits : IPrimaryAssemblyTraits
+ primaryAssemblyName: string
noDebugData: bool
- generateDebugBrowsableData: bool
tref_Object: ILTypeRef
tspec_Object: ILTypeSpec
typ_Object: ILType
@@ -1691,13 +1713,13 @@ type ILGlobals =
typ_IComparable: ILType
tref_Type: ILTypeRef
typ_Type: ILType
- typ_Missing: ILType
+ typ_Missing: Lazy
typ_Activator: ILType
typ_Delegate: ILType
typ_ValueType: ILType
typ_Enum: ILType
- tspec_TypedReference: ILTypeSpec
- typ_TypedReference: ILType
+ tspec_TypedReference: ILTypeSpec option
+ typ_TypedReference: ILType option
typ_MulticastDelegate: ILType
typ_Array: ILType
tspec_Int64: ILTypeSpec
@@ -1728,7 +1750,7 @@ type ILGlobals =
typ_char: ILType
typ_IntPtr: ILType
typ_UIntPtr: ILType
- typ_RuntimeArgumentHandle: ILType
+ typ_RuntimeArgumentHandle: ILType option
typ_RuntimeTypeHandle: ILType
typ_RuntimeMethodHandle: ILType
typ_RuntimeFieldHandle: ILType
@@ -1744,18 +1766,33 @@ type ILGlobals =
typ_Double: ILType
typ_Bool: ILType
typ_Char: ILType
- typ_SerializationInfo: ILType
+ typ_SerializationInfo: ILType option
typ_StreamingContext: ILType
- tref_SecurityPermissionAttribute : ILTypeRef
+ tref_SecurityPermissionAttribute : ILTypeRef option
tspec_Exception: ILTypeSpec
typ_Exception: ILType
mutable generatedAttribsCache: ILAttribute list
mutable debuggerBrowsableNeverAttributeCache : ILAttribute option
mutable debuggerTypeProxyAttributeCache : ILAttribute option }
-/// Build the table of commonly used references given a ILScopeRef for mscorlib.
-val mkILGlobals : mscorlibScopeRef:ILScopeRef -> mscorlibAssemblyNameOpt:string option -> noDebugData:bool * generateDebugBrowsableData:bool -> ILGlobals
+ with
+ member mkDebuggableAttribute: bool (* debug tracking *) * bool (* disable JIT optimizations *) -> ILAttribute
+ /// Some commonly used custom attibutes
+ member mkDebuggableAttributeV2 : bool (* jitTracking *) * bool (* ignoreSymbolStoreSequencePoints *) * bool (* disable JIT optimizations *) * bool (* enable EnC *) -> ILAttribute
+ member mkCompilerGeneratedAttribute : unit -> ILAttribute
+ member mkDebuggerNonUserCodeAttribute : unit -> ILAttribute
+ member mkDebuggerStepThroughAttribute : unit -> ILAttribute
+ member mkDebuggerHiddenAttribute : unit -> ILAttribute
+ member mkDebuggerDisplayAttribute : string -> ILAttribute
+ member mkDebuggerTypeProxyAttribute : ILType -> ILAttribute
+ member mkDebuggerBrowsableNeverAttribute : unit -> ILAttribute
+
+/// Build the table of commonly used references given a ILScopeRef for system runtime assembly.
+val mkILGlobals : IPrimaryAssemblyTraits -> string option -> bool -> ILGlobals
+
+val mkMscorlibBasedTraits : ILScopeRef -> IPrimaryAssemblyTraits
+val EcmaILGlobals : ILGlobals
/// When writing a binary the fake "toplevel" type definition (called )
/// must come first. This function puts it first, and creates it in the returned list as an empty typedef if it
@@ -2172,28 +2209,11 @@ val instILType: ILGenericArgs -> ILType -> ILType
/// This is a 'vendor neutral' way of referencing mscorlib.
val ecmaPublicKey: PublicKey
-/// This is a 'vendor neutral' way of referencing mscorlib.
-val ecmaMscorlibScopeRef: ILScopeRef
-/// This is a 'vendor neutral' collection of references to items in mscorlib.
-val ecmaILGlobals: ILGlobals
-
/// Some commonly used methods
val mkInitializeArrayMethSpec: ILGlobals -> ILMethodSpec
-val mkMscorlibExnNewobj: ILGlobals -> string -> ILInstr
-
-/// Some commonly used custom attibutes
-val mkDebuggableAttribute: ILGlobals -> bool (* debug tracking *) * bool (* disable JIT optimizations *) -> ILAttribute
-val mkDebuggableAttributeV2: ILGlobals -> bool (* jitTracking *) * bool (* ignoreSymbolStoreSequencePoints *) * bool (* disable JIT optimizations *) * bool (* enable EnC *) -> ILAttribute
-
-val mkCompilerGeneratedAttribute : ILGlobals -> ILAttribute
-val mkDebuggerNonUserCodeAttribute : ILGlobals -> ILAttribute
-val mkDebuggerStepThroughAttribute : ILGlobals -> ILAttribute
-val mkDebuggerHiddenAttribute : ILGlobals -> ILAttribute
-val mkDebuggerDisplayAttribute : ILGlobals -> string -> ILAttribute
-val mkDebuggerTypeProxyAttribute : ILGlobals -> ILType -> ILAttribute
-val mkDebuggerBrowsableNeverAttribute : ILGlobals -> ILAttribute
+val mkPrimaryAssemblyExnNewobj: ILGlobals -> string -> ILInstr
val addMethodGeneratedAttrs : ILGlobals -> ILMethodDef -> ILMethodDef
val addPropertyGeneratedAttrs : ILGlobals -> ILPropertyDef -> ILPropertyDef
diff --git a/src/absil/ilascii.fs b/src/absil/ilascii.fs
index 709cc839fc..ceca10c9b6 100755
--- a/src/absil/ilascii.fs
+++ b/src/absil/ilascii.fs
@@ -21,7 +21,8 @@ open Microsoft.FSharp.Compiler.AbstractIL.Diagnostics
open Microsoft.FSharp.Compiler.AbstractIL.Extensions.ILX.Types
open Microsoft.FSharp.Compiler.AbstractIL.IL
-let parseILGlobals = ref ecmaILGlobals
+// set to the proper value at build.fs (BuildFrameworkTcImports)
+let parseILGlobals = ref EcmaILGlobals
// --------------------------------------------------------------------
// Table of parsing and pretty printing data for instructions.
diff --git a/src/absil/illib.fs b/src/absil/illib.fs
index 3b7bfb5fe2..17b6d22946 100755
--- a/src/absil/illib.fs
+++ b/src/absil/illib.fs
@@ -11,7 +11,9 @@
//----------------------------------------------------------------------------
-module (* internal *) Microsoft.FSharp.Compiler.AbstractIL.Internal.Library
+
+
+module (*internal*) Microsoft.FSharp.Compiler.AbstractIL.Internal.Library
#nowarn "1178" // The struct, record or union type 'internal_instr_extension' is not structurally comparable because the type
@@ -59,6 +61,8 @@ module Order =
module Array =
+ let take n xs = xs |> Seq.take n |> Array.ofSeq
+
let mapq f inp =
match inp with
| [| |] -> inp
@@ -94,9 +98,9 @@ module Array =
res, acc
- // REVIEW: systematically eliminate fmap/mapFold duplication.
+ // REVIEW: systematically eliminate foldMap/mapFold duplication.
// They only differ by the tuple returned by the function.
- let fmap f s l =
+ let foldMap f s l =
let mutable acc = s
let n = Array.length l
let mutable res = Array.zeroCreate n
@@ -160,8 +164,8 @@ module Option =
| None -> dflt
| Some x -> x
- // REVIEW: systematically eliminate fmap/mapFold duplication
- let fmap f z l =
+ // REVIEW: systematically eliminate foldMap/mapFold duplication
+ let foldMap f z l =
match l with
| None -> z,None
| Some x -> let z,x = f z x
@@ -350,11 +354,11 @@ module List =
List.rev r, s
// note: not tail recursive
- let rec mapfoldBack f l s =
+ let rec mapFoldBack f l s =
match l with
| [] -> ([],s)
| h::t ->
- let t',s = mapfoldBack f t s
+ let t',s = mapFoldBack f t s
let h',s = f h s
(h'::t', s)
@@ -369,10 +373,10 @@ module List =
let count pred xs = List.fold (fun n x -> if pred x then n+1 else n) 0 xs
- let rec private repeatA n x acc = if n <= 0 then acc else repeatA (n-1) x (x::acc)
- let repeat n x = repeatA n x []
+ let rec private repeatAux n x acc = if n <= 0 then acc else repeatAux (n-1) x (x::acc)
+ let repeat n x = repeatAux n x []
- (* WARNING: not tail-recursive *)
+ // WARNING: not tail-recursive
let mapHeadTail fhead ftail = function
| [] -> []
| [x] -> [fhead x]
@@ -385,25 +389,27 @@ module List =
let singleton x = [x]
// note: must be tail-recursive
- let rec private fmapA f z l acc =
+ let rec private foldMapAux f z l acc =
match l with
| [] -> z,List.rev acc
| x::xs -> let z,x = f z x
- fmapA f z xs (x::acc)
+ foldMapAux f z xs (x::acc)
// note: must be tail-recursive
- // REVIEW: systematically eliminate fmap/mapFold duplication
- let fmap f z l = fmapA f z l []
+ // REVIEW: systematically eliminate foldMap/mapFold duplication
+ let foldMap f z l = foldMapAux f z l []
let collect2 f xs ys = List.concat (List.map2 f xs ys)
+ let toArraySquared xss = xss |> List.map List.toArray |> List.toArray
let iterSquared f xss = xss |> List.iter (List.iter f)
let collectSquared f xss = xss |> List.collect (List.collect f)
let mapSquared f xss = xss |> List.map (List.map f)
- let mapfoldSquared f xss = xss |> mapFold (mapFold f)
+ let mapFoldSquared f z xss = mapFold (mapFold f) z xss
let forallSquared f xss = xss |> List.forall (List.forall f)
let mapiSquared f xss = xss |> List.mapi (fun i xs -> xs |> List.mapi (fun j x -> f i j x))
let existsSquared f xss = xss |> List.exists (fun xs -> xs |> List.exists (fun x -> f x))
+ let mapiFoldSquared f z xss = mapFoldSquared f z (xss |> mapiSquared (fun i j x -> (i,j,x)))
module String =
let indexNotFound() = raise (new System.Collections.Generic.KeyNotFoundException("An index for the character was not found in the string"))
@@ -539,13 +545,13 @@ module FlatList =
let arr,acc = Array.mapFold f acc x.array
FlatList(arr),acc
- // REVIEW: systematically eliminate fmap/mapFold duplication
- let fmap f acc (x:FlatList<_>) =
+ // REVIEW: systematically eliminate foldMap/mapFold duplication
+ let foldMap f acc (x:FlatList<_>) =
match x.array with
| null ->
acc,FlatList.Empty
| arr ->
- let acc,arr = Array.fmap f acc x.array
+ let acc,arr = Array.foldMap f acc x.array
acc,FlatList(arr)
#endif
#if FLAT_LIST_AS_LIST
@@ -558,7 +564,7 @@ module FlatList =
let order eltOrder = List.order eltOrder
let mapq f (x:FlatList<_>) = List.mapq f x
let mapFold f acc (x:FlatList<_>) = List.mapFold f acc x
- let fmap f acc (x:FlatList<_>) = List.fmap f acc x
+ let foldMap f acc (x:FlatList<_>) = List.foldMap f acc x
#endif
@@ -568,7 +574,7 @@ module FlatList =
let order eltOrder = Array.order eltOrder
let mapq f x = Array.mapq f x
let mapFold f acc x = Array.mapFold f acc x
- let fmap f acc x = Array.fmap f acc x
+ let foldMap f acc x = Array.foldMap f acc x
#endif
@@ -674,7 +680,7 @@ module Eventually =
| Exception e -> raise e)
let tryWith e handler =
- catch e
+ catch e
|> bind (function Result v -> Done v | Exception e -> handler e)
type EventuallyBuilder() =
@@ -837,18 +843,18 @@ module NameMap =
let toList (l: NameMap<'T>) = Map.toList l
let layer (m1 : NameMap<'T>) m2 = Map.foldBack Map.add m1 m2
- (* not a very useful function - only called in one place - should be changed *)
+ /// Not a very useful function - only called in one place - should be changed
let layerAdditive addf m1 m2 =
Map.foldBack (fun x y sofar -> Map.add x (addf (Map.tryFindMulti x sofar) y) sofar) m1 m2
- // Union entries by identical key, using the provided function to union sets of values
+ /// Union entries by identical key, using the provided function to union sets of values
let union unionf (ms: NameMap<_> seq) =
seq { for m in ms do yield! m }
|> Seq.groupBy (fun (KeyValue(k,_v)) -> k)
|> Seq.map (fun (k,es) -> (k,unionf (Seq.map (fun (KeyValue(_k,v)) -> v) es)))
|> Map.ofSeq
- (* For every entry in m2 find an entry in m1 and fold *)
+ /// For every entry in m2 find an entry in m1 and fold
let subfold2 errf f m1 m2 acc =
Map.foldBack (fun n x2 acc -> try f n (Map.find n m1) x2 acc with :? KeyNotFoundException -> errf n x2) m2 acc
@@ -915,435 +921,6 @@ module MultiMap =
let empty : MultiMap<_,_> = Map.empty
let initBy f xs : MultiMap<_,_> = xs |> Seq.groupBy f |> Seq.map (fun (k,v) -> (k,List.ofSeq v)) |> Map.ofSeq
-#if LAYERED_MAPS
-/// State of immutable map collection, converted to a dictionary on first lookup.
-[]
-type LayeredMapState<'Key,'Value when 'Key : equality and 'Key : comparison> =
- /// Collapsible(entries, size)
- | Collapsible of list>> * int
- /// Collapsed(frontMap, backingDict)
- | Collapsed of (Map<'Key,'Value> * Dictionary<'Key,'Value>)
-
-/// Immutable map collection, with explicit flattening to a backing dictionary
-///
-/// A layered map is still an immutable map containing a "front"
-/// F# Map, but the layered map collapses its entries to a "backing"
-/// dictionary at specific "add-and-collapse" points.
-///
-/// For maps built from multiple "add-and-collapse" operations,
-/// the process of building the collapsed maps is coalesced.
-[]
-type LayeredMap<'Key,'Value when 'Key : equality and 'Key : comparison>(state:LayeredMapState<'Key,'Value>) =
- let mutable state = state
- static let empty = LayeredMap<'Key,'Value>(LayeredMapState.Collapsible ([],0))
-
- let entries() =
- match state with
- | LayeredMapState.Collapsible (el,n) -> (el,n)
- | LayeredMapState.Collapsed (m,d) -> [(m :> seq<_>); (d :> seq<_>)], m.Count + d.Count
-
- let markAsCollapsible() =
- match state with
- | LayeredMapState.Collapsible _ -> ()
- | LayeredMapState.Collapsed _ -> state <- LayeredMapState.Collapsible (entries())
-
- let collapse() =
- match state with
- | LayeredMapState.Collapsible (el, n) ->
- let d = Dictionary<_,_>(n)
- for e in List.rev el do
- for (KeyValue(k,v)) in e do
- d.[k] <- v
- let p = (Map.empty, d)
- state <- LayeredMapState.Collapsed p
- p
- | LayeredMapState.Collapsed p -> p
-
- let dict() =
- markAsCollapsible()
- let (_,dict) = collapse()
- dict
-
- static member Empty : LayeredMap<'Key,'Value> = empty
-
- member x.TryGetValue (key,res:byref<'Value>) =
- let (m,d) = collapse()
- match m.TryFind key with
- | None -> d.TryGetValue (key,&res)
- | Some r -> res <- r; true
-
- member x.ContainsKey k =
- let (map,dict) = collapse()
- map.ContainsKey k || dict.ContainsKey k
-
- member x.Item
- with get key =
- // collapse on first lookup
- let (map,dict) = collapse()
- match map.TryFind key with
- | None ->
- let mutable res = Unchecked.defaultof<_>
- if dict.TryGetValue (key, &res) then res
- else raise <| KeyNotFoundException("the key was not found in the LayerdNameMap")
- | Some v -> v
-
- member x.TryFind key =
- let (map,dict) = collapse()
- match map.TryFind key with
- | None ->
- let mutable res = Unchecked.defaultof<_>
- if dict.TryGetValue (key, &res) then Some res else None
- | res -> res
-
- member x.Values = dict().Values
-
- member x.Elements = dict() |> Seq.readonly
-
- member x.Add (key, value) =
- match state with
- | LayeredMapState.Collapsible (el,n) -> LayeredMap<_,_>(LayeredMapState.Collapsible ((([| KeyValuePair(key,value) |] :> seq<_>) :: el), n + 1))
- | LayeredMapState.Collapsed (map,dict) -> LayeredMap (LayeredMapState.Collapsed (map.Add (key,value), dict))
-
- member x.AddAndMarkAsCollapsible (kvs: _[]) =
- let el,n = entries()
- LayeredMap<_,_>(LayeredMapState.Collapsible (((kvs :> seq<_>) :: el), n + kvs.Length))
-
- member x.MarkAsCollapsible () =
- markAsCollapsible()
- x
-#endif
-
-#if LAYERED_MULTI_MAP
-/// State of immutable map collection, converted to a dictionary on first lookup.
-[]
-type LayeredMultiMapState<'Key,'Value when 'Key : equality and 'Key : comparison> =
- /// Collapsible(entries, size)
- | Collapsible of list>> * int
- /// Collapsed(frontMap, backingDict)
- | Collapsed of (MultiMap<'Key,'Value> * Dictionary<'Key,'Value list>)
-
-/// Immutable map collection, with explicit flattening to a backing dictionary
-[]
-type LayeredMultiMap<'Key,'Value when 'Key : equality and 'Key : comparison>(state:LayeredMultiMapState<'Key,'Value>) =
-
- let mutable state = state
- static let empty = LayeredMultiMap<'Key,'Value>(LayeredMultiMapState.Collapsible ([],0))
-
- let entries() =
- match state with
- | LayeredMultiMapState.Collapsible (el,n) -> (el,n)
- | LayeredMultiMapState.Collapsed (m,d) -> [(m :> seq<_>); (d :> seq<_>)], m.Count + d.Count
-
- let markAsCollapsible() =
- match state with
- | LayeredMultiMapState.Collapsible _ -> ()
- | LayeredMultiMapState.Collapsed _ -> state <- LayeredMultiMapState.Collapsible (entries())
-
- let collapse() =
- match state with
- | LayeredMultiMapState.Collapsible (el, n) ->
- let d = Dictionary<_,_>(n)
- for e in List.rev el do
- for (KeyValue(k,vs)) in e do
- for v in List.rev vs do
- let prev =
- let mutable res = Unchecked.defaultof<'Value list>
- let ok = d.TryGetValue(k,&res)
- if ok then res else []
- d.[k] <- v::prev
- let p = (MultiMap.empty, d)
- state <- LayeredMultiMapState.Collapsed p
- p
- | LayeredMultiMapState.Collapsed p -> p
-
- let dict() =
- markAsCollapsible()
- let (_,dict) = collapse()
- dict
-
- static member Empty : LayeredMultiMap<'Key,'Value> = empty
-
- member x.TryGetValue (key,res:byref<'Value list>) =
- let (m,d) = collapse()
- match m.TryFind key with
- | None -> d.TryGetValue (key,&res)
- | Some res1 ->
- let mutable res2 = Unchecked.defaultof<'Value list>
- let ok = d.TryGetValue (key,&res2)
- if ok then res <- (res1@res2); true
- else res <- res1; true
-
- member x.ContainsKey k =
- let (map,dict) = collapse()
- map.ContainsKey k || dict.ContainsKey k
-
- member x.Item
- with get key =
- let mutable res = Unchecked.defaultof<_>
- if x.TryGetValue (key, &res) then res
- else []
-
- member x.TryFind key =
- let mutable res = Unchecked.defaultof<_>
- if x.TryGetValue (key, &res) then Some res
- else None
-
- member x.Values = dict().Values |> Seq.concat
-
- member x.Add (key, value) =
- match state with
- | LayeredMultiMapState.Collapsible (el,n) -> LayeredMultiMap<_,_>(LayeredMultiMapState.Collapsible ((([| KeyValuePair(key,[value]) |] :> seq<_>) :: el), n + 1))
- | LayeredMultiMapState.Collapsed (map,dict) -> LayeredMultiMap (LayeredMultiMapState.Collapsed (MultiMap.add key value map, dict))
-
- member x.AddAndMarkAsCollapsible (kvs: _[]) =
- let el,n = entries()
- LayeredMultiMap<_,_>(LayeredMultiMapState.Collapsible ((([| for KeyValue(k,v) in kvs -> KeyValuePair(k,[v]) |] :> seq<_>) :: el), n + kvs.Length))
-
- member x.MarkAsCollapsible () =
- markAsCollapsible()
- x
-
-#endif
-//#if NEW_LAYERED_MAP
-
-/// Immutable map collection, with explicit flattening to a backing dictionary
-///
-/// A layered map is still an immutable map containing a "front"
-/// F# Map, but the layered map collapses its treeMap to a "backing"
-/// dictionary at specific "add-and-tryCollapseToDictAndNothingElse" points.
-///
-/// For maps built from multiple "add-and-tryCollapseToDictAndNothingElse" operations,
-/// the process of building the collapsed maps is coalesced.
-type LayeredMap<'Key,'Value when 'Key : equality and 'Key : comparison>
- (// The queue of operations to build the full map, empty except during bulk-add operations
- xqueue: list[],
- ('Key * ('Value option -> 'Value))>>,
- // The existing backing tree map (which is looked up in preference to the dictionary)
- xentries: Map<'Key,'Value>,
- // The existing backing dictionary (which may be null)
- xdict: Dictionary<'Key,'Value>) =
- static let empty = LayeredMap<'Key,'Value>([], Map.empty, null)
- let mutable state = (xqueue,xentries,xdict)
-
- let tryCollapseToDictAndNothingElse force =
- let (bulkQueue,treeMap,fastDict) = state
- if not bulkQueue.IsEmpty || force then
- // bulkQueue.Length +
- let d = Dictionary<_,_>(treeMap.Count + (match fastDict with null -> 0 | _ -> fastDict.Count))
- begin
- match fastDict with
- | null -> ()
- | _ ->
- for (KeyValue(k,v)) in fastDict do
- d.[k] <- v
- end
- treeMap |> Map.iter (fun k v -> d.[k] <- v)
- for kvsOrModify in List.rev bulkQueue do
- match kvsOrModify with
- | Choice1Of2 kvs ->
- for (KeyValue(k,v)) in kvs do
- d.[k] <- v
- | Choice2Of2 (k,updatef) ->
- let mutable prev = Unchecked.defaultof<_>
- let n = updatef (if d.TryGetValue(k,&prev) then Some prev else None)
- d.[k] <- n
-
- state <- ([], Map.empty, d)
- d
- elif treeMap.IsEmpty then fastDict
- else null
-
- static member Empty : LayeredMap<'Key,'Value> = empty
-
- member x.TryGetValue (key,res:byref<'Value>) =
- match tryCollapseToDictAndNothingElse false with
- | null ->
- let (_,treeMap,fastDict) = state
- match treeMap.TryFind key with
- | None ->
- match fastDict with
- | null -> false
- | _ -> fastDict.TryGetValue (key,&res)
- | Some r -> res <- r; true
- | fastDict ->
- //printfn "collapsed"
- match fastDict with
- | null -> false
- | _ -> fastDict.TryGetValue (key, &res)
-
- member x.ContainsKey key =
- let mutable res = Unchecked.defaultof<_>
- x.TryGetValue(key, &res)
-
- member x.Item
- with get key =
- let mutable res = Unchecked.defaultof<_>
- let ok = x.TryGetValue(key, &res)
- if ok then res
- else raise <| KeyNotFoundException("the key was not found in the LayerdNameMap")
-
- member x.TryFind key =
- let mutable res = Unchecked.defaultof<_>
- let ok = x.TryGetValue(key, &res)
- if ok then Some res else None
-
- member x.Values = (tryCollapseToDictAndNothingElse true).Values
-
- member x.Elements = (tryCollapseToDictAndNothingElse true) |> Seq.readonly
-
-
- member x.Add (key, value) =
- let (bulkQueue,treeMap,fastDict) = state
- if bulkQueue.IsEmpty then
- let treeMap = treeMap.Add (key, value)
- LayeredMap(bulkQueue, treeMap, fastDict)
- else
- // There are elements in the bulk queue, squash them down (mutating map "x"),
- // then use a one-element treemap
- let newFastDict = tryCollapseToDictAndNothingElse false
- match newFastDict with
- | null -> failwith "unreachable, bulkQueue was non empty, newFastDict should not be null"
- | _ -> LayeredMap([], Map.empty.Add(key,value), newFastDict)
-
- member x.AddAndMarkAsCollapsible (kvs: _[]) =
- if kvs.Length = 0 then x else
- let (bulkQueue,treeMap,fastDict) = state
- let state = (Choice1Of2 kvs::bulkQueue,treeMap,fastDict)
- LayeredMap state
-
- /// Push an item that transforms a possible existing entry. This is used for the bulk updates
- /// in nameres.fs, where, for each type we push during an "open", we must combine the
- /// type with any existing entries for types in the eUnqualifiedItems table.
- member x.LinearTryModifyThenLaterFlatten (key, f: 'Value option -> 'Value) =
- let (bulkQueue,treeMap,fastDict) = state
- let state = (Choice2Of2 (key,f)::bulkQueue,treeMap,fastDict)
- LayeredMap state
-
-
- member x.MarkAsCollapsible () = //x.AddAndMarkAsCollapsible [| |]
- let (bulkQueue,treeMap,fastDict) = state
- let state = (Choice1Of2 [| |]::bulkQueue,treeMap,fastDict)
- LayeredMap state
-
-
-//#endif
-
-//#if NEW_LAYERED_MULTI_MAP
-type LayeredMultiMap<'Key,'Value when 'Key : equality and 'Key : comparison>
- (xqueue: list[]>,
- xentries: Map<'Key,'Value list>,
- xdict: Dictionary<'Key,'Value list>) =
- static let empty = LayeredMultiMap<'Key,'Value>([], Map.empty, null)
- let mutable state = (xqueue,xentries,xdict)
-
- let tryCollapseToDictAndNothingElse force =
- let (bulkQueue,treeMap,fastDict) = state
- if not bulkQueue.IsEmpty || force then
- // bulkQueue.Length +
- let d = Dictionary<_,_>(treeMap.Count + (match fastDict with null -> 0 | _ -> fastDict.Count))
- begin
- match fastDict with
- | null -> ()
- | _ ->
- for (KeyValue(k,vs)) in fastDict do
- d.[k] <- vs
- end
- treeMap |> Map.iter (fun k vs ->
- let mutable prev = Unchecked.defaultof<_>
- if d.TryGetValue(k,&prev) then
- d.[k] <- vs@prev
- else
- d.[k] <- vs)
- //printfn "collapsing, bulkQueue = %A" bulkQueue
- for kvs in List.rev bulkQueue do
- //printfn "collapsing, bulkQueue.i] = %A" bulkQueue.[i]
- for (KeyValue(k,v)) in kvs do
- let mutable prev = Unchecked.defaultof<_>
- if d.TryGetValue(k,&prev) then
- d.[k] <- (v::prev)
- else
- d.[k] <- [v]
- state <- ([], Map.empty, d)
- d
- elif treeMap.IsEmpty then fastDict
- else null
-
- static member Empty : LayeredMultiMap<'Key,'Value> = empty
-
- member x.TryGetValue (key,res:byref<'Value list>) =
- match tryCollapseToDictAndNothingElse false with
- | null ->
- let (_,treeMap,fastDict) = state
- match treeMap.TryFind key with
- | None ->
- match fastDict with
- | null -> false
- | _ -> fastDict.TryGetValue (key,&res)
- | Some r ->
- match fastDict with
- | null ->
- res <- r
- true
- | _ ->
- let mutable res2 = Unchecked.defaultof<_>
- if fastDict.TryGetValue (key,&res2) then
- res <- r@res2
- else
- res <- r
- true
- | fastDict ->
- //printfn "collapsed"
- match fastDict with
- | null -> false
- | _ -> fastDict.TryGetValue (key, &res)
-
- member x.ContainsKey key =
- let mutable res = Unchecked.defaultof<_>
- x.TryGetValue(key, &res)
-
- member x.Item
- with get key =
- let mutable res = Unchecked.defaultof<_>
- let ok = x.TryGetValue(key, &res)
- if ok then res else []
-
- member x.TryFind key =
- let mutable res = Unchecked.defaultof<_>
- let ok = x.TryGetValue(key, &res)
- if ok then Some res else None
-
- member x.Values = (tryCollapseToDictAndNothingElse true).Values |> Seq.concat
-
- member x.Elements = (tryCollapseToDictAndNothingElse true) |> Seq.readonly
-
- member x.Add (key, value) =
- let (bulkQueue,treeMap,fastDict) = state
- if bulkQueue.IsEmpty then
- let prev = match treeMap.TryFind key with None -> [] | Some vs -> vs
- let treeMap = treeMap.Add (key, value::prev)
- LayeredMultiMap(bulkQueue, treeMap, fastDict)
- else
- // There are elements in the bulk queue, squash them down (mutating map "x"),
- // then use a one-element treemap
- let newFastDict = tryCollapseToDictAndNothingElse false
- match newFastDict with
- | null -> failwith "unreachable, bulkQueue was non empty, newFastDict should not be null"
- | _ -> LayeredMultiMap([], Map.empty.Add(key,[value]), newFastDict)
-
- member x.AddAndMarkAsCollapsible (kvs: _[]) =
- if kvs.Length = 0 then x else
- let (bulkQueue,treeMap,fastDict) = state
- let state = (kvs::bulkQueue,treeMap,fastDict)
- LayeredMultiMap state
-
- member x.MarkAsCollapsible () = //x.AddAndMarkAsCollapsible [| |]
- let (bulkQueue,treeMap,fastDict) = state
- let state = ([| |]::bulkQueue,treeMap,fastDict)
- LayeredMultiMap state
-
-//#endif
-
-#if NO_LAYERED_MAP
type LayeredMap<'Key,'Value when 'Key : comparison> = Map<'Key,'Value>
type Map<'Key,'Value when 'Key : comparison> with
@@ -1358,28 +935,20 @@ type Map<'Key,'Value when 'Key : comparison> with
member x.Elements = [ for kvp in x -> kvp ]
member x.AddAndMarkAsCollapsible (kvs: _[]) = (x,kvs) ||> Array.fold (fun x (KeyValue(k,v)) -> x.Add(k,v))
member x.LinearTryModifyThenLaterFlatten (key, f: 'Value option -> 'Value) = x.Add (key, f (x.TryFind key))
-
member x.MarkAsCollapsible () = x
-//#endif
-
-
-//#if NO_LAYERED_MULTI_MAP
/// Immutable map collection, with explicit flattening to a backing dictionary
[]
-type LayeredMultiMap<'Key,'Value when 'Key : equality and 'Key : comparison>(contents : Map<'Key,'Value list>) =
- static let empty : LayeredMultiMap<'Key,'Value> = LayeredMultiMap Map.empty
+type LayeredMultiMap<'Key,'Value when 'Key : equality and 'Key : comparison>(contents : LayeredMap<'Key,'Value list>) =
member x.Add (k,v) = LayeredMultiMap(contents.Add(k,v :: x.[k]))
member x.Item with get k = match contents.TryFind k with None -> [] | Some l -> l
member x.AddAndMarkAsCollapsible (kvs: _[]) =
let x = (x,kvs) ||> Array.fold (fun x (KeyValue(k,v)) -> x.Add(k,v))
x.MarkAsCollapsible()
- member x.MarkAsCollapsible() = x //LayeredMultiMap(contents)
+ member x.MarkAsCollapsible() = LayeredMultiMap(contents.MarkAsCollapsible())
member x.TryFind k = contents.TryFind k
- member x.Values = [ for (KeyValue(_,v)) in contents -> v ] |> Seq.concat
- static member Empty : LayeredMultiMap<'Key,'Value> = empty
-
-#endif
+ member x.Values = contents.Values |> Seq.concat
+ static member Empty : LayeredMultiMap<'Key,'Value> = LayeredMultiMap LayeredMap.Empty
[]
module Shim =
@@ -1431,7 +1000,12 @@ module Shim =
with e ->
this.AssemblyLoadFrom(assemblyName.Name + ".dll")
#else
- default this.AssemblyLoadFrom(fileName:string) = System.Reflection.Assembly.LoadFrom fileName
+ default this.AssemblyLoadFrom(fileName:string) =
+#if FX_ATLEAST_40_COMPILER_LOCATION
+ System.Reflection.Assembly.UnsafeLoadFrom fileName
+#else
+ System.Reflection.Assembly.LoadFrom fileName
+#endif
default this.AssemblyLoad(assemblyName:System.Reflection.AssemblyName) = System.Reflection.Assembly.Load assemblyName
#endif
diff --git a/src/absil/ilpars.fsy b/src/absil/ilpars.fsy
index 71545cc2e0..934a686a11 100755
--- a/src/absil/ilpars.fsy
+++ b/src/absil/ilpars.fsy
@@ -61,13 +61,14 @@ let resolveCurrentMethodSpecScope obj =
resolveMethodSpecScope obj mkILEmptyGenericParams
-let findMscorlibAssemblyRef() =
- match (!parseILGlobals).mscorlibScopeRef with
+let findSystemRuntimeAssemblyRef() =
+ match (!parseILGlobals).traits.ScopeRef with
| ILScopeRef.Assembly aref -> aref
- | _ -> pfailwith "mscorlibScopeRef not set to valid assembly reference in parseILGlobals"
+ | _ -> pfailwith "systemRuntimeScopeRef not set to valid assembly reference in parseILGlobals"
let findAssemblyRef nm =
- if nm = "mscorlib" then findMscorlibAssemblyRef() else
+ if nm = "mscorlib" then findSystemRuntimeAssemblyRef()
+ else
pfailwith ("Undefined assembly ref '" + nm + "'")
%}
diff --git a/src/absil/ilprint.fs b/src/absil/ilprint.fs
index 0f009582d9..fdc64db944 100755
--- a/src/absil/ilprint.fs
+++ b/src/absil/ilprint.fs
@@ -177,21 +177,21 @@ and goutput_typ env os ty =
| ILType.Byref typ -> goutput_typ env os typ; output_string os "&"
| ILType.Ptr typ -> goutput_typ env os typ; output_string os "*"
- | ILType.Value tspec when tspec.Name = ecmaILGlobals.tspec_SByte.Name -> output_string os "int8"
- | ILType.Value tspec when tspec.Name = ecmaILGlobals.tspec_Int16.Name -> output_string os "int16"
- | ILType.Value tspec when tspec.Name = ecmaILGlobals.tspec_Int32.Name -> output_string os "int32"
- | ILType.Value tspec when tspec.Name = ecmaILGlobals.tspec_Int64.Name -> output_string os "int64"
- | ILType.Value tspec when tspec.Name = ecmaILGlobals.tspec_IntPtr.Name -> output_string os "native int"
- | ILType.Value tspec when tspec.Name = ecmaILGlobals.tspec_Byte.Name -> output_string os "unsigned int8"
- | ILType.Value tspec when tspec.Name = ecmaILGlobals.tspec_UInt16.Name -> output_string os "unsigned int16"
- | ILType.Value tspec when tspec.Name = ecmaILGlobals.tspec_UInt32.Name -> output_string os "unsigned int32"
- | ILType.Value tspec when tspec.Name = ecmaILGlobals.tspec_UInt64.Name -> output_string os "unsigned int64"
- | ILType.Value tspec when tspec.Name = ecmaILGlobals.tspec_UIntPtr.Name -> output_string os "native unsigned int"
- | ILType.Value tspec when tspec.Name = ecmaILGlobals.tspec_Double.Name -> output_string os "float64"
- | ILType.Value tspec when tspec.Name = ecmaILGlobals.tspec_Single.Name -> output_string os "float32"
- | ILType.Value tspec when tspec.Name = ecmaILGlobals.tspec_Bool.Name -> output_string os "bool"
- | ILType.Value tspec when tspec.Name = ecmaILGlobals.tspec_Char.Name -> output_string os "char"
- | ILType.Value tspec when tspec.Name = ecmaILGlobals.tspec_TypedReference.Name -> output_string os "refany"
+ | ILType.Value tspec when tspec.Name = EcmaILGlobals.tspec_SByte.Name -> output_string os "int8"
+ | ILType.Value tspec when tspec.Name = EcmaILGlobals.tspec_Int16.Name -> output_string os "int16"
+ | ILType.Value tspec when tspec.Name = EcmaILGlobals.tspec_Int32.Name -> output_string os "int32"
+ | ILType.Value tspec when tspec.Name = EcmaILGlobals.tspec_Int64.Name -> output_string os "int64"
+ | ILType.Value tspec when tspec.Name = EcmaILGlobals.tspec_IntPtr.Name -> output_string os "native int"
+ | ILType.Value tspec when tspec.Name = EcmaILGlobals.tspec_Byte.Name -> output_string os "unsigned int8"
+ | ILType.Value tspec when tspec.Name = EcmaILGlobals.tspec_UInt16.Name -> output_string os "unsigned int16"
+ | ILType.Value tspec when tspec.Name = EcmaILGlobals.tspec_UInt32.Name -> output_string os "unsigned int32"
+ | ILType.Value tspec when tspec.Name = EcmaILGlobals.tspec_UInt64.Name -> output_string os "unsigned int64"
+ | ILType.Value tspec when tspec.Name = EcmaILGlobals.tspec_UIntPtr.Name -> output_string os "native unsigned int"
+ | ILType.Value tspec when tspec.Name = EcmaILGlobals.tspec_Double.Name -> output_string os "float64"
+ | ILType.Value tspec when tspec.Name = EcmaILGlobals.tspec_Single.Name -> output_string os "float32"
+ | ILType.Value tspec when tspec.Name = EcmaILGlobals.tspec_Bool.Name -> output_string os "bool"
+ | ILType.Value tspec when tspec.Name = EcmaILGlobals.tspec_Char.Name -> output_string os "char"
+ | ILType.Value tspec when tspec.Name = EcmaILGlobals.tspec_TypedReference.Value.Name -> output_string os "refany"
| ILType.Value tspec ->
output_string os "value class ";
goutput_tref env os tspec.TypeRef;
@@ -715,7 +715,7 @@ let rec goutput_instr env os inst =
goutput_dlocref env os (mkILArrTy(typ,shape));
output_string os ".ctor";
let rank = shape.Rank
- output_parens (output_seq "," (goutput_typ env)) os (Array.toList (Array.create ( rank) ecmaILGlobals.typ_int32))
+ output_parens (output_seq "," (goutput_typ env)) os (Array.toList (Array.create ( rank) EcmaILGlobals.typ_int32))
| I_stelem_any (shape,dt) ->
if shape = ILArrayShape.SingleDimensional then
output_string os "stelem.any "; goutput_typ env os dt
@@ -724,7 +724,7 @@ let rec goutput_instr env os inst =
goutput_dlocref env os (mkILArrTy(dt,shape));
output_string os "Set";
let rank = shape.Rank
- output_parens (output_seq "," (goutput_typ env)) os (Array.toList (Array.create ( rank) ecmaILGlobals.typ_int32) @ [dt])
+ output_parens (output_seq "," (goutput_typ env)) os (Array.toList (Array.create ( rank) EcmaILGlobals.typ_int32) @ [dt])
| I_ldelem_any (shape,tok) ->
if shape = ILArrayShape.SingleDimensional then
output_string os "ldelem.any "; goutput_typ env os tok
@@ -735,7 +735,7 @@ let rec goutput_instr env os inst =
goutput_dlocref env os (mkILArrTy(tok,shape));
output_string os "Get";
let rank = shape.Rank
- output_parens (output_seq "," (goutput_typ env)) os (Array.toList (Array.create ( rank) ecmaILGlobals.typ_int32))
+ output_parens (output_seq "," (goutput_typ env)) os (Array.toList (Array.create ( rank) EcmaILGlobals.typ_int32))
| I_ldelema (ro,_,shape,tok) ->
if ro = ReadonlyAddress then output_string os "readonly. ";
if shape = ILArrayShape.SingleDimensional then
@@ -747,7 +747,7 @@ let rec goutput_instr env os inst =
goutput_dlocref env os (mkILArrTy(tok,shape));
output_string os "Address";
let rank = shape.Rank
- output_parens (output_seq "," (goutput_typ env)) os (Array.toList (Array.create ( rank) ecmaILGlobals.typ_int32))
+ output_parens (output_seq "," (goutput_typ env)) os (Array.toList (Array.create ( rank) EcmaILGlobals.typ_int32))
| I_box tok -> output_string os "box "; goutput_typ env os tok
| I_unbox tok -> output_string os "unbox "; goutput_typ env os tok
@@ -1216,7 +1216,6 @@ let output_module_fragment_aux _refs os modul =
with e ->
output_string os "*** Error during printing : "; output_string os (e.ToString()); os.Flush();
reraise()
- raise e
let output_module_fragment os modul =
let refs = computeILRefs modul
diff --git a/src/absil/ilread.fs b/src/absil/ilread.fs
index 01ca3b5067..bd4035fb00 100755
--- a/src/absil/ilread.fs
+++ b/src/absil/ilread.fs
@@ -26,7 +26,10 @@ open System.Collections.Generic
open Internal.Utilities
open Microsoft.FSharp.Compiler.AbstractIL
open Microsoft.FSharp.Compiler.AbstractIL.Internal
+#if NO_PDB_READER
+#else
open Microsoft.FSharp.Compiler.AbstractIL.Internal.Support
+#endif
open Microsoft.FSharp.Compiler.AbstractIL.Diagnostics
open Microsoft.FSharp.Compiler.AbstractIL.Internal.BinaryConstants
open Microsoft.FSharp.Compiler.AbstractIL.IL
@@ -2175,7 +2178,10 @@ and sigptrGetTy ctxt numtypars bytes sigptr =
mkILArrTy (typ, shape), sigptr
elif b0 = et_VOID then ILType.Void, sigptr
- elif b0 = et_TYPEDBYREF then ctxt.ilg.typ_TypedReference, sigptr
+ elif b0 = et_TYPEDBYREF then
+ match ctxt.ilg.typ_TypedReference with
+ | Some t -> t, sigptr
+ | _ -> failwith "system runtime doesn't contain System.TypedReference"
elif b0 = et_CMOD_REQD || b0 = et_CMOD_OPT then
let tdorIdx, sigptr = sigptrGetTypeDefOrRefOrSpecIdx bytes sigptr
let typ, sigptr = sigptrGetTy ctxt numtypars bytes sigptr
@@ -4076,10 +4082,10 @@ let rec genOpenBinaryReader infile is opts =
let CloseILModuleReader x = x.dispose()
-let defaults =
+let mkDefault ilg =
{ optimizeForMemory=false;
pdbPath= None;
- ilGlobals=ecmaILGlobals }
+ ilGlobals = ilg }
#if NO_PDB_READER
let ClosePdbReader _x = ()
diff --git a/src/absil/ilread.fsi b/src/absil/ilread.fsi
index 55969dbfbe..c459e18e0d 100755
--- a/src/absil/ilread.fsi
+++ b/src/absil/ilread.fsi
@@ -48,7 +48,7 @@ type ILReaderOptions =
ilGlobals: ILGlobals;
optimizeForMemory: bool (* normally off, i.e. optimize for startup-path speed *) }
-val defaults : ILReaderOptions
+val mkDefault : ILGlobals -> ILReaderOptions
// The non-memory resources (i.e. the file handle) associated with
// the read can be recovered by calling CloseILModuleReader. Any reamining
diff --git a/src/absil/ilreflect.fs b/src/absil/ilreflect.fs
index 28aeaa2541..e496c47b6e 100755
--- a/src/absil/ilreflect.fs
+++ b/src/absil/ilreflect.fs
@@ -414,7 +414,8 @@ type emEnv =
emLocals : LocalBuilder[];
emLabels : Zmap;
emTyvars : Type[] list; // stack
- emEntryPts : (TypeBuilder * string) list }
+ emEntryPts : (TypeBuilder * string) list
+ delayedFieldInits : (unit -> unit) list}
let orderILTypeRef = ComparisonIdentity.Structural
let orderILMethodRef = ComparisonIdentity.Structural
@@ -430,7 +431,8 @@ let emEnv0 =
emLocals = [| |];
emLabels = Zmap.empty codeLabelOrder;
emTyvars = [];
- emEntryPts = []; }
+ emEntryPts = []
+ delayedFieldInits = [] }
let envBindTypeRef emEnv (tref:ILTypeRef) (typT,typB,typeDef)=
match typT with
@@ -581,8 +583,10 @@ and convTypeAux cenv emEnv preferCreated typ =
baseT.MakeByRefType() |> nonNull "convType: byref"
| ILType.TypeVar tv -> envGetTyvar emEnv tv |> nonNull "convType: tyvar"
// XXX: REVIEW: complete the following cases.
+ | ILType.Modified (false, _, modifiedTy) -> convTypeAux cenv emEnv preferCreated modifiedTy
+ | ILType.Modified (true, _, _) -> failwith "convType: modreq"
| ILType.FunctionPointer _callsig -> failwith "convType: fptr"
- | ILType.Modified _ -> failwith "convType: modified"
+
// [Bug 4063].
// The convType functions convert AbsIL types into concrete Type values.
@@ -926,6 +930,8 @@ let emitInstrCall cenv emEnv (ilG:ILGenerator) opCall tail (mspec:ILMethodSpec)
else
let minfo = convMethodSpec cenv emEnv mspec
#if SILVERLIGHT
+ // When generating code for silverlight, we intercept direct
+ // calls to System.Console.WriteLine.
let fullName = minfo.DeclaringType.FullName + "." + minfo.Name
let minfo =
if fullName = "System.Console.WriteLine" || fullName = "System.Console.Write" then
@@ -1660,7 +1666,23 @@ let buildFieldPass2 cenv tref (typB:TypeBuilder) emEnv (fdef : ILFieldDef) =
typB.DefineFieldAndLog(fdef.Name,fieldT,attrs)
// set default value
- fdef.LiteralValue |> Option.iter (fun initial -> fieldB.SetConstant(convFieldInit initial));
+ let emEnv =
+ match fdef.LiteralValue with
+ | None -> emEnv
+ | Some initial ->
+ if not fieldT.IsEnum
+#if FX_ATLEAST_45
+ || not fieldT.Assembly.IsDynamic // it is ok to init fields with type = enum that are defined in other assemblies
+#endif
+ then
+ fieldB.SetConstant(convFieldInit initial)
+ emEnv
+ else
+ // if field type (enum) is defined in FSI dynamic assembly it is created as nested type
+ // => its underlying type cannot be explicitly specified and will be inferred at the very moment of first field definition
+ // => here we cannot detect if underlying type is already set so as a conservative solution we delay initialization of fields
+ // to the end of pass2 (types and members are already created but method bodies are yet not emitted)
+ { emEnv with delayedFieldInits = (fun() -> fieldB.SetConstant(convFieldInit initial))::emEnv.delayedFieldInits }
#if FX_ATLEAST_SILVERLIGHT_50
#else
fdef.Offset |> Option.iter (fun offset -> fieldB.SetOffset(offset));
@@ -1768,8 +1790,8 @@ let typeAttributesOfTypeLayout cenv emEnv x =
else
Some(convCustomAttr cenv emEnv
(IL.mkILCustomAttribute cenv.ilg
- (mkILTyRef (cenv.ilg.mscorlibScopeRef,"System.Runtime.InteropServices.StructLayoutAttribute"),
- [mkILNonGenericValueTy (mkILTyRef (cenv.ilg.mscorlibScopeRef,"System.Runtime.InteropServices.LayoutKind")) ],
+ (mkILTyRef (cenv.ilg.traits.ScopeRef,"System.Runtime.InteropServices.StructLayoutAttribute"),
+ [mkILNonGenericValueTy (mkILTyRef (cenv.ilg.traits.ScopeRef,"System.Runtime.InteropServices.LayoutKind")) ],
[ ILAttribElem.Int32 0x02 ],
(p.Pack |> Option.toList |> List.map (fun x -> ("Pack", cenv.ilg.typ_int32, false, ILAttribElem.Int32 (int32 x)))) @
(p.Size |> Option.toList |> List.map (fun x -> ("Size", cenv.ilg.typ_int32, false, ILAttribElem.Int32 x)))))) in
@@ -2031,6 +2053,12 @@ let buildModuleFragment cenv emEnv (asmB : AssemblyBuilder) (modB : ModuleBuilde
let emEnv = List.fold (buildModuleTypePass1 cenv modB) emEnv tdefs
tdefs |> List.iter (buildModuleTypePass1b cenv emEnv)
let emEnv = List.fold (buildModuleTypePass2 cenv) emEnv tdefs
+
+ for delayedFieldInit in emEnv.delayedFieldInits do
+ delayedFieldInit()
+
+ let emEnv = { emEnv with delayedFieldInits = [] }
+
let emEnv = List.fold (buildModuleTypePass3 cenv modB) emEnv tdefs
let visited = new Dictionary<_,_>(10)
let created = new Dictionary<_,_>(10)
@@ -2060,7 +2088,7 @@ let mkDynamicAssemblyAndModule (assemblyName, optimize, debugInfo) =
let filename = assemblyName ^ ".dll"
let currentDom = System.AppDomain.CurrentDomain
#if SILVERLIGHT
- let _asmDir = if optimize then "." else "." // TODO: factor out optimize
+ ignore optimize
let asmName = new AssemblyName()
asmName.Name <- assemblyName;
let asmB = currentDom.DefineDynamicAssembly(asmName,AssemblyBuilderAccess.Run)
@@ -2136,4 +2164,3 @@ let LookupType cenv emEnv typ = convCreatedType cenv emEnv typ
let LookupFieldRef emEnv fref = Zmap.tryFind fref emEnv.emFieldMap |> Option.map (fun fieldBuilder -> fieldBuilder :> FieldInfo)
let LookupMethodRef emEnv mref = Zmap.tryFind mref emEnv.emMethMap |> Option.map (fun methodBuilder -> methodBuilder :> MethodInfo)
-
diff --git a/src/absil/ilsupp.fs b/src/absil/ilsupp.fs
index c809a74546..d3870f3970 100755
--- a/src/absil/ilsupp.fs
+++ b/src/absil/ilsupp.fs
@@ -53,9 +53,9 @@ let check _action (hresult) =
// of the debug symbols file. This function takes output file name and returns debug file name.
let getDebugFileName outfile =
if IL.runningOnMono then
- outfile^".mdb"
+ outfile+".mdb"
else
- (Filename.chopExtension outfile)^".pdb"
+ (Filename.chopExtension outfile)+".pdb"
type PEFileType = X86 | X64
@@ -897,8 +897,8 @@ type IMetadataEmit =
[< Guid("B01FAFEB-C450-3A4D-BEEC-B4CEEC01E006") ; InterfaceType(ComInterfaceType.InterfaceIsIUnknown) >]
[< ComVisible(false) >]
type ISymUnmanagedDocumentWriter =
- abstract SetSource : sourceSize : int * source : byte[] -> unit
- abstract SetCheckSum : algorithmId : System.Guid * checkSumSize : int * checkSum : byte [] -> unit
+ abstract SetSource : sourceSize : int * [] source : byte[] -> unit
+ abstract SetCheckSum : algorithmId : System.Guid * checkSumSize : int * [] checkSum : byte [] -> unit
// Struct used to retrieve info on the debug output
[]
@@ -1023,7 +1023,6 @@ type ISymUnmanagedWriter2 =
isect : int *
offset : int -> unit
-
type PdbWriter = { symWriter : ISymUnmanagedWriter2 }
type PdbDocumentWriter = { symDocWriter : ISymUnmanagedDocumentWriter } (* pointer to pDocumentWriter COM object *)
@@ -1071,7 +1070,6 @@ let pdbClose (writer:PdbWriter) =
// The SymReader class gets around this problem by implementing the ISymUnmanagedDispose
// interface, which the SymWriter class, unfortunately, does not.
// Right now, take the same approach as mdbg, and manually forcing a collection.
-
let rc = Marshal.ReleaseComObject(writer.symWriter)
for i = 0 to (rc - 1) do
Marshal.ReleaseComObject(writer.symWriter) |> ignore
@@ -1091,6 +1089,23 @@ let pdbClose (writer:PdbWriter) =
let pdbSetUserEntryPoint (writer:PdbWriter) (entryMethodToken:int32) =
writer.symWriter.SetUserEntryPoint((uint32)entryMethodToken)
+// Document checksum algorithms
+
+let guidSourceHashMD5 = System.Guid(0x406ea660u, 0x64cfus, 0x4c82us, 0xb6uy, 0xf0uy, 0x42uy, 0xd4uy, 0x81uy, 0x72uy, 0xa7uy, 0x99uy) //406ea660-64cf-4c82-b6f0-42d48172a799
+let hashSizeOfMD5 = 16
+
+// If the FIPS algorithm policy is enabled on the computer (e.g., for US government employees and contractors)
+// then obtaining the MD5 implementation in BCL will throw.
+// In this case, catch the failure, and not set a checksum.
+let internal setCheckSum (url:string, writer:ISymUnmanagedDocumentWriter) =
+ try
+ use file = new FileStream(url, FileMode.Open, FileAccess.Read, FileShare.Read)
+ use md5 = System.Security.Cryptography.MD5.Create()
+ let checkSum = md5.ComputeHash(file)
+ if (checkSum.Length = hashSizeOfMD5) then
+ writer.SetCheckSum (guidSourceHashMD5, hashSizeOfMD5, checkSum)
+ with _ -> ()
+
let pdbDefineDocument (writer:PdbWriter) (url:string) =
//3F5162F8-07C6-11D3-9053-00C04FA302A1
//let mutable corSymLanguageTypeCSharp = System.Guid(0x3F5162F8u, 0x07C6us, 0x11D3us, 0x90uy, 0x53uy, 0x00uy, 0xC0uy, 0x4Fuy, 0xA3uy, 0x02uy, 0xA1uy)
@@ -1099,6 +1114,7 @@ let pdbDefineDocument (writer:PdbWriter) (url:string) =
let mutable corSymDocumentTypeText = System.Guid(0x5a869d0bu, 0x6611us, 0x11d3us, 0xbduy, 0x2auy, 0x0uy, 0x0uy, 0xf8uy, 0x8uy, 0x49uy, 0xbduy)
let mutable docWriter = Unchecked.defaultof
writer.symWriter.DefineDocument(url, &corSymLanguageTypeFSharp, &corSymLanguageVendorMicrosoft, &corSymDocumentTypeText, &docWriter)
+ setCheckSum (url, docWriter)
{ symDocWriter = docWriter }
let pdbOpenMethod (writer:PdbWriter) (methodToken:int32) =
diff --git a/src/absil/ilwrite.fs b/src/absil/ilwrite.fs
index 4ec4ebe1a1..1046cf5651 100755
--- a/src/absil/ilwrite.fs
+++ b/src/absil/ilwrite.fs
@@ -910,7 +910,7 @@ type TypeDefTableKey = TdKey of string list (* enclosing *) * string (* type nam
[]
type cenv =
- { mscorlib: ILScopeRef;
+ { primaryAssembly: ILScopeRef;
ilg: ILGlobals;
emitTailcalls: bool;
showTimes: bool;
@@ -1583,8 +1583,6 @@ and GenTypeDefPass2 pidx enc cenv (td:ILTypeDef) =
td.NestedTypes.AsList |> GenTypeDefsPass2 tidx (enc@[td.Name]) cenv
with e ->
failwith ("Error in pass2 for type "+td.Name+", error: "+e.Message);
- reraise()
- raise e
and GenTypeDefsPass2 pidx enc cenv tds =
List.iter (GenTypeDefPass2 pidx enc cenv) tds
@@ -1642,17 +1640,15 @@ and GetFieldDefAsFieldDefIdx cenv tidx fd =
// --------------------------------------------------------------------
let GetMethodRefAsMethodDefIdx cenv (mref:ILMethodRef) =
+ let tref = mref.EnclosingTypeRef
try
- let tref = mref.EnclosingTypeRef
if not (isTypeRefLocal tref) then
failwithf "method referred to by method impl, event or property is not in a type defined in this module, method ref is %A" mref;
let tidx = GetIdxForTypeDef cenv (TdKey(tref.Enclosing,tref.Name))
let mdkey = MethodDefKey (tidx,mref.GenericArity, mref.Name, mref.ReturnType, mref.ArgTypes, mref.CallingConv.IsStatic)
FindMethodDefIdx cenv mdkey
with e ->
- failwithf "Error in GetMethodRefAsMethodDefIdx for mref = %A, error: %s" mref.Name e.Message;
- reraise()
- raise e
+ failwithf "Error in GetMethodRefAsMethodDefIdx for mref = %A, error: %s" (mref.Name, tref.Name) e.Message;
let rec MethodRefInfoAsMemberRefRow cenv env fenv (nm,typ,callconv,args,ret,varargs,genarity) =
MemberRefRow(GetTypeAsMemberRefParent cenv env typ,
@@ -1794,11 +1790,11 @@ and GetCustomAttrRow cenv hca attr =
CustomAttributeType (fst cat, snd cat);
Blob (GetCustomAttrDataAsBlobIdx cenv attr.Data); |]
-and GenCustomAttrPass3 cenv hca attr =
+and GenCustomAttrPass3Or4 cenv hca attr =
AddUnsharedRow cenv TableNames.CustomAttribute (GetCustomAttrRow cenv hca attr) |> ignore
-and GenCustomAttrsPass3 cenv hca (attrs: ILAttributes) =
- attrs.AsList |> List.iter (GenCustomAttrPass3 cenv hca)
+and GenCustomAttrsPass3Or4 cenv hca (attrs: ILAttributes) =
+ attrs.AsList |> List.iter (GenCustomAttrPass3Or4 cenv hca)
// --------------------------------------------------------------------
// ILPermissionSet --> DeclSecurity rows
@@ -2763,7 +2759,7 @@ and GetFieldDefSigAsBlobIdx cenv env fd = GetFieldDefTypeAsBlobIdx cenv env fd.T
and GenFieldDefPass3 cenv env fd =
let fidx = AddUnsharedRow cenv TableNames.Field (GetFieldDefAsFieldDefRow cenv env fd)
- GenCustomAttrsPass3 cenv (hca_FieldDef,fidx) fd.CustomAttrs;
+ GenCustomAttrsPass3Or4 cenv (hca_FieldDef,fidx) fd.CustomAttrs;
// Write FieldRVA table - fixups into data section done later
match fd.Data with
| None -> ()
@@ -2836,12 +2832,15 @@ and GenGenericParamConstraintPass4 cenv env gpidx ty =
AddUnsharedRow cenv TableNames.GenericParamConstraint (GenTypeAsGenericParamConstraintRow cenv env gpidx ty) |> ignore
and GenGenericParamPass3 cenv env idx owner gp =
+ // here we just collect generic params, its constraints\custom attributes will be processed on pass4
// shared since we look it up again below in GenGenericParamPass4
- let gpidx = AddSharedRow cenv TableNames.GenericParam (GetGenericParamAsGenericParamRow cenv env idx owner gp)
- GenCustomAttrsPass3 cenv (hca_GenericParam,gpidx) gp.CustomAttrs;
+ AddSharedRow cenv TableNames.GenericParam (GetGenericParamAsGenericParamRow cenv env idx owner gp)
+ |> ignore
+
and GenGenericParamPass4 cenv env idx owner gp =
let gpidx = FindOrAddRow cenv TableNames.GenericParam (GetGenericParamAsGenericParamRow cenv env idx owner gp)
+ GenCustomAttrsPass3Or4 cenv (hca_GenericParam, gpidx) gp.CustomAttrs
gp.Constraints |> ILList.iter (GenGenericParamConstraintPass4 cenv env gpidx)
// --------------------------------------------------------------------
@@ -2866,7 +2865,7 @@ and GenParamPass3 cenv env seq param =
then ()
else
let pidx = AddUnsharedRow cenv TableNames.Param (GetParamAsParamRow cenv env seq param)
- GenCustomAttrsPass3 cenv (hca_ParamDef,pidx) param.CustomAttrs;
+ GenCustomAttrsPass3Or4 cenv (hca_ParamDef,pidx) param.CustomAttrs;
// Write FieldRVA table - fixups into data section done later
match param.Marshal with
| None -> ()
@@ -2885,7 +2884,7 @@ let GenReturnAsParamRow (returnv : ILReturn) =
let GenReturnPass3 cenv (returnv: ILReturn) =
if isSome returnv.Marshal || nonNil returnv.CustomAttrs.AsList then
let pidx = AddUnsharedRow cenv TableNames.Param (GenReturnAsParamRow returnv)
- GenCustomAttrsPass3 cenv (hca_ParamDef,pidx) returnv.CustomAttrs;
+ GenCustomAttrsPass3Or4 cenv (hca_ParamDef,pidx) returnv.CustomAttrs;
match returnv.Marshal with
| None -> ()
| Some ntyp ->
@@ -3003,7 +3002,7 @@ let GenMethodDefPass3 cenv env (md:ILMethodDef) =
if midx <> idx2 then failwith "index of method def on pass 3 does not match index on pass 2";
GenReturnPass3 cenv md.Return;
md.Parameters |> ILList.iteri (fun n param -> GenParamPass3 cenv env (n+1) param) ;
- md.CustomAttrs |> GenCustomAttrsPass3 cenv (hca_MethodDef,midx) ;
+ md.CustomAttrs |> GenCustomAttrsPass3Or4 cenv (hca_MethodDef,midx) ;
md.SecurityDecls.AsList |> GenSecurityDeclsPass3 cenv (hds_MethodDef,midx);
md.GenericParams |> List.iteri (fun n gp -> GenGenericParamPass3 cenv env n (tomd_MethodDef, midx) gp) ;
match md.mdBody.Contents with
@@ -3091,7 +3090,7 @@ and GenPropertyPass3 cenv env prop =
[| GetFieldInitFlags i;
HasConstant (hc_Property, pidx);
Blob (GetFieldInitAsBlobIdx cenv i) |]) |> ignore
- GenCustomAttrsPass3 cenv (hca_Property,pidx) prop.CustomAttrs
+ GenCustomAttrsPass3Or4 cenv (hca_Property,pidx) prop.CustomAttrs
let rec GenEventMethodSemanticsPass3 cenv eidx kind mref =
let addIdx = try GetMethodRefAsMethodDefIdx cenv mref with MethodDefNotFound -> 1
@@ -3118,7 +3117,7 @@ and GenEventPass3 cenv env (md: ILEventDef) =
md.RemoveMethod |> GenEventMethodSemanticsPass3 cenv eidx 0x0010
Option.iter (GenEventMethodSemanticsPass3 cenv eidx 0x0020) md.FireMethod
List.iter (GenEventMethodSemanticsPass3 cenv eidx 0x0004) md.OtherMethods;
- GenCustomAttrsPass3 cenv (hca_Event,eidx) md.CustomAttrs
+ GenCustomAttrsPass3Or4 cenv (hca_Event,eidx) md.CustomAttrs
// --------------------------------------------------------------------
@@ -3150,7 +3149,7 @@ let rec GetResourceAsManifestResourceRow cenv r =
and GenResourcePass3 cenv r =
let idx = AddUnsharedRow cenv TableNames.ManifestResource (GetResourceAsManifestResourceRow cenv r)
- GenCustomAttrsPass3 cenv (hca_ManifestResource,idx) r.CustomAttrs
+ GenCustomAttrsPass3Or4 cenv (hca_ManifestResource,idx) r.CustomAttrs
// --------------------------------------------------------------------
// ILTypeDef --> generate ILFieldDef, ILMethodDef, ILPropertyDef etc. rows
@@ -3177,7 +3176,7 @@ let rec GenTypeDefPass3 enc cenv (td:ILTypeDef) =
SimpleIndex (TableNames.TypeDef, tidx) |]) |> ignore
td.SecurityDecls.AsList |> GenSecurityDeclsPass3 cenv (hds_TypeDef,tidx);
- td.CustomAttrs |> GenCustomAttrsPass3 cenv (hca_TypeDef,tidx);
+ td.CustomAttrs |> GenCustomAttrsPass3Or4 cenv (hca_TypeDef,tidx);
td.GenericParams |> List.iteri (fun n gp -> GenGenericParamPass3 cenv env n (tomd_TypeDef,tidx) gp) ;
td.NestedTypes.AsList |> GenTypeDefsPass3 (enc@[td.Name]) cenv;
with e ->
@@ -3220,7 +3219,7 @@ let rec GenNestedExportedTypePass3 cenv cidx (ce: ILNestedExportedType) =
StringE (GetStringHeapIdx cenv ce.Name);
StringE 0;
Implementation (i_ExportedType, cidx) |])
- GenCustomAttrsPass3 cenv (hca_ExportedType,nidx) ce.CustomAttrs;
+ GenCustomAttrsPass3Or4 cenv (hca_ExportedType,nidx) ce.CustomAttrs;
GenNestedExportedTypesPass3 cenv nidx ce.Nested
and GenNestedExportedTypesPass3 cenv nidx (nce: ILNestedExportedTypes) =
@@ -3239,7 +3238,7 @@ and GenExportedTypePass3 cenv (ce: ILExportedTypeOrForwarder) =
nelem;
nselem;
Implementation (fst impl, snd impl); |])
- GenCustomAttrsPass3 cenv (hca_ExportedType,cidx) ce.CustomAttrs;
+ GenCustomAttrsPass3Or4 cenv (hca_ExportedType,cidx) ce.CustomAttrs;
GenNestedExportedTypesPass3 cenv cidx ce.Nested
and GenExportedTypesPass3 cenv (ce: ILExportedTypesAndForwarders) =
@@ -3278,7 +3277,7 @@ and GetManifsetAsAssemblyRow cenv m =
and GenManifestPass3 cenv m =
let aidx = AddUnsharedRow cenv TableNames.Assembly (GetManifsetAsAssemblyRow cenv m)
GenSecurityDeclsPass3 cenv (hds_Assembly,aidx) m.SecurityDecls.AsList;
- GenCustomAttrsPass3 cenv (hca_Assembly,aidx) m.CustomAttrs;
+ GenCustomAttrsPass3Or4 cenv (hca_Assembly,aidx) m.CustomAttrs;
GenExportedTypesPass3 cenv m.ExportedTypes;
// Record the entrypoint decl if needed.
match m.EntrypointElsewhere with
@@ -3335,23 +3334,23 @@ let GenModule (cenv : cenv) (modul: ILModuleDef) =
(match modul.Manifest with None -> () | Some m -> GenManifestPass3 cenv m);
GenTypeDefsPass3 [] cenv tds;
reportTime cenv.showTimes "Module Generation Pass 3";
- GenCustomAttrsPass3 cenv (hca_Module,midx) modul.CustomAttrs;
- // GenericParam is the only sorted table indexed by Columns in other tables (GenericParamConstraint).
- // Hence we need to sort it before we emit any entries in GenericParamConstraint.
+ GenCustomAttrsPass3Or4 cenv (hca_Module,midx) modul.CustomAttrs;
+ // GenericParam is the only sorted table indexed by Columns in other tables (GenericParamConstraint\CustomAttributes).
+ // Hence we need to sort it before we emit any entries in GenericParamConstraint\CustomAttributes that are attached to generic params.
// Note this mutates the rows in a table. 'SetRowsOfTable' clears
// the key --> index map since it is no longer valid
cenv.GetTable(TableNames.GenericParam).SetRowsOfTable (SortTableRows TableNames.GenericParam (cenv.GetTable(TableNames.GenericParam).EntriesAsArray));
GenTypeDefsPass4 [] cenv tds;
reportTime cenv.showTimes "Module Generation Pass 4"
-let generateIL requiredDataFixups (desiredMetadataVersion,generatePdb,mscorlib,emitTailcalls,showTimes) (m : ILModuleDef) noDebugData cilStartAddress =
+let generateIL requiredDataFixups (desiredMetadataVersion,generatePdb, ilg : ILGlobals, emitTailcalls,showTimes) (m : ILModuleDef) noDebugData cilStartAddress =
let isDll = m.IsDLL
let cenv =
- { mscorlib=mscorlib;
+ { primaryAssembly=ilg.traits.ScopeRef;
emitTailcalls=emitTailcalls;
showTimes=showTimes;
- ilg = mkILGlobals mscorlib None noDebugData; // assumes mscorlib is Scope_assembly _ ILScopeRef
+ ilg = mkILGlobals ilg.traits None noDebugData; // assumes mscorlib is Scope_assembly _ ILScopeRef
desiredMetadataVersion=desiredMetadataVersion;
requiredDataFixups= requiredDataFixups;
requiredStringFixups = [];
@@ -3468,7 +3467,7 @@ module FileSystemUtilites =
// Fail silently
#endif
-let writeILMetadataAndCode (generatePdb,desiredMetadataVersion,mscorlib,emitTailcalls,showTimes) modul noDebugData cilStartAddress =
+let writeILMetadataAndCode (generatePdb,desiredMetadataVersion,ilg,emitTailcalls,showTimes) modul noDebugData cilStartAddress =
// When we know the real RVAs of the data section we fixup the references for the FieldRVA table.
// These references are stored as offsets into the metadata we return from this function
@@ -3477,7 +3476,7 @@ let writeILMetadataAndCode (generatePdb,desiredMetadataVersion,mscorlib,emitTail
let next = cilStartAddress
let strings,userStrings,blobs,guids,tables,entryPointToken,code,requiredStringFixups,data,resources,pdbData,mappings =
- generateIL requiredDataFixups (desiredMetadataVersion,generatePdb,mscorlib,emitTailcalls,showTimes) modul noDebugData cilStartAddress
+ generateIL requiredDataFixups (desiredMetadataVersion,generatePdb,ilg,emitTailcalls,showTimes) modul noDebugData cilStartAddress
reportTime showTimes "Generated Tables and Code";
let tableSize (tab: TableName) = tables.[tab.Index].Length
@@ -3917,7 +3916,7 @@ let writeDirectory os dict =
let writeBytes (os: BinaryWriter) (chunk:byte[]) = os.Write(chunk,0,chunk.Length)
-let writeBinaryAndReportMappings (outfile, mscorlib, pdbfile: string option, signer: ILStrongNameSigner option, fixupOverlappingSequencePoints, emitTailcalls, showTimes, dumpDebugInfo) modul noDebugData =
+let writeBinaryAndReportMappings (outfile, ilg, pdbfile: string option, signer: ILStrongNameSigner option, fixupOverlappingSequencePoints, emitTailcalls, showTimes, dumpDebugInfo) modul noDebugData =
// Store the public key from the signer into the manifest. This means it will be written
// to the binary and also acts as an indicator to leave space for delay sign
@@ -4024,7 +4023,7 @@ let writeBinaryAndReportMappings (outfile, mscorlib, pdbfile: string option, sig
if modul.MetadataVersion <> "" then
parseILVersion modul.MetadataVersion
else
- match mscorlib with
+ match ilg.traits.ScopeRef with
| ILScopeRef.Local -> failwith "Expected mscorlib to be ILScopeRef.Assembly was ILScopeRef.Local"
| ILScopeRef.Module(_) -> failwith "Expected mscorlib to be ILScopeRef.Assembly was ILScopeRef.Module"
| ILScopeRef.Assembly(aref) ->
@@ -4034,7 +4033,7 @@ let writeBinaryAndReportMappings (outfile, mscorlib, pdbfile: string option, sig
| None -> failwith "Expected msorlib to have a version number"
let entryPointToken,code,codePadding,metadata,data,resources,requiredDataFixups,pdbData,mappings =
- writeILMetadataAndCode ((pdbfile <> None), desiredMetadataVersion,mscorlib,emitTailcalls,showTimes) modul noDebugData next
+ writeILMetadataAndCode ((pdbfile <> None), desiredMetadataVersion, ilg,emitTailcalls,showTimes) modul noDebugData next
reportTime showTimes "Generated IL and metadata";
let _codeChunk,next = chunk code.Length next
@@ -4523,7 +4522,6 @@ let writeBinaryAndReportMappings (outfile, mscorlib, pdbfile: string option, sig
FileSystem.FileDelete outfile
with _ -> ());
reraise()
- raise e // is this really needed?
reportTime showTimes "Writing Image";
@@ -4602,7 +4600,7 @@ let writeBinaryAndReportMappings (outfile, mscorlib, pdbfile: string option, sig
type options =
- { mscorlib: ILScopeRef;
+ { ilg: ILGlobals;
pdbfile: string option;
signer: ILStrongNameSigner option;
fixupOverlappingSequencePoints: bool;
@@ -4612,7 +4610,7 @@ type options =
let WriteILBinary outfile (args: options) modul noDebugData =
- ignore (writeBinaryAndReportMappings (outfile, args.mscorlib, args.pdbfile, args.signer, args.fixupOverlappingSequencePoints, args.emitTailcalls, args.showTimes, args.dumpDebugInfo) modul (noDebugData, true))
+ ignore (writeBinaryAndReportMappings (outfile, args.ilg, args.pdbfile, args.signer, args.fixupOverlappingSequencePoints, args.emitTailcalls, args.showTimes, args.dumpDebugInfo) modul noDebugData)
diff --git a/src/absil/ilwrite.fsi b/src/absil/ilwrite.fsi
index bc17084855..62a20039b9 100755
--- a/src/absil/ilwrite.fsi
+++ b/src/absil/ilwrite.fsi
@@ -26,7 +26,7 @@ type ILStrongNameSigner =
static member OpenKeyContainer: string -> ILStrongNameSigner
type options =
- { mscorlib: ILScopeRef;
+ { ilg: ILGlobals
pdbfile: string option;
signer : ILStrongNameSigner option;
fixupOverlappingSequencePoints : bool;
diff --git a/src/absil/zmap.fs b/src/absil/zmap.fs
index 5248c174ee..03d7337e2e 100755
--- a/src/absil/zmap.fs
+++ b/src/absil/zmap.fs
@@ -1,4 +1,13 @@
-(* (c) Microsoft Corporation. Apache 2.0 License *)
+//----------------------------------------------------------------------------
+// Copyright (c) 2002-2012 Microsoft Corporation.
+//
+// This source code is subject to terms and conditions of the Apache License, Version 2.0. A
+// copy of the license can be found in the License.html file at the root of this distribution.
+// By using this source code in any fashion, you are agreeing to be bound
+// by the terms of the Apache License, Version 2.0.
+//
+// You must not remove this notice, or any other, from this software.
+//----------------------------------------------------------------------------
namespace Microsoft.FSharp.Compiler.AbstractIL.Internal
@@ -33,7 +42,7 @@ module internal Zmap =
let isEmpty (m:Zmap<_,_>) = m.IsEmpty
- let fmap f z (m:Zmap<_,_>) =
+ let foldMap f z (m:Zmap<_,_>) =
let m,z = m.FoldAndMap (fun k v z -> let z,v' = f z k v in v',z) z in
z,m
diff --git a/src/absil/zmap.fsi b/src/absil/zmap.fsi
index 0aa0fbd4be..ea8f4c5c71 100755
--- a/src/absil/zmap.fsi
+++ b/src/absil/zmap.fsi
@@ -1,4 +1,13 @@
-(* (c) Microsoft Corporation. Apache 2.0 License *)
+//----------------------------------------------------------------------------
+// Copyright (c) 2002-2012 Microsoft Corporation.
+//
+// This source code is subject to terms and conditions of the Apache License, Version 2.0. A
+// copy of the license can be found in the License.html file at the root of this distribution.
+// By using this source code in any fashion, you are agreeing to be bound
+// by the terms of the Apache License, Version 2.0.
+//
+// You must not remove this notice, or any other, from this software.
+//----------------------------------------------------------------------------
namespace Microsoft.FSharp.Compiler.AbstractIL.Internal
@@ -26,7 +35,7 @@ module internal Zmap =
val map : mapping:('T -> 'U) -> Zmap<'Key,'T> -> Zmap<'Key,'U>
val mapi : ('Key -> 'T -> 'U) -> Zmap<'Key,'T> -> Zmap<'Key,'U>
val fold : ('Key -> 'T -> 'U -> 'U) -> Zmap<'Key,'T> -> 'U -> 'U
- val fmap : ('State -> 'Key -> 'T -> 'State * 'U) -> 'State -> Zmap<'Key,'T> -> 'State * Zmap<'Key,'U>
+ val foldMap : ('State -> 'Key -> 'T -> 'State * 'U) -> 'State -> Zmap<'Key,'T> -> 'State * Zmap<'Key,'U>
val iter : action:('T -> 'U -> unit) -> Zmap<'T, 'U> -> unit
val foldSection: 'Key -> 'Key -> ('Key -> 'T -> 'U -> 'U) -> Zmap<'Key,'T> -> 'U -> 'U
diff --git a/src/absil/zset.fs b/src/absil/zset.fs
index ec92ae03d3..b7fdccf6e3 100755
--- a/src/absil/zset.fs
+++ b/src/absil/zset.fs
@@ -1,4 +1,13 @@
-(* (c) Microsoft Corporation. Apache 2.0 License *)
+//----------------------------------------------------------------------------
+// Copyright (c) 2002-2012 Microsoft Corporation.
+//
+// This source code is subject to terms and conditions of the Apache License, Version 2.0. A
+// copy of the license can be found in the License.html file at the root of this distribution.
+// By using this source code in any fashion, you are agreeing to be bound
+// by the terms of the Apache License, Version 2.0.
+//
+// You must not remove this notice, or any other, from this software.
+//----------------------------------------------------------------------------
namespace Microsoft.FSharp.Compiler.AbstractIL.Internal
diff --git a/src/absil/zset.fsi b/src/absil/zset.fsi
index 7084bc4942..4713d22681 100755
--- a/src/absil/zset.fsi
+++ b/src/absil/zset.fsi
@@ -1,4 +1,13 @@
-(* (c) Microsoft Corporation. Apache 2.0 License *)
+//----------------------------------------------------------------------------
+// Copyright (c) 2002-2012 Microsoft Corporation.
+//
+// This source code is subject to terms and conditions of the Apache License, Version 2.0. A
+// copy of the license can be found in the License.html file at the root of this distribution.
+// By using this source code in any fashion, you are agreeing to be bound
+// by the terms of the Apache License, Version 2.0.
+//
+// You must not remove this notice, or any other, from this software.
+//----------------------------------------------------------------------------
namespace Microsoft.FSharp.Compiler.AbstractIL.Internal
diff --git a/src/all-vs2012.sln b/src/all-vs2012.sln
index d883996fa0..3f5362be57 100755
--- a/src/all-vs2012.sln
+++ b/src/all-vs2012.sln
@@ -1,4 +1,3 @@
-
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{D78E3B57-DAD1-4FE1-9DC8-84F7847B0C77}"
@@ -13,8 +12,6 @@ Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Fsc", "fsharp\Fsc\Fsc.fspro
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Compiler", "fsharp\FSharp.Compiler\FSharp.Compiler.fsproj", "{2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}"
EndProject
-Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Compiler.Silverlight", "fsharp\FSharp.Compiler.Silverlight\FSharp.Compiler.Silverlight.fsproj", "{A90A57BE-C2BD-4CB9-87DC-C0D18820FF6B}"
-EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Core", "fsharp\FSharp.Core\FSharp.Core.fsproj", "{DED3BBD7-53F4-428A-8C9F-27968E768605}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Build", "fsharp\FSharp.Build\FSharp.Build.fsproj", "{702A7979-BCF9-4C41-853E-3ADFC9897890}"
@@ -35,44 +32,28 @@ Global
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Release|Any CPU.Build.0 = Release|Any CPU
- {649FA588-F02E-457C-9FCF-87E46407481E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {649FA588-F02E-457C-9FCF-87E46407481E}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {649FA588-F02E-457C-9FCF-87E46407481E}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {649FA588-F02E-457C-9FCF-87E46407481E}.Release|Any CPU.Build.0 = Release|Any CPU
- {702A7979-BCF9-4C41-853E-3ADFC9897890}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {702A7979-BCF9-4C41-853E-3ADFC9897890}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {702A7979-BCF9-4C41-853E-3ADFC9897890}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {702A7979-BCF9-4C41-853E-3ADFC9897890}.Release|Any CPU.Build.0 = Release|Any CPU
- {88E2D422-6852-46E3-A740-83E391DC7973}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {88E2D422-6852-46E3-A740-83E391DC7973}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {88E2D422-6852-46E3-A740-83E391DC7973}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {88E2D422-6852-46E3-A740-83E391DC7973}.Release|Any CPU.Build.0 = Release|Any CPU
- {A90A57BE-C2BD-4CB9-87DC-C0D18820FF6B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {A90A57BE-C2BD-4CB9-87DC-C0D18820FF6B}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {C94C257C-3C0A-4858-B5D8-D746498D1F08}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {C94C257C-3C0A-4858-B5D8-D746498D1F08}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {C94C257C-3C0A-4858-B5D8-D746498D1F08}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {C94C257C-3C0A-4858-B5D8-D746498D1F08}.Release|Any CPU.Build.0 = Release|Any CPU
- {D0E98C0D-490B-4C61-9329-0862F6E87645}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {D0E98C0D-490B-4C61-9329-0862F6E87645}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {D0E98C0D-490B-4C61-9329-0862F6E87645}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {D0E98C0D-490B-4C61-9329-0862F6E87645}.Release|Any CPU.Build.0 = Release|Any CPU
- {D5870CF0-ED51-4CBC-B3D7-6F56DA84AC06}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {D5870CF0-ED51-4CBC-B3D7-6F56DA84AC06}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {D5870CF0-ED51-4CBC-B3D7-6F56DA84AC06}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {D5870CF0-ED51-4CBC-B3D7-6F56DA84AC06}.Release|Any CPU.Build.0 = Release|Any CPU
- {DED3BBD7-53F4-428A-8C9F-27968E768605}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {DED3BBD7-53F4-428A-8C9F-27968E768605}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {DED3BBD7-53F4-428A-8C9F-27968E768605}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {DED3BBD7-53F4-428A-8C9F-27968E768605}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C94C257C-3C0A-4858-B5D8-D746498D1F08}.Debug|Any CPU.ActiveCfg = Debug|x86
+ {C94C257C-3C0A-4858-B5D8-D746498D1F08}.Release|Any CPU.ActiveCfg = Release|x86
+ {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Debug|Any CPU.ActiveCfg = Debug|x86
+ {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Release|Any CPU.ActiveCfg = Release|x86
+ {DED3BBD7-53F4-428A-8C9F-27968E768605}.Debug|Any CPU.ActiveCfg = Debug|x86
+ {DED3BBD7-53F4-428A-8C9F-27968E768605}.Release|Any CPU.ActiveCfg = Release|x86
+ {702A7979-BCF9-4C41-853E-3ADFC9897890}.Debug|Any CPU.ActiveCfg = Debug|x86
+ {702A7979-BCF9-4C41-853E-3ADFC9897890}.Release|Any CPU.ActiveCfg = Release|x86
{EE85AAB7-CDA0-4C4E-BDA0-A64DDDD13E3F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EE85AAB7-CDA0-4C4E-BDA0-A64DDDD13E3F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EE85AAB7-CDA0-4C4E-BDA0-A64DDDD13E3F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EE85AAB7-CDA0-4C4E-BDA0-A64DDDD13E3F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D0E98C0D-490B-4C61-9329-0862F6E87645}.Debug|Any CPU.ActiveCfg = Debug|x86
+ {D0E98C0D-490B-4C61-9329-0862F6E87645}.Release|Any CPU.ActiveCfg = Release|x86
+ {649FA588-F02E-457C-9FCF-87E46407481E}.Debug|Any CPU.ActiveCfg = Debug|x86
+ {649FA588-F02E-457C-9FCF-87E46407481E}.Release|Any CPU.ActiveCfg = Release|x86
+ {D5870CF0-ED51-4CBC-B3D7-6F56DA84AC06}.Debug|Any CPU.ActiveCfg = Debug|x86
+ {D5870CF0-ED51-4CBC-B3D7-6F56DA84AC06}.Release|Any CPU.ActiveCfg = Release|x86
+ {88E2D422-6852-46E3-A740-83E391DC7973}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {88E2D422-6852-46E3-A740-83E391DC7973}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {88E2D422-6852-46E3-A740-83E391DC7973}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {88E2D422-6852-46E3-A740-83E391DC7973}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/src/all-vs2013.sln b/src/all-vs2013.sln
new file mode 100644
index 0000000000..7400bcec7d
--- /dev/null
+++ b/src/all-vs2013.sln
@@ -0,0 +1,63 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2013
+VisualStudioVersion = 12.0.21005.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{D78E3B57-DAD1-4FE1-9DC8-84F7847B0C77}"
+ ProjectSection(SolutionItems) = preProject
+ fsharp-compiler-build.proj = fsharp-compiler-build.proj
+ fsharp-proto-build.proj = fsharp-proto-build.proj
+ root.traversal.targets = root.traversal.targets
+ source-build-version = source-build-version
+ EndProjectSection
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Fsc", "fsharp\Fsc\Fsc.fsproj", "{C94C257C-3C0A-4858-B5D8-D746498D1F08}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Compiler", "fsharp\FSharp.Compiler\FSharp.Compiler.fsproj", "{2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Core", "fsharp\FSharp.Core\FSharp.Core.fsproj", "{DED3BBD7-53F4-428A-8C9F-27968E768605}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Build", "fsharp\FSharp.Build\FSharp.Build.fsproj", "{702A7979-BCF9-4C41-853E-3ADFC9897890}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Unittests", "fsharp\unittests\Unittests.fsproj", "{EE85AAB7-CDA0-4C4E-BDA0-A64DDDD13E3F}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Fsi", "fsharp\fsi\Fsi.fsproj", "{D0E98C0D-490B-4C61-9329-0862F6E87645}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Compiler.Interactive.Settings", "fsharp\FSharp.Compiler.Interactive.Settings\FSharp.Compiler.Interactive.Settings.fsproj", "{649FA588-F02E-457C-9FCF-87E46407481E}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Compiler.Server.Shared", "fsharp\FSharp.Compiler.Server.Shared\FSharp.Compiler.Server.Shared.fsproj", "{D5870CF0-ED51-4CBC-B3D7-6F56DA84AC06}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Core.Unittests", "fsharp\FSharp.Core.Unittests\FSharp.Core.Unittests.fsproj", "{88E2D422-6852-46E3-A740-83E391DC7973}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {C94C257C-3C0A-4858-B5D8-D746498D1F08}.Debug|Any CPU.ActiveCfg = Debug|x86
+ {C94C257C-3C0A-4858-B5D8-D746498D1F08}.Release|Any CPU.ActiveCfg = Release|x86
+ {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Debug|Any CPU.ActiveCfg = Debug|x86
+ {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Release|Any CPU.ActiveCfg = Release|x86
+ {DED3BBD7-53F4-428A-8C9F-27968E768605}.Debug|Any CPU.ActiveCfg = Debug|x86
+ {DED3BBD7-53F4-428A-8C9F-27968E768605}.Release|Any CPU.ActiveCfg = Release|x86
+ {702A7979-BCF9-4C41-853E-3ADFC9897890}.Debug|Any CPU.ActiveCfg = Debug|x86
+ {702A7979-BCF9-4C41-853E-3ADFC9897890}.Release|Any CPU.ActiveCfg = Release|x86
+ {EE85AAB7-CDA0-4C4E-BDA0-A64DDDD13E3F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EE85AAB7-CDA0-4C4E-BDA0-A64DDDD13E3F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EE85AAB7-CDA0-4C4E-BDA0-A64DDDD13E3F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EE85AAB7-CDA0-4C4E-BDA0-A64DDDD13E3F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D0E98C0D-490B-4C61-9329-0862F6E87645}.Debug|Any CPU.ActiveCfg = Debug|x86
+ {D0E98C0D-490B-4C61-9329-0862F6E87645}.Release|Any CPU.ActiveCfg = Release|x86
+ {649FA588-F02E-457C-9FCF-87E46407481E}.Debug|Any CPU.ActiveCfg = Debug|x86
+ {649FA588-F02E-457C-9FCF-87E46407481E}.Release|Any CPU.ActiveCfg = Release|x86
+ {D5870CF0-ED51-4CBC-B3D7-6F56DA84AC06}.Debug|Any CPU.ActiveCfg = Debug|x86
+ {D5870CF0-ED51-4CBC-B3D7-6F56DA84AC06}.Release|Any CPU.ActiveCfg = Release|x86
+ {88E2D422-6852-46E3-A740-83E391DC7973}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {88E2D422-6852-46E3-A740-83E391DC7973}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {88E2D422-6852-46E3-A740-83E391DC7973}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {88E2D422-6852-46E3-A740-83E391DC7973}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/src/fsharp-compiler-build.proj b/src/fsharp-compiler-build.proj
index 8750037920..c2ceb46493 100755
--- a/src/fsharp-compiler-build.proj
+++ b/src/fsharp-compiler-build.proj
@@ -8,19 +8,10 @@
net40
-
-
-
-
-
-
-
-
-
diff --git a/src/fsharp-compiler-unittests-build.proj b/src/fsharp-compiler-unittests-build.proj
index 1f626ab822..c5d2a9f6e0 100755
--- a/src/fsharp-compiler-unittests-build.proj
+++ b/src/fsharp-compiler-unittests-build.proj
@@ -11,9 +11,7 @@
+ '$(TargetFramework)' == 'net40'">
diff --git a/src/fsharp/ErrorLogger.fs b/src/fsharp/ErrorLogger.fs
index baedfcbecb..b50450c568 100755
--- a/src/fsharp/ErrorLogger.fs
+++ b/src/fsharp/ErrorLogger.fs
@@ -10,7 +10,7 @@
// You must not remove this notice, or any other, from this software.
//----------------------------------------------------------------------------
-module internal Microsoft.FSharp.Compiler.ErrorLogger
+module (*internal*) Microsoft.FSharp.Compiler.ErrorLogger
open Internal.Utilities
@@ -239,6 +239,9 @@ type ErrorLogger(nameForDebugging:string) =
member this.ErrorSink err =
this.ErrorSinkImpl err
member this.DebugDisplay() = sprintf "ErrorLogger(%s)" nameForDebugging
+ // record the reported error/warning numbers for SQM purpose
+ abstract ErrorOrWarningNumbers : int list
+ default this.ErrorOrWarningNumbers = []
let DiscardErrorsLogger =
{ new ErrorLogger("DiscardErrorsLogger") with
diff --git a/src/fsharp/FSComp.txt b/src/fsharp/FSComp.txt
index 86f36a2aee..274fba7208 100755
--- a/src/fsharp/FSComp.txt
+++ b/src/fsharp/FSComp.txt
@@ -18,7 +18,7 @@ buildUnexpectedTypeArgs,"The non-generic type '%s' does not expect any type argu
203,buildInvalidWarningNumber,"Invalid warning number '%s'"
204,buildInvalidVersionString,"Invalid version string '%s'"
205,buildInvalidVersionFile,"Invalid version file '%s'"
-buildProductName,"F# Compiler for F# 3.0 %s"
+buildProductName,"F# Compiler for F# 3.1 %s"
206,buildProblemWithFilename,"Problem with filename '%s': %s"
207,buildNoInputsSpecified,"No inputs specified"
208,buildMismatchOutputExtension,"The output name extension doesn't match the options used. If '-a' or '--target:library' is used the output file name must end with '.dll', if '--target:module' is used the output extension must be '.netmodule', otherwise '.exe'."
@@ -36,7 +36,7 @@ buildCouldNotReadVersionInfoFromMscorlib,"Could not read version from mscorlib.d
219,buildMscorLibAndFSharpCoreMismatch,"The referenced or default base CLI library 'mscorlib' is binary-incompatible with the referenced F# core library '%s'. Consider recompiling the library or making an explicit reference to a version of this library that matches the CLI version you are using."
220,buildAssemblyResolutionFailed,"Assembly resolution failure at or near this location"
221,buildImplicitModuleIsNotLegalIdentifier,"The declarations in this file will be placed in an implicit module '%s' based on the file name '%s'. However this is not a valid F# identifier, so the contents will not be accessible from other files. Consider renaming the file or adding a 'module' or 'namespace' declaration at the top of the file."
-222,buildMultiFileRequiresNamespaceOrModule,"Files in libraries or multiple-file applications must begin with a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule'"
+222,buildMultiFileRequiresNamespaceOrModule,"Files in libraries or multiple-file applications must begin with a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule'. Only the last source file of an application may omit such a declaration."
223,buildMultipleToplevelModules,"This file contains multiple declarations of the form 'module SomeNamespace.SomeModule'. Only one declaration of this form is permitted in a file. Change your file to use an initial namespace declaration and/or use 'module ModuleName = ...' to define your modules."
buildUnknownFileSuffix,"ParseInput: unknown file suffix for '%s'"
224,buildOptionRequiresParameter,"Option requires parameter: %s"
@@ -90,8 +90,7 @@ tastUnexpectedDecodeOfAutoOpenAttribute,"Unexpected decode of AutoOpenAttribute"
tastUnexpectedDecodeOfInternalsVisibleToAttribute,"Unexpected decode of InternalsVisibleToAttribute"
tastUnexpectedDecodeOfInterfaceDataVersionAttribute,"Unexpected decode of InterfaceDataVersionAttribute"
265,tastActivePatternsLimitedToSeven,"Active patterns cannot return more than 7 possibilities"
-266,tastConstantCannotBeCustomAttribute,"This constant cannot be used as a custom attribute value"
-267,tastNotAConstantExpression,"This is not a constant expression or valid custom attribute value"
+267,tastNotAConstantExpression,"This is not a valid constant expression or custom attribute value"
# -----------------------------------------------------------------------------
# typrelns.fs
# -----------------------------------------------------------------------------
@@ -500,7 +499,6 @@ tcMemberKindPropertyGetSetNotExpected,"MemberKind.PropertyGetSet only expected i
644,tcNamespaceCannotContainExtensionMembers,"Namespaces cannot contain extension members except in the same file and namespace where the type is defined. Consider using a module to hold declarations of extension members."
645,tcMultipleVisibilityAttributes,"Multiple visibility attributes have been specified for this identifier"
646,tcMultipleVisibilityAttributesWithLet,"Multiple visibility attributes have been specified for this identifier. 'let' bindings in classes are always private, as are any 'let' bindings inside expressions."
-tcUnrecognizedAccessibilitySpec,"Unrecognized accessibility specification"
tcInvalidMethodNameForRelationalOperator,"The name '(%s)' should not be used as a member name. To define comparison semantics for a type, implement the 'System.IComparable' interface. If defining a static member for use from other CLI languages then use the name '%s' instead."
tcInvalidMethodNameForEquality,"The name '(%s)' should not be used as a member name. To define equality semantics for a type, override the 'Object.Equals' member. If defining a static member for use from other CLI languages then use the name '%s' instead."
tcInvalidMemberName,"The name '(%s)' should not be used as a member name. If defining a static member for use from other CLI languages then use the name '%s' instead."
@@ -551,7 +549,6 @@ tcCouldNotFindIDisposable,"Couldn't find Dispose on IDisposable, or it was overl
691,tcNameArgumentsMustAppearLast,"Named arguments must appear after all other arguments"
692,tcFunctionRequiresExplicitLambda,"This function value is being used to construct a delegate type whose signature includes a byref argument. You must use an explicit lambda expression taking %d arguments."
693,tcTypeCannotBeEnumerated,"The type '%s' is not a type whose values can be enumerated with this syntax, i.e. is not compatible with either seq<_>, IEnumerable<_> or IEnumerable and does not have a GetEnumerator method"
-694,tcBadReturnTypeForGetEnumerator,"This expression has a method called GetEnumerator, but its return type is a value type. Methods returning struct enumerators cannot be used in this expression form."
695,tcInvalidMixtureOfRecursiveForms,"This recursive binding uses an invalid mixture of recursive forms"
696,tcInvalidObjectConstructionExpression,"This is not a valid object construction expression. Explicit object constructors must either call an alternate constructor or initialize all fields of the object and specify a call to a super class constructor."
697,tcInvalidConstraint,"Invalid constraint"
@@ -718,8 +715,6 @@ tcUnnamedArgumentsDoNotFormPrefix,"The unnamed arguments do not form a prefix of
859,tcNoPropertyFoundForOverride,"No abstract property was found that corresponds to this override"
860,tcAbstractPropertyMissingGetOrSet,"This property overrides or implements an abstract property but the abstract property doesn't have a corresponding %s"
861,tcInvalidSignatureForSet,"Invalid signature for set member"
-862,tcPropertyAlreadyHasDefaultImplementation,"This property already has a default implementation"
-863,tcPropertyImplementedIsAmbiguous,"The property implemented by this default is ambiguous"
864,tcNewMemberHidesAbstractMember,"This new member hides the abstract member '%s'. Rename the member or use 'override' instead."
864,tcNewMemberHidesAbstractMemberWithSuffix,"This new member hides the abstract member '%s' once tuples, functions, units of measure and/or provided types are erased. Rename the member or use 'override' instead."
865,tcStaticInitializersIllegalInInterface,"Interfaces cannot contain definitions of static initializers"
@@ -837,8 +832,6 @@ tcReservedSyntaxForAugmentation,"The syntax 'type X with ...' is reserved for au
ilDynamicInvocationNotSupported,"Dynamic invocation of %s is not supported"
975,ilAddressOfLiteralFieldIsInvalid,"Taking the address of a literal field is invalid"
976,ilAddressOfValueHereIsInvalid,"This operation involves taking the address of a value '%s' represented using a local variable or other special representation. This is invalid."
-978,ilValuesWithLiteralAttributeCannotBeMutable,"Values marked with 'LiteralAttribute' cannot be mutable"
-979,ilValuesWithLiteralAttributeMustBeSimple,"Values marked with 'LiteralAttribute' must currently be simple integer, character, Boolean, string or floating point constants"
980,ilCustomMarshallersCannotBeUsedInFSharp,"Custom marshallers cannot be specified in F# code. Consider using a C# helper function."
981,ilMarshalAsAttributeCannotBeDecoded,"The MarshalAs attribute could not be decoded"
982,ilSignatureForExternalFunctionContainsTypeParameters,"The signature for this external function contains type parameters. Constrain the argument and return types to indicate the types of the corresponding C function."
@@ -927,7 +920,10 @@ optsDCLOHtmlDoc,"The command-line option '%s' has been deprecated. HTML document
optsConsoleColors,"Output warning and error messages in color"
optsUseHighEntropyVA,"Enable high-entropy ASLR"
optsSubSystemVersion,"Specify subsystem version of this assembly"
+optsTargetProfile,"Specify target framework profile of this assembly. Valid values are mscorlib or netcore. Default - mscorlib"
+optsEmitDebugInfoInQuotations,"Emit debug information in quotations"
1051,optsInvalidSubSystemVersion,"Invalid version '%s' for '--subsystemversion'. The version must be 4.00 or greater."
+1052,optsInvalidTargetProfile,"Invalid value '%s' for '--targetprofile', valid values are 'mscorlib' or 'netcore'."
# -----------------------------------------------------------------------------
# service.fs strings
# -----------------------------------------------------------------------------
@@ -942,6 +938,7 @@ typeInfoActiveRecognizer,"active recognizer"
typeInfoField,"field"
typeInfoEvent,"event"
typeInfoProperty,"property"
+typeInfoExtension,"extension"
typeInfoCustomOperation,"custom operation"
typeInfoArgument,"argument"
typeInfoPatternVariable,"patvar"
@@ -1097,7 +1094,6 @@ parsNonAtomicType,"The use of the type syntax 'int C' and 'C ' is not perm
1196,tcInvalidUseNullAsTrueValue,"The 'UseNullAsTrueValue' attribute flag may only be used with union types that have one nullary case and at least one non-nullary case"
1197,tcParameterInferredByref,"The parameter '%s' was inferred to have byref type. Parameters of byref type must be given an explicit type annotation, e.g. 'x1: byref'. When used, a byref parameter is implicitly dereferenced."
1198,tcNonUniformMemberUse,"The generic member '%s' has been used at a non-uniform instantiation prior to this program point. Consider reordering the members so this member occurs first. Alternatively, specify the full type of the member explicitly, including argument types, return type and any additional generic parameters and constraints."
-1199,tcNamedArgumentsCannotBeUsedInUnionCaseConstructions,"The use of named arguments in union case expressions is reserved for future use. Arguments of the form 'a=b' should be parenthesized."
1200,tcAttribArgsDiffer,"The attribute '%s' appears in both the implementation and the signature, but the attribute arguments differ. Only the attribute from the signature will be included in the compiled code."
1201,tcCannotCallAbstractBaseMember,"Cannot call an abstract base member: '%s'"
1202,typrelCannotResolveAmbiguityInUnmanaged,"Could not resolve the ambiguity in the use of a generic construct with an 'unmanaged' constraint at or near this position"
@@ -1164,6 +1160,7 @@ fscTooManyErrors,"Exiting - too many errors"
2021,fscRemotingError,"The resident compilation service was not used because a problem occured in communicating with the server."
2022,pathIsInvalid,"Problem with filename '%s': Illegal characters in path."
2023,fscResxSourceFileDeprecated,"Passing a .resx file (%s) as a source file to the compiler is deprecated. Use resgen.exe to transform the .resx file into a .resources file to pass as a --resource option. If you are using MSBuild, this can be done via an item in the .fsproj project file."
+2024,fscStaticLinkingNoProfileMismatches,"Static linking may not use assembly that targets different profile."
# -----------------------------------------------------------------------------
# Extension typing errors
# -----------------------------------------------------------------------------
@@ -1234,9 +1231,7 @@ invalidFullNameForProvidedType,"invalid full name for provided type"
3085,tcCustomOperationMayNotBeUsedInConjunctionWithNonSimpleLetBindings,"A custom operation may not be used in conjunction with a non-value or recursive 'let' binding in another part of this computation expression"
3086,tcCustomOperationMayNotBeUsedHere,"A custom operation may not be used in conjunction with 'use', 'try/with', 'try/finally', 'if/then/else' or 'match' operators within this computation expression"
3087,tcCustomOperationMayNotBeOverloaded,"The custom operation '%s' refers to a method which is overloaded. The implementations of custom operations may not be overloaded."
-3088,tcTryFinallyMayNotBeUsedWithCustomOperators,"A try/finally expression may not be used within a computation expression with uses of custom operators. Consider using a sequence expression instead."
-3089,tcTryWithMayNotBeUsedWithCustomOperators,"A try/with expression may not be used within a within a computation expression with uses of custom operators. Consider using a sequence expression instead."
-3090,tcIfThenElseMayNotBeUsedWithCustomOperators,"An if/then/else expression may not be used within a computation expression with uses of custom operators. Consider using either an if/then expression, or use a sequence expression instead."
+3090,tcIfThenElseMayNotBeUsedWithinQueries,"An if/then/else expression may not be used within queries. Consider using either an if/then expression, or use a sequence expression instead."
3091,ilxgenUnexpectedArgumentToMethodHandleOfDuringCodegen,"Invalid argument to 'methodhandleof' during codegen"
3092,etProvidedTypeReferenceMissingArgument,"A reference to a provided type was missing a value for the static parameter '%s'. You may need to recompile one or more referenced assemblies."
3093,etProvidedTypeReferenceInvalidText,"A reference to a provided type had an invalid value '%s' for a static parameter. You may need to recompile one or more referenced assemblies."
@@ -1244,7 +1239,7 @@ invalidFullNameForProvidedType,"invalid full name for provided type"
3095,tcCustomOperationNotUsedCorrectly2,"'%s' is not used correctly. Usage: %s. This is a custom operation in this query or computation expression."
customOperationTextLikeJoin,"%s var in collection %s (outerKey = innerKey). Note that parentheses are required after '%s'"
customOperationTextLikeGroupJoin,"%s var in collection %s (outerKey = innerKey) into group. Note that parentheses are required after '%s'"
-customOperationTextLikeZip,"%s collection into var"
+customOperationTextLikeZip,"%s var in collection"
3096,tcBinaryOperatorRequiresVariable,"'%s' must be followed by a variable name. Usage: %s."
3097,tcOperatorIncorrectSyntax,"Incorrect syntax for '%s'. Usage: %s."
3098,tcBinaryOperatorRequiresBody,"'%s' must come after a 'for' selection clause and be followed by the rest of the query. Syntax: ... %s ..."
@@ -1328,3 +1323,9 @@ descriptionUnavailable,"(description unavailable...)"
3171,tcGeneratedTypesShouldBeInternalOrPrivate,"The provided types generated by this use of a type provider may not be used from other F# assemblies and should be marked internal or private. Consider using 'type internal TypeName = ...' or 'type private TypeName = ...'."
3172,chkGetterAndSetterHaveSamePropertyType,"A property's getter and setter must have the same type. Property '%s' has getter of type '%s' but setter of type '%s'."
3173,tcRuntimeSuppliedMethodCannotBeUsedInUserCode,"Array method '%s' is supplied by the runtime and cannot be directly used in code. For operations with array elements consider using family of GetArray/SetArray functions from LanguagePrimitives.IntrinsicFunctions module."
+3174,tcUnionCaseConstructorDoesNotHaveFieldWithGivenName,"Union case/exception '%s' does not have field named '%s'."
+3175,tcUnionCaseFieldCannotBeUsedMoreThanOnce,"Union case/exception field '%s' cannot be used more than once."
+3176,tcFieldNameIsUsedModeThanOnce,"Named field '%s' is used more than once."
+3176,tcFieldNameConflictsWithGeneratedNameForAnonymousField,"Named field '%s' conflicts with autogenerated name for anonymous field."
+3177,tastConstantExpressionOverflow,"This literal expression or attribute argument results in an arithmetic overflow."
+3178,tcIllegalStructTypeForConstantExpression,"This is not valid literal expression. The [] attribute will be ignored."
diff --git a/src/fsharp/FSharp.Build-proto/FSharp.Build-proto.fsproj b/src/fsharp/FSharp.Build-proto/FSharp.Build-proto.fsproj
index 860d6232ac..3562310196 100755
--- a/src/fsharp/FSharp.Build-proto/FSharp.Build-proto.fsproj
+++ b/src/fsharp/FSharp.Build-proto/FSharp.Build-proto.fsproj
@@ -1,14 +1,4 @@
-
$(MSBuildProjectDirectory)\..\..
diff --git a/src/fsharp/FSharp.Build-proto/Makefile.in b/src/fsharp/FSharp.Build-proto/Makefile.in
index 60a0463dc7..89d3f27dd5 100644
--- a/src/fsharp/FSharp.Build-proto/Makefile.in
+++ b/src/fsharp/FSharp.Build-proto/Makefile.in
@@ -5,36 +5,8 @@ srcdir := @abs_srcdir@/
include @abs_top_builddir@/config.make
-CONFIG=proto
-
-FSC=$(bootstrapdir)fsc.exe
-
-FLAGS += --target:library
-
-DEFINES += \
- --define:BUILDING_WITH_LKG
-
-REFERENCES += \
- -r:$(bootstrapdir)FSharp.Core.dll
-
-sources= \
- $(tmpdir)FSBuild.fs \
- ../../utils/CompilerLocationUtils.fs \
- ../FSharp.Build/CreateFSharpManifestResourceName.fsi \
- ../FSharp.Build/CreateFSharpManifestResourceName.fs \
- ../FSharp.Build/Fsc.fsi \
- ../FSharp.Build/Fsc.fs
-
-RESOURCES = \
- $(tmpdir)FSBuild.resources
-
-$(tmpdir)FSBuild.fs $(tmpdir)FSBuild.resources: ../FSharp.Build/FSBuild.txt
- mono $(MONO_OPTIONS) $(FSSRGEN) $< $(tmpdir)FSBuild.fs $(tmpdir)FSBuild.resx
- resgen $(tmpdir)FSBuild.resx $(tmpdir)FSBuild.resources
-
-do-proto: do-4-0
-
-clean: clean-4-0
+build-proto:
+ MONO_ENV_OPTIONS=$(monoopts) xbuild /p:Configuration=Proto
include $(topdir)/src/fsharp/targets.make
diff --git a/src/fsharp/FSharp.Build/FSharp.Build.fsproj b/src/fsharp/FSharp.Build/FSharp.Build.fsproj
index beaa2db3d8..1057a5d154 100644
--- a/src/fsharp/FSharp.Build/FSharp.Build.fsproj
+++ b/src/fsharp/FSharp.Build/FSharp.Build.fsproj
@@ -1,20 +1,7 @@
-
$(MSBuildProjectDirectory)\..\..
- 10.0.0
- 2.0
- False
@@ -33,19 +20,29 @@
FSBuild.txt
- assemblyinfo.FSharp.Build.dll.fs
+ Utilities/assemblyinfo.FSharp.Build.dll.fs
- CompilerLocationUtils.fs
+ Utilities/CompilerLocationUtils.fs
+
+
+ BuildTasks/Fsc.fsi
+
+
+ BuildTasks/Fsc.fs
+
+
+ BuildTasks/CreateFSharpManifestResourceName.fsi
+
+
+ BuildTasks/CreateFSharpManifestResourceName.fs
-
-
-
-
+ Microsoft.FSharp.Targets
PreserveNewest
+ Microsoft.Portable.FSharp.Targets
PreserveNewest
@@ -54,9 +51,10 @@
-
-
-
+
+
+
+ {DED3BBD7-53F4-428A-8C9F-27968E768605}FSharp.Core
diff --git a/src/fsharp/FSharp.Build/Fsc.fs b/src/fsharp/FSharp.Build/Fsc.fs
index a5d70449db..857b8eb19d 100755
--- a/src/fsharp/FSharp.Build/Fsc.fs
+++ b/src/fsharp/FSharp.Build/Fsc.fs
@@ -154,6 +154,8 @@ type [
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ true
+
+
+
+
+
+ $(MSBuildAllProjects);$(MSBuildThisFileFullPath)
+ .fs
+ F#
+ Managed
+ $(Optimize)
+ Software\Microsoft\Microsoft SDKs\$(TargetFrameworkIdentifier)
+
+ RootNamespace
+ false
+ $(Prefer32Bit)
+
+
+
+
+
+
+
+
+ false
+ true
+
+
+
+
+
+ <_Temporary Remove="@(_Temporary)" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_Temporary Remove="@(_Temporary)" />
+
+
+
+
+
+
+
+
+
+ <_DebugSymbolsIntermediatePathTemporary Include="$(PdbFile)"/>
+
+ <_DebugSymbolsIntermediatePath Include="@(_DebugSymbolsIntermediatePathTemporary->'%(RootDir)%(Directory)%(Filename).pdb')"/>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_CoreCompileResourceInputs Remove="@(_CoreCompileResourceInputs)" />
+
+
+
+
+
+
+
+
+
+
diff --git a/src/fsharp/FSharp.Compiler-proto/FSharp.Compiler-proto.fsproj b/src/fsharp/FSharp.Compiler-proto/FSharp.Compiler-proto.fsproj
index 9fe60a4fe9..a098976925 100644
--- a/src/fsharp/FSharp.Compiler-proto/FSharp.Compiler-proto.fsproj
+++ b/src/fsharp/FSharp.Compiler-proto/FSharp.Compiler-proto.fsproj
@@ -13,9 +13,6 @@
$(MSBuildProjectDirectory)\..\..Proto
- 10.0.0
- 2.0
- False
diff --git a/src/fsharp/FSharp.Compiler-proto/Makefile.in b/src/fsharp/FSharp.Compiler-proto/Makefile.in
index ee92d99dca..fc325f20ef 100644
--- a/src/fsharp/FSharp.Compiler-proto/Makefile.in
+++ b/src/fsharp/FSharp.Compiler-proto/Makefile.in
@@ -5,185 +5,7 @@ srcdir := @abs_srcdir@/
include @abs_top_builddir@/config.make
-CONFIG=proto
-
-FSC=$(bootstrapdir)fsc.exe
-
-FLAGS += --target:library
-
-DEFINES += \
- --define:BUILDING_WITH_LKG \
- --define:BUILDING_PROTO \
- --define:COMPILER \
- --define:NO_STRONG_NAMES \
- --define:INCLUDE_METADATA_READER \
- --define:INCLUDE_METADATA_WRITER
-
-REFERENCES += \
- -r:$(bootstrapdir)FSharp.Core.dll \
- -r:$(monogacdirXX)/System.Windows.Forms.dll
-
-
-sources = \
- $(tmpdir)FSComp.fs \
- ../../assemblyinfo/assemblyinfo.FSharp.Compiler.dll.fs \
- ../../utils/sformat.fsi \
- ../../utils/sformat.fs \
- ../sr.fsi \
- ../sr.fs \
- ../../utils/prim-lexing.fsi \
- ../../utils/prim-lexing.fs \
- ../../utils/prim-parsing.fsi \
- ../../utils/prim-parsing.fs \
- ../../utils/resizearray.fsi \
- ../../utils/resizearray.fs \
- ../../utils/HashMultiMap.fsi \
- ../../utils/HashMultiMap.fs \
- ../../utils/TaggedCollections.fsi \
- ../../utils/TaggedCollections.fs \
- ../FlatList.fs \
- ../../absil/illib.fs \
- ../../utils/filename.fsi \
- ../../utils/filename.fs \
- ../../absil/zmap.fsi \
- ../../absil/zmap.fs \
- ../../absil/zset.fsi \
- ../../absil/zset.fs \
- ../../absil/bytes.fsi \
- ../../absil/bytes.fs \
- ../../absil/ildiag.fsi \
- ../../absil/ildiag.fs \
- ../ReferenceResolution.fs \
- ../../absil/il.fsi \
- ../../absil/il.fs \
- ../../absil/ilx.fsi \
- ../../absil/ilx.fs \
- ../../absil/ilascii.fsi \
- ../../absil/ilascii.fs \
- ../../absil/ilprint.fsi \
- ../../absil/ilprint.fs \
- ../../absil/ilmorph.fsi \
- ../../absil/ilmorph.fs \
- ../../absil/ilsupp.fsi \
- ../../absil/ilsupp.fs \
- $(tmpdir)ilpars.fs \
- $(tmpdir)illex.fs \
- ../../absil/ilbinary.fsi \
- ../../absil/ilbinary.fs \
- ../lib.fs \
- ../range.fsi \
- ../range.fs \
- ../ErrorLogger.fs \
- ../InternalCollections.fsi \
- ../InternalCollections.fs \
- ../../absil/ilread.fsi \
- ../../absil/ilread.fs \
- ../../absil/ilwrite.fsi \
- ../../absil/ilwrite.fs \
- ../../absil/ilreflect.fs \
- ../../utils/CompilerLocationUtils.fs \
- ../PrettyNaming.fs \
- ../../ilx/ilxsettings.fs \
- ../../ilx/pubclo.fsi \
- ../../ilx/pubclo.fs \
- ../../ilx/cu_erase.fsi \
- ../../ilx/cu_erase.fs \
- ../InternalFileSystemUtils.fsi \
- ../InternalFileSystemUtils.fs \
- ../unilex.fsi \
- ../unilex.fs \
- ../layout.fsi \
- ../layout.fs \
- ../ast.fs \
- $(tmpdir)pars.fs \
- ../lexhelp.fsi \
- ../lexhelp.fs \
- $(tmpdir)lex.fs \
- ../sreflect.fsi \
- ../sreflect.fs \
- ../QueueList.fs \
- ../tast.fs \
- ../env.fs \
- ../tastops.fsi \
- ../tastops.fs \
- ../pickle.fsi \
- ../pickle.fs \
- ../lexfilter.fs \
- ../import.fsi \
- ../import.fs \
- ../infos.fs \
- ../NicePrint.fs \
- ../augment.fsi \
- ../augment.fs \
- ../typrelns.fs \
- ../patcompile.fsi \
- ../patcompile.fs \
- ../outcome.fsi \
- ../outcome.fs \
- ../csolve.fsi \
- ../csolve.fs \
- ../formats.fsi \
- ../formats.fs \
- ../nameres.fsi \
- ../nameres.fs \
- ../unsolved.fs \
- ../creflect.fsi \
- ../creflect.fs \
- ../check.fsi \
- ../check.fs \
- ../tc.fsi \
- ../tc.fs \
- ../opt.fsi \
- ../opt.fs \
- ../detuple.fsi \
- ../detuple.fs \
- ../tlr.fsi \
- ../tlr.fs \
- ../lowertop.fs \
- ../ilxgen.fsi \
- ../ilxgen.fs \
- ../TraceCall.fs \
- ../build.fsi \
- ../build.fs \
- ../fscopts.fsi \
- ../fscopts.fs \
- ../vs/IncrementalBuild.fsi \
- ../vs/IncrementalBuild.fs \
- ../fsc.fs
-
-RESOURCES= \
- $(tmpdir)FSStrings.resources \
- $(tmpdir)FSComp.resources
-
-$(tmpdir)FSComp.fs $(tmpdir)FSComp.resources: ../FSComp.txt
- mono $(MONO_OPTIONS) $(FSSRGEN) $< $(tmpdir)FSComp.fs $(tmpdir)FSComp.resx
- resgen $(tmpdir)FSComp.resx $(tmpdir)FSComp.resources
-
-$(tmpdir)FSStrings.resources: ../FSStrings.resx
- resgen $< $@
-
-$(tmpdir)lex.fs: ../lex.fsl
- mono $(MONO_OPTIONS) $(FSLEX) $< -o $@ --lexlib Internal.Utilities.Text.Lexing --unicode
- @-mkdir -p ../FSharp.Compiler/.libs/
- cp -p $(tmpdir)lex.fs* ../FSharp.Compiler/.libs/
-
-$(tmpdir)illex.fs: ../../absil/illex.fsl
- mono $(MONO_OPTIONS) $(FSLEX) $< -o $@ --lexlib Internal.Utilities.Text.Lexing --unicode
- @-mkdir -p ../FSharp.Compiler/.libs/
- cp -p $(tmpdir)illex.fs* ../FSharp.Compiler/.libs/
-
-$(tmpdir)pars.fs: ../pars.fsy
- mono $(MONO_OPTIONS) $(FSYACC) $< -o $@ --internal --open Microsoft.FSharp.Compiler --module Microsoft.FSharp.Compiler.Parser --lexlib Internal.Utilities.Text.Lexing --parslib Internal.Utilities.Text.Parsing | tee $@.report | grep "time"
- @-mkdir -p ../FSharp.Compiler/.libs/
- cp -p $(tmpdir)pars.fs* ../FSharp.Compiler/.libs/
-
-$(tmpdir)ilpars.fs: ../../absil/ilpars.fsy
- mono $(MONO_OPTIONS) $(FSYACC) $< -o $@ --internal --module Microsoft.FSharp.Compiler.AbstractIL.Internal.AsciiParser --lexlib Internal.Utilities.Text.Lexing --parslib Internal.Utilities.Text.Parsing | tee $@.report | grep "time"
- @-mkdir -p ../FSharp.Compiler/.libs/
- cp -p $(tmpdir)ilpars.fs* ../FSharp.Compiler/.libs/
-
-do-proto: do-4-0
-
-clean: clean-4-0
+build-proto:
+ MONO_ENV_OPTIONS=$(monoopts) xbuild /p:Configuration=Proto
include $(topdir)/src/fsharp/targets.make
diff --git a/src/fsharp/FSharp.Compiler.Interactive.Settings/FSharp.Compiler.Interactive.Settings.fsproj b/src/fsharp/FSharp.Compiler.Interactive.Settings/FSharp.Compiler.Interactive.Settings.fsproj
index 93a11b4b96..f57bb95dc1 100644
--- a/src/fsharp/FSharp.Compiler.Interactive.Settings/FSharp.Compiler.Interactive.Settings.fsproj
+++ b/src/fsharp/FSharp.Compiler.Interactive.Settings/FSharp.Compiler.Interactive.Settings.fsproj
@@ -1,20 +1,7 @@
-
$(MSBuildProjectDirectory)\..\..
- 10.0.0
- 2.0
- False
@@ -35,16 +22,16 @@
FSInteractiveSettings.txt
- assemblyinfo.FSharp.Compiler.Interactive.Settings.dll.fs
+ Utilities/assemblyinfo.FSharp.Compiler.Interactive.Settings.dll.fs
+
+
+ Utilities/fsiattrs.fs
- fsiaux.fsi
+ InteractiveSettings/fsiaux.fsi
- fsiaux.fs
-
-
- fsiattrs.fs
+ InteractiveSettings/fsiaux.fs
diff --git a/src/fsharp/FSharp.Compiler.Interactive.Settings/Makefile.in b/src/fsharp/FSharp.Compiler.Interactive.Settings/Makefile.in
index fed3f5d425..5254a08f89 100644
--- a/src/fsharp/FSharp.Compiler.Interactive.Settings/Makefile.in
+++ b/src/fsharp/FSharp.Compiler.Interactive.Settings/Makefile.in
@@ -6,29 +6,9 @@ srcdir := @abs_srcdir@/
include @abs_top_builddir@/config.make
-FSC=$(protodir)fsc-proto.exe
-
-FLAGS += \
- $(SIGN_FLAGS) \
- --target:library
-
-REFERENCES += \
- -r:$(outdir)FSharp.Core.dll \
- -r:Mono.Security.dll
-
-sources = \
- ../../assemblyinfo/assemblyinfo.FSharp.Compiler.Interactive.Settings.dll.fs \
- ../fsiaux.fsi \
- ../fsiaux.fs \
- ../fsiattrs.fs
-
include $(topdir)/src/fsharp/targets.make
-do-final: do-4-0
-
-clean: clean-4-0
-
-install: install-lib-4 install-lib-4-5
+install: install-lib install-lib-net45
diff --git a/src/fsharp/FSharp.Compiler.Server.Shared/FSharp.Compiler.Server.Shared.fsproj b/src/fsharp/FSharp.Compiler.Server.Shared/FSharp.Compiler.Server.Shared.fsproj
index 1e905ae19d..fbceeb9e36 100644
--- a/src/fsharp/FSharp.Compiler.Server.Shared/FSharp.Compiler.Server.Shared.fsproj
+++ b/src/fsharp/FSharp.Compiler.Server.Shared/FSharp.Compiler.Server.Shared.fsproj
@@ -1,20 +1,7 @@
-
$(MSBuildProjectDirectory)\..\..
- 10.0.0
- 2.0
- False
diff --git a/src/fsharp/FSharp.Compiler.Server.Shared/Makefile.in b/src/fsharp/FSharp.Compiler.Server.Shared/Makefile.in
index 2678437354..e48bee4458 100644
--- a/src/fsharp/FSharp.Compiler.Server.Shared/Makefile.in
+++ b/src/fsharp/FSharp.Compiler.Server.Shared/Makefile.in
@@ -6,28 +6,9 @@ srcdir := @abs_srcdir@/
include @abs_top_builddir@/config.make
-FSC=$(protodir)fsc-proto.exe
-
-FLAGS += \
- $(SIGN_FLAGS) \
- --target:library
-
-REFERENCES += \
- -r:$(outdir)FSharp.Core.dll \
- -r:System.Runtime.Remoting.dll \
- -r:Mono.Security.dll
-
-sources = \
- ../../assemblyinfo/assemblyinfo.FSharp.Compiler.Server.Shared.dll.fs \
- ../fsiserver/fsiserver.fs
-
include $(topdir)/src/fsharp/targets.make
-do-final: do-4-0
-
-clean: clean-4-0
-
-install: install-lib-4 install-lib-4-5
+install: install-lib install-lib-net45
diff --git a/src/fsharp/FSharp.Compiler.Silverlight/FSharp.Compiler.Silverlight.fsproj b/src/fsharp/FSharp.Compiler.Silverlight/FSharp.Compiler.Silverlight.fsproj
index 0342bc13e6..3cc18d4be9 100644
--- a/src/fsharp/FSharp.Compiler.Silverlight/FSharp.Compiler.Silverlight.fsproj
+++ b/src/fsharp/FSharp.Compiler.Silverlight/FSharp.Compiler.Silverlight.fsproj
@@ -3,9 +3,6 @@
$(MSBuildProjectDirectory)\..\..sl5-compiler
- 10.0.0
- 2.0
- False
@@ -475,9 +472,11 @@
fsi.fs
+
diff --git a/src/fsharp/FSharp.Compiler/FSharp.Compiler.fsproj b/src/fsharp/FSharp.Compiler/FSharp.Compiler.fsproj
index 676bcf8613..7e774ff411 100644
--- a/src/fsharp/FSharp.Compiler/FSharp.Compiler.fsproj
+++ b/src/fsharp/FSharp.Compiler/FSharp.Compiler.fsproj
@@ -1,31 +1,19 @@
-
$(MSBuildProjectDirectory)\..\..
- 10.0.0
- 2.0
- FalseDebugAnyCPULibrary
- FSharp.Compiler
+ FSharp.Compiler.EditorEXTENSIONTYPING;COMPILER;INCLUDE_METADATA_READER;INCLUDE_METADATA_WRITER;EXTENSIBLE_DUMPER;TYPE_PROVIDER_SECURITY;$(DefineConstants)$(NoWarn);44;62;9{2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}true
+ v4.50x06800000$(OtherFlags) /warnon:1182
@@ -33,204 +21,207 @@
+
+ assemblyinfo.FSharp.Compiler.dll.fs
+
FSComp.txt
FSStrings.resx
-
- assemblyinfo.FSharp.Compiler.dll.fs
-
-
- --lexlib Internal.Utilities.Text.Lexing
- lex.fsl
-
-
- --lexlib Internal.Utilities.Text.Lexing
- illex.fsl
-
-
- Microsoft.FSharp.Compiler.Parser
- Microsoft.FSharp.Compiler
- --internal --lexlib Internal.Utilities.Text.Lexing --parslib Internal.Utilities.Text.Parsing
- pars.fsy
-
-
- Microsoft.FSharp.Compiler.AbstractIL.Internal.AsciiParser
- Microsoft.FSharp.Compiler.AbstractIL
- --internal --lexlib Internal.Utilities.Text.Lexing --parslib Internal.Utilities.Text.Parsing
- ilpars.fsy
-
-
- ExtensibleDumper.fsi
-
-
- ExtensibleDumper.fs
-
- sformat.fsi
+ ErrorText/sformat.fsi
- sformat.fs
+ ErrorText/sformat.fs
- sr.fsi
+ ErrorText/sr.fsi
- sr.fs
+ ErrorText/sr.fs
- prim-lexing.fsi
+ LexYaccRuntime/prim-lexing.fsi
- prim-lexing.fs
+ LexYaccRuntime/prim-lexing.fs
- prim-parsing.fsi
+ LexYaccRuntime/prim-parsing.fsi
- prim-parsing.fs
+ LexYaccRuntime/prim-parsing.fs
+
+
+ Utilities/ExtensibleDumper.fsi
+
+
+ Utilities/ExtensibleDumper.fs
- resizearray.fsi
+ Utilities/resizearray.fsi
- resizearray.fs
+ Utilities/resizearray.fs
- HashMultiMap.fsi
+ Utilities/HashMultiMap.fsi
- HashMultiMap.fs
+ Utilities/HashMultiMap.fs
- TaggedCollections.fsi
+ Utilities/TaggedCollections.fsi
- TaggedCollections.fs
+ Utilities/TaggedCollections.fs
- FlatList.fs
+ Utilities/FlatList.fs
- illib.fs
+ Utilities/illib.fs
- filename.fsi
+ Utilities/filename.fsi
- filename.fs
+ Utilities/filename.fs
- zmap.fsi
+ Utilities/zmap.fsi
- zmap.fs
+ Utilities/zmap.fs
- zset.fsi
+ Utilities/zset.fsi
- zset.fs
+ Utilities/zset.fs
- bytes.fsi
+ Utilities/bytes.fsi
- bytes.fs
+ Utilities/bytes.fs
- ildiag.fsi
+ Utilities/ildiag.fsi
- ildiag.fs
+ Utilities/ildiag.fs
+
+
+ Utilities/InternalCollections.fsi
+
+
+ Utilities/InternalCollections.fs
+
+
+ Utilities/QueueList.fs
+
+
+ Utilities/lib.fs
+
+
+ Utilities/InternalFileSystemUtils.fsi
+
+
+ Utilities/InternalFileSystemUtils.fs
+
+
+ Utilities/TraceCall.fsi
+
+
+ Utilities/TraceCall.fs
+
+
+ ErrorLogging/range.fsi
+
+
+ ErrorLogging/range.fs
+
+
+ ErrorLogging/ErrorLogger.fs
ReferenceResolution.fs
+
+ --lexlib Internal.Utilities.Text.Lexing
+ AbsIL/illex.fsl
+
+
+ Microsoft.FSharp.Compiler.AbstractIL.Internal.AsciiParser
+ Microsoft.FSharp.Compiler.AbstractIL
+ --internal --lexlib Internal.Utilities.Text.Lexing --parslib Internal.Utilities.Text.Parsing
+ AbsIL/ilpars.fsy
+
- il.fsi
+ AbsIL/il.fsi
- il.fs
+ AbsIL/il.fs
- ilx.fsi
+ AbsIL/ilx.fsi
- ilx.fs
+ AbsIL/ilx.fs
- ilascii.fsi
+ AbsIL/ilascii.fsi
- ilascii.fs
+ AbsIL/ilascii.fs
- ilprint.fsi
+ AbsIL/ilprint.fsi
- ilprint.fs
+ AbsIL/ilprint.fs
- ilmorph.fsi
+ AbsIL/ilmorph.fsi
- ilmorph.fs
+ AbsIL/ilmorph.fs
- ilsupp.fsi
+ AbsIL/ilsupp.fsi
- ilsupp.fs
+ AbsIL/ilsupp.fs
-
-
-
- ilbinary.fsi
-
-
- ilbinary.fs
+
+ AbsIL/ilpars.fs
-
- lib.fs
+
+ AbsIL/illex.fs
-
- range.fsi
-
-
- range.fs
-
-
- ErrorLogger.fs
-
-
- tainted.fsi
-
-
- tainted.fs
-
-
- InternalCollections.fsi
+
+ AbsIL/ilbinary.fsi
-
- InternalCollections.fs
+
+ AbsIL/ilbinary.fs
- ilread.fsi
+ AbsIL/ilread.fsi
- ilread.fs
+ AbsIL/ilread.fs
- ilwrite.fsi
+ AbsIL/ilwrite.fsi
- ilwrite.fs
+ AbsIL/ilwrite.fs
- ilreflect.fs
+ AbsIL/ilreflect.fs
CompilerLocationUtils.fs
@@ -239,262 +230,269 @@
PrettyNaming.fs
- ilxsettings.fs
+ ILXErase/ilxsettings.fs
- pubclo.fsi
+ ILXErase/pubclo.fsi
- pubclo.fs
+ ILXErase/pubclo.fs
- cu_erase.fsi
+ ILXErase/cu_erase.fsi
- cu_erase.fs
-
-
- InternalFileSystemUtils.fsi
-
-
- InternalFileSystemUtils.fs
+ ILXErase/cu_erase.fs
+
+ --lexlib Internal.Utilities.Text.Lexing
+ ParserAndUntypedAST/lex.fsl
+
+
+ Microsoft.FSharp.Compiler.Parser
+ Microsoft.FSharp.Compiler
+ --lexlib Internal.Utilities.Text.Lexing --parslib Internal.Utilities.Text.Parsing
+ ParserAndUntypedAST/pars.fsy
+
- unilex.fsi
+ ParserAndUntypedAST/unilex.fsi
- unilex.fs
+ ParserAndUntypedAST/unilex.fs
- layout.fsi
+ ParserAndUntypedAST/layout.fsi
- layout.fs
+ ParserAndUntypedAST/layout.fs
- ast.fs
+ ParserAndUntypedAST/ast.fs
-
- est.fsi
-
-
- est.fs
+
+ ParserAndUntypedAST/pars.fs
-
- lexhelp.fsi
+ ParserAndUntypedAST/lexhelp.fsi
- lexhelp.fs
+ ParserAndUntypedAST/lexhelp.fs
+
+
+ ParserAndUntypedAST/lex.fs
+
+
+ ParserAndUntypedAST/lexfilter.fs
+
+
+ TypedAST/tainted.fsi
+
+
+ TypedAST/tainted.fs
+
+
+ TypedAST/est.fsi
+
+
+ TypedAST/est.fs
-
- sreflect.fsi
+ TypedAST/sreflect.fsi
- sreflect.fs
-
-
- QueueList.fs
+ TypedAST/sreflect.fs
- tast.fs
+ TypedAST/tast.fs
- env.fs
+ TypedAST/env.fs
- tastops.fsi
+ TypedAST/tastops.fsi
- tastops.fs
+ TypedAST/tastops.fs
- pickle.fsi
+ TypedAST/pickle.fsi
- pickle.fs
-
-
- lexfilter.fs
+ TypedAST/pickle.fs
- import.fsi
+ Logic/import.fsi
- import.fs
+ Logic/import.fs
- infos.fs
+ Logic/infos.fs
- NicePrint.fs
+ Logic/NicePrint.fs
- augment.fsi
+ Logic/augment.fsi
- augment.fs
+ Logic/augment.fs
- outcome.fsi
+ Logic/outcome.fsi
- outcome.fs
+ Logic/outcome.fs
- nameres.fsi
+ Logic/nameres.fsi
- nameres.fs
+ Logic/nameres.fs
- typrelns.fs
+ Logic/typrelns.fs
- patcompile.fsi
+ Logic/patcompile.fsi
- patcompile.fs
+ Logic/patcompile.fs
- csolve.fsi
+ Logic/csolve.fsi
- csolve.fs
+ Logic/csolve.fs
- formats.fsi
+ Logic/formats.fsi
- formats.fs
+ Logic/formats.fs
- unsolved.fs
+ Logic/unsolved.fs
- creflect.fsi
+ Logic/creflect.fsi
- creflect.fs
+ Logic/creflect.fs
- check.fsi
+ Logic/check.fsi
- check.fs
+ Logic/check.fs
- tc.fsi
+ Logic/tc.fsi
- tc.fs
+ Logic/tc.fs
- opt.fsi
+ Optimize/opt.fsi
- opt.fs
+ Optimize/opt.fs
- detuple.fsi
+ Optimize/detuple.fsi
- detuple.fs
+ Optimize/detuple.fs
- tlr.fsi
+ Optimize/tlr.fsi
- tlr.fs
+ Optimize/tlr.fs
- lowertop.fs
+ Optimize/lowertop.fs
- ilxgen.fsi
+ CodeGen/ilxgen.fsi
- ilxgen.fs
-
-
- TraceCall.fsi
-
-
- TraceCall.fs
+ CodeGen/ilxgen.fs
- build.fsi
+ Driver/build.fsi
- build.fs
+ Driver/build.fs
- fscopts.fsi
+ Driver/fscopts.fsi
- fscopts.fs
+ Driver/fscopts.fs
- IncrementalBuild.fsi
+ Driver/IncrementalBuild.fsi
- IncrementalBuild.fs
+ Driver/IncrementalBuild.fs
- fsc.fs
+ Driver/fsc.fs
- Reactor.fsi
+ Service/Reactor.fsi
- Reactor.fs
+ Service/Reactor.fs
- ServiceLexing.fsi
+ Service/ServiceLexing.fsi
- ServiceLexing.fs
+ Service/ServiceLexing.fs
- ServiceConstants.fs
+ Service/ServiceConstants.fs
- ServiceParseTreeWalk.fs
+ Service/ServiceParseTreeWalk.fs
- ServiceNavigation.fsi
+ Service/ServiceNavigation.fsi
- ServiceNavigation.fs
+ Service/ServiceNavigation.fs
- ServiceParamInfoLocations.fsi
+ Service/ServiceParamInfoLocations.fsi
- ServiceParamInfoLocations.fs
+ Service/ServiceParamInfoLocations.fs
- ServiceUntypedParse.fsi
+ Service/ServiceUntypedParse.fsi
- ServiceUntypedParse.fs
+ Service/ServiceUntypedParse.fs
- ServiceDeclarations.fsi
+ Service/ServiceDeclarations.fsi
- ServiceDeclarations.fs
+ Service/ServiceDeclarations.fs
- service.fsi
+ Service/service.fsi
- service.fs
+ Service/service.fs
+
@@ -505,14 +503,11 @@
-
-
-
-
-
- {DED3BBD7-53F4-428A-8C9F-27968E768605}
- FSharp.Core
-
+
+
+
+
+
diff --git a/src/fsharp/FSharp.Compiler/Makefile.in b/src/fsharp/FSharp.Compiler/Makefile.in
index 67b850f173..311a75b5ec 100644
--- a/src/fsharp/FSharp.Compiler/Makefile.in
+++ b/src/fsharp/FSharp.Compiler/Makefile.in
@@ -6,203 +6,9 @@ srcdir := @abs_srcdir@/
include @abs_top_builddir@/config.make
-FSC=$(protodir)fsc-proto.exe
-
-FLAGS += \
- $(SIGN_FLAGS) \
- --target:library
-
-DEFINES += \
- --define:COMPILER \
- --define:INCLUDE_METADATA_READER \
- --define:INCLUDE_METADATA_WRITER
-
-DEFINES_4_0 += \
- --define:EXTENSIONTYPING
-
-REFERENCES += \
- -r:$(outdir)FSharp.Core.dll \
- -r:$(monogacdirXX)/System.Drawing.dll \
- -r:$(monogacdirXX)/System.Windows.Forms.dll
-
-
-sources = \
- $(tmpdir)FSComp.fs \
- ../../assemblyinfo/assemblyinfo.FSharp.Compiler.dll.fs \
- ../../utils/sformat.fsi \
- ../../utils/sformat.fs \
- ../sr.fsi \
- ../sr.fs \
- ../../utils/prim-lexing.fsi \
- ../../utils/prim-lexing.fs \
- ../../utils/prim-parsing.fsi \
- ../../utils/prim-parsing.fs \
- ../../utils/resizearray.fsi \
- ../../utils/resizearray.fs \
- ../../utils/HashMultiMap.fsi \
- ../../utils/HashMultiMap.fs \
- ../../utils/TaggedCollections.fsi \
- ../../utils/TaggedCollections.fs \
- ../FlatList.fs \
- ../../absil/illib.fs \
- ../../utils/filename.fsi \
- ../../utils/filename.fs \
- ../../absil/zmap.fsi \
- ../../absil/zmap.fs \
- ../../absil/zset.fsi \
- ../../absil/zset.fs \
- ../../absil/bytes.fsi \
- ../../absil/bytes.fs \
- ../../absil/ildiag.fsi \
- ../../absil/ildiag.fs \
- ../ReferenceResolution.fs \
- ../../absil/il.fsi \
- ../../absil/il.fs \
- ../../absil/ilx.fsi \
- ../../absil/ilx.fs \
- ../../absil/ilascii.fsi \
- ../../absil/ilascii.fs \
- ../../absil/ilprint.fsi \
- ../../absil/ilprint.fs \
- ../../absil/ilmorph.fsi \
- ../../absil/ilmorph.fs \
- ../../absil/ilsupp.fsi \
- ../../absil/ilsupp.fs \
- $(tmpdir)ilpars.fs \
- $(tmpdir)illex.fs \
- ../../absil/ilbinary.fsi \
- ../../absil/ilbinary.fs \
- ../lib.fs \
- ../range.fsi \
- ../range.fs \
- ../ErrorLogger.fs \
- ../tainted.fsi \
- ../tainted.fs \
- ../InternalCollections.fsi \
- ../InternalCollections.fs \
- ../../absil/ilread.fsi \
- ../../absil/ilread.fs \
- ../../absil/ilwrite.fsi \
- ../../absil/ilwrite.fs \
- ../../absil/ilreflect.fs \
- ../../utils/CompilerLocationUtils.fs \
- ../PrettyNaming.fs \
- ../../ilx/ilxsettings.fs \
- ../../ilx/pubclo.fsi \
- ../../ilx/pubclo.fs \
- ../../ilx/cu_erase.fsi \
- ../../ilx/cu_erase.fs \
- ../InternalFileSystemUtils.fsi \
- ../InternalFileSystemUtils.fs \
- ../unilex.fsi \
- ../unilex.fs \
- ../layout.fsi \
- ../layout.fs \
- ../ast.fs \
- ../est.fsi \
- ../est.fs \
- $(tmpdir)pars.fs \
- ../lexhelp.fsi \
- ../lexhelp.fs \
- $(tmpdir)lex.fs \
- ../sreflect.fsi \
- ../sreflect.fs \
- ../QueueList.fs \
- ../tast.fs \
- ../env.fs \
- ../tastops.fsi \
- ../tastops.fs \
- ../pickle.fsi \
- ../pickle.fs \
- ../lexfilter.fs \
- ../import.fsi \
- ../import.fs \
- ../infos.fs \
- ../NicePrint.fs \
- ../augment.fsi \
- ../augment.fs \
- ../typrelns.fs \
- ../patcompile.fsi \
- ../patcompile.fs \
- ../outcome.fsi \
- ../outcome.fs \
- ../csolve.fsi \
- ../csolve.fs \
- ../formats.fsi \
- ../formats.fs \
- ../nameres.fsi \
- ../nameres.fs \
- ../unsolved.fs \
- ../creflect.fsi \
- ../creflect.fs \
- ../check.fsi \
- ../check.fs \
- ../tc.fsi \
- ../tc.fs \
- ../opt.fsi \
- ../opt.fs \
- ../detuple.fsi \
- ../detuple.fs \
- ../tlr.fsi \
- ../tlr.fs \
- ../lowertop.fs \
- ../ilxgen.fsi \
- ../ilxgen.fs \
- ../TraceCall.fs \
- ../build.fsi \
- ../build.fs \
- ../fscopts.fsi \
- ../fscopts.fs \
- ../vs/IncrementalBuild.fsi \
- ../vs/IncrementalBuild.fs \
- ../vs/Reactor.fsi \
- ../vs/Reactor.fs \
- ../vs/ServiceLexing.fsi \
- ../vs/ServiceLexing.fs \
- ../vs/ServiceConstants.fs \
- ../vs/ServiceParseTreeWalk.fs \
- ../vs/ServiceNavigation.fsi \
- ../vs/ServiceNavigation.fs \
- ../vs/ServiceParamInfoLocations.fsi \
- ../vs/ServiceParamInfoLocations.fs \
- ../vs/ServiceUntypedParse.fsi \
- ../vs/ServiceUntypedParse.fs \
- ../vs/ServiceDeclarations.fsi \
- ../vs/ServiceDeclarations.fs \
- ../vs/service.fsi \
- ../vs/service.fs \
- ../fsc.fs
-
-RESOURCES= \
- $(tmpdir)FSStrings.resources \
- $(tmpdir)FSComp.resources
-
-$(tmpdir)FSComp.fs $(tmpdir)FSComp.resources: ../FSComp.txt
- mono $(MONO_OPTIONS) $(FSSRGEN) $< $(tmpdir)FSComp.fs $(tmpdir)FSComp.resx
- resgen $(tmpdir)FSComp.resx $(tmpdir)FSComp.resources
-
-$(tmpdir)FSStrings.resources: ../FSStrings.resx
- resgen $< $@
-
-$(tmpdir)lex.fs: ../lex.fsl
- mono $(MONO_OPTIONS) $(FSLEX) $< -o $@ --lexlib Internal.Utilities.Text.Lexing --unicode
-
-$(tmpdir)illex.fs: ../../absil/illex.fsl
- mono $(MONO_OPTIONS) $(FSLEX) $< -o $@ --lexlib Internal.Utilities.Text.Lexing --unicode
-
-$(tmpdir)pars.fs: ../pars.fsy
- mono $(MONO_OPTIONS) $(FSYACC) $< -o $@ --internal --open Microsoft.FSharp.Compiler --module Microsoft.FSharp.Compiler.Parser --lexlib Internal.Utilities.Text.Lexing --parslib Internal.Utilities.Text.Parsing | tee $@.report | grep "time"
-
-$(tmpdir)ilpars.fs: ../../absil/ilpars.fsy
- mono $(MONO_OPTIONS) $(FSYACC) $< -o $@ --internal --module Microsoft.FSharp.Compiler.AbstractIL.Internal.AsciiParser --lexlib Internal.Utilities.Text.Lexing --parslib Internal.Utilities.Text.Parsing | tee $@.report | grep "time"
-
include $(topdir)/src/fsharp/targets.make
-do-final: do-4-0
-
-clean: clean-4-0
-
-install: install-lib-4 install-lib-4-5
+install: install-lib install-lib-net45
diff --git a/src/fsharp/FSharp.Core.Unittests/FSharp.Core.Unittests.fsproj b/src/fsharp/FSharp.Core.Unittests/FSharp.Core.Unittests.fsproj
index 9eb8be852e..f565508f2d 100644
--- a/src/fsharp/FSharp.Core.Unittests/FSharp.Core.Unittests.fsproj
+++ b/src/fsharp/FSharp.Core.Unittests/FSharp.Core.Unittests.fsproj
@@ -2,8 +2,6 @@
$(MSBuildProjectDirectory)\..\..
- 10.0.0
- False
@@ -12,10 +10,10 @@
2.0truetrue
- {88E2D422-6852-46E3-A740-83E391DC7973}LibraryFSharp.Core.UnittestsSystematicUnitTests
+ {88e2d422-6852-46e3-a740-83e391dc7973}falsefalse
@@ -41,6 +39,12 @@
False
+
+
+
+ {DED3BBD7-53F4-428A-8C9F-27968E768605}
+ FSharp.Core
+
@@ -48,6 +52,10 @@
+
+
+
+ {DED3BBD7-53F4-428A-8C9F-27968E768605}
diff --git a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.2.0.fs b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.2.0.fs
index 3451ce37f6..b2d4547670 100755
--- a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.2.0.fs
+++ b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.2.0.fs
@@ -8,7 +8,10 @@ type SurfaceAreaTest() =
member this.VerifyArea() =
let file = typeof.Assembly.Location
let asm = System.Reflection.Assembly.ReflectionOnlyLoadFrom(file)
- if asm.ImageRuntimeVersion.[1] = '2' then // v2.0.50727 - we only want this test to run as 2.0 (nu20), not FSharp.Core 2.0 on CLR 4.0 (nu20on40)
+ let frameworkAsm = typeof.Assembly
+ printfn "FSharp.Core image runtime version: %s" asm.ImageRuntimeVersion
+ printfn "Framework image runtime version: %s" frameworkAsm.ImageRuntimeVersion
+ if (frameworkAsm.ImageRuntimeVersion.[1] = '2') then // v2.0.50727 - we only want this test to run as 2.0 (nu20), not FSharp.Core 2.0 on CLR 4.0 (nu20on40)
let referenced = asm.GetReferencedAssemblies()
for ref in referenced do
diff --git a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.4.0.fs b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.4.0.fs
index c820170bfd..c1d1d6dde5 100755
--- a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.4.0.fs
+++ b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.4.0.fs
@@ -2391,11 +2391,15 @@ Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T2 SqrtDynamic[T1,T2](T1)
Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,,,] GetArraySlice4D[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32])
Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,,] GetArraySlice3D[T](T[,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32])
Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,] GetArraySlice2D[T](T[,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32])
+Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[] GetArraySlice2DFixed1[T](T[,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32])
+Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[] GetArraySlice2DFixed2[T](T[,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32)
Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[] GetArraySlice[T](T[], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32])
Microsoft.FSharp.Core.Operators+OperatorIntrinsics: UInt16 PowUInt16(UInt16, Int32)
Microsoft.FSharp.Core.Operators+OperatorIntrinsics: UInt32 PowUInt32(UInt32, Int32)
Microsoft.FSharp.Core.Operators+OperatorIntrinsics: UInt64 PowUInt64(UInt64, Int32)
Microsoft.FSharp.Core.Operators+OperatorIntrinsics: UIntPtr PowUIntPtr(UIntPtr, Int32)
+Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice2DFixed1[T](T[,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[])
+Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice2DFixed2[T](T[,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, T[])
Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice2D[T](T[,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[,])
Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice3D[T](T[,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[,,])
Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4D[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[,,,])
@@ -3228,6 +3232,29 @@ Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1
Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Type] DefaultValuePattern(Microsoft.FSharp.Quotations.FSharpExpr)
Microsoft.FSharp.Quotations.PatternsModule: System.String ToString()
Microsoft.FSharp.Quotations.PatternsModule: System.Type GetType()
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Boolean Equals(System.Object)
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Boolean FSharpType.IsExceptionRepresentation.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean])
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Boolean FSharpType.IsRecord.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean])
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Boolean FSharpType.IsUnion.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean])
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Int32 GetHashCode()
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Microsoft.FSharp.Core.FSharpFunc`2[System.Object,System.Int32] FSharpValue.PreComputeUnionTagReader.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean])
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Microsoft.FSharp.Core.FSharpFunc`2[System.Object,System.Object[]] FSharpValue.PreComputeRecordReader.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean])
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Microsoft.FSharp.Core.FSharpFunc`2[System.Object,System.Object[]] FSharpValue.PreComputeUnionReader.Static(Microsoft.FSharp.Reflection.UnionCaseInfo, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean])
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Microsoft.FSharp.Core.FSharpFunc`2[System.Object[],System.Object] FSharpValue.PreComputeRecordConstructor.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean])
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Microsoft.FSharp.Core.FSharpFunc`2[System.Object[],System.Object] FSharpValue.PreComputeUnionConstructor.Static(Microsoft.FSharp.Reflection.UnionCaseInfo, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean])
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Microsoft.FSharp.Reflection.UnionCaseInfo[] FSharpType.GetUnionCases.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean])
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Object FSharpValue.MakeRecord.Static(System.Type, System.Object[], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean])
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Object FSharpValue.MakeUnion.Static(Microsoft.FSharp.Reflection.UnionCaseInfo, System.Object[], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean])
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Object[] FSharpValue.GetExceptionFields.Static(System.Object, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean])
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Object[] FSharpValue.GetRecordFields.Static(System.Object, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean])
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Reflection.ConstructorInfo FSharpValue.PreComputeRecordConstructorInfo.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean])
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Reflection.MemberInfo FSharpValue.PreComputeUnionTagMemberInfo.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean])
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Reflection.MethodInfo FSharpValue.PreComputeUnionConstructorInfo.Static(Microsoft.FSharp.Reflection.UnionCaseInfo, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean])
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Reflection.PropertyInfo[] FSharpType.GetExceptionFields.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean])
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Reflection.PropertyInfo[] FSharpType.GetRecordFields.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean])
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.String ToString()
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Tuple`2[Microsoft.FSharp.Reflection.UnionCaseInfo,System.Object[]] FSharpValue.GetUnionFields.Static(System.Object, System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean])
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Type GetType()
Microsoft.FSharp.Reflection.FSharpType: Boolean Equals(System.Object)
Microsoft.FSharp.Reflection.FSharpType: Boolean IsExceptionRepresentation(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags])
Microsoft.FSharp.Reflection.FSharpType: Boolean IsFunction(System.Type)
diff --git a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.Portable.fs b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.Portable.fs
index a318a8d472..b5902bf002 100755
--- a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.Portable.fs
+++ b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.Portable.fs
@@ -2378,11 +2378,15 @@ Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T2 SqrtDynamic[T1,T2](T1)
Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,,,] GetArraySlice4D[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32])
Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,,] GetArraySlice3D[T](T[,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32])
Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,] GetArraySlice2D[T](T[,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32])
+Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[] GetArraySlice2DFixed1[T](T[,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32])
+Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[] GetArraySlice2DFixed2[T](T[,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32)
Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[] GetArraySlice[T](T[], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32])
Microsoft.FSharp.Core.Operators+OperatorIntrinsics: UInt16 PowUInt16(UInt16, Int32)
Microsoft.FSharp.Core.Operators+OperatorIntrinsics: UInt32 PowUInt32(UInt32, Int32)
Microsoft.FSharp.Core.Operators+OperatorIntrinsics: UInt64 PowUInt64(UInt64, Int32)
Microsoft.FSharp.Core.Operators+OperatorIntrinsics: UIntPtr PowUIntPtr(UIntPtr, Int32)
+Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice2DFixed1[T](T[,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[])
+Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice2DFixed2[T](T[,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, T[])
Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice2D[T](T[,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[,])
Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice3D[T](T[,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[,,])
Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4D[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[,,,])
@@ -3206,6 +3210,29 @@ Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1
Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Type] DefaultValuePattern(Microsoft.FSharp.Quotations.FSharpExpr)
Microsoft.FSharp.Quotations.PatternsModule: System.String ToString()
Microsoft.FSharp.Quotations.PatternsModule: System.Type GetType()
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Boolean Equals(System.Object)
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Boolean FSharpType.IsExceptionRepresentation.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean])
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Boolean FSharpType.IsRecord.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean])
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Boolean FSharpType.IsUnion.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean])
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Int32 GetHashCode()
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Microsoft.FSharp.Core.FSharpFunc`2[System.Object,System.Int32] FSharpValue.PreComputeUnionTagReader.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean])
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Microsoft.FSharp.Core.FSharpFunc`2[System.Object,System.Object[]] FSharpValue.PreComputeRecordReader.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean])
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Microsoft.FSharp.Core.FSharpFunc`2[System.Object,System.Object[]] FSharpValue.PreComputeUnionReader.Static(Microsoft.FSharp.Reflection.UnionCaseInfo, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean])
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Microsoft.FSharp.Core.FSharpFunc`2[System.Object[],System.Object] FSharpValue.PreComputeRecordConstructor.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean])
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Microsoft.FSharp.Core.FSharpFunc`2[System.Object[],System.Object] FSharpValue.PreComputeUnionConstructor.Static(Microsoft.FSharp.Reflection.UnionCaseInfo, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean])
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Microsoft.FSharp.Reflection.UnionCaseInfo[] FSharpType.GetUnionCases.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean])
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Object FSharpValue.MakeRecord.Static(System.Type, System.Object[], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean])
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Object FSharpValue.MakeUnion.Static(Microsoft.FSharp.Reflection.UnionCaseInfo, System.Object[], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean])
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Object[] FSharpValue.GetExceptionFields.Static(System.Object, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean])
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Object[] FSharpValue.GetRecordFields.Static(System.Object, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean])
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Reflection.ConstructorInfo FSharpValue.PreComputeRecordConstructorInfo.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean])
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Reflection.MemberInfo FSharpValue.PreComputeUnionTagMemberInfo.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean])
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Reflection.MethodInfo FSharpValue.PreComputeUnionConstructorInfo.Static(Microsoft.FSharp.Reflection.UnionCaseInfo, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean])
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Reflection.PropertyInfo[] FSharpType.GetExceptionFields.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean])
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Reflection.PropertyInfo[] FSharpType.GetRecordFields.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean])
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.String ToString()
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Tuple`2[Microsoft.FSharp.Reflection.UnionCaseInfo,System.Object[]] FSharpValue.GetUnionFields.Static(System.Object, System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean])
+Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Type GetType()
Microsoft.FSharp.Reflection.FSharpType: Boolean Equals(System.Object)
Microsoft.FSharp.Reflection.FSharpType: Boolean IsExceptionRepresentation(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags])
Microsoft.FSharp.Reflection.FSharpType: Boolean IsFunction(System.Type)
diff --git a/src/fsharp/FSharp.Core.Unittests/TypeForwarding.fs b/src/fsharp/FSharp.Core.Unittests/TypeForwarding.fs
index d3ec6792b8..a9bbb7cf77 100755
--- a/src/fsharp/FSharp.Core.Unittests/TypeForwarding.fs
+++ b/src/fsharp/FSharp.Core.Unittests/TypeForwarding.fs
@@ -16,15 +16,20 @@ type TypeForwardingModule() =
[]
member this.TypeForwarding() =
let currentRuntimeVersion = System.Runtime.InteropServices.RuntimeEnvironment.GetSystemVersion()
+ let currentFSharpCoreTargetRuntime = typeof.Assembly.ImageRuntimeVersion
let tupleAssemblyName = typeof>.Assembly.FullName
- let mscorlibAssemblyName = "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
- let fsharpCoreAssemblyName = "FSharp.Core, Version=2.3.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
- // 2.0 runtime
- if currentRuntimeVersion = "v2.0.50727" then
- Assert.AreEqual(tupleAssemblyName, fsharpCoreAssemblyName)
- else
- Assert.AreEqual(tupleAssemblyName, mscorlibAssemblyName)
+ let mscorlib4AssemblyName = "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
+ let fsharpCore2AssemblyName = "FSharp.Core, Version=2.3.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
+
+ printfn "currentRuntimeVersion = %s; currentFSharpCoreTargetRuntime=%s tupleAssemblyName=%s" currentRuntimeVersion currentFSharpCoreTargetRuntime tupleAssemblyName
+ match (currentRuntimeVersion, currentFSharpCoreTargetRuntime) with
+ | ("v2.0.50727", _)
+ | ("v4.0.30319", "v2.0.50727") ->
+ Assert.AreEqual(tupleAssemblyName, fsharpCore2AssemblyName)
+ | ("v4.0.30319", "v4.0.30319") ->
+ Assert.AreEqual(tupleAssemblyName, mscorlib4AssemblyName)
+ | _ -> failwith "Unknown scenario."
()
#endif
#endif
\ No newline at end of file
diff --git a/src/fsharp/FSharp.Core/FSharp.Core.fsproj b/src/fsharp/FSharp.Core/FSharp.Core.fsproj
index e758e7b935..2108613d2f 100644
--- a/src/fsharp/FSharp.Core/FSharp.Core.fsproj
+++ b/src/fsharp/FSharp.Core/FSharp.Core.fsproj
@@ -1,20 +1,7 @@
-
$(MSBuildProjectDirectory)\..\..
- 10.0.0
- 2.0
- False
@@ -32,7 +19,8 @@
truev2.0$(OtherFlags) --warnon:1182 --compiling-fslib --optimize --maxerrors:20 --extraoptimizationloops:1
- $(OtherFlags) --compiling-fslib-20:"$(SystemRoot)\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll"
+ $(OtherFlags) --compiling-fslib-20:"$(SystemRoot)\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll"
+ $(OtherFlags) --compiling-fslib-20:"$(MonoLibDir40)/mscorlib.dll" $(OtherFlags) --compiling-fslib-40
@@ -43,166 +31,166 @@
FSCore.resx
- prim-types-prelude.fsi
+ Primitives/prim-types-prelude.fsi
- prim-types-prelude.fs
+ Primitives/prim-types-prelude.fs
- SR.fs
+ Primitives/SR.fs
- prim-types.fsi
+ Primitives/prim-types.fsi
- prim-types.fs
+ Primitives/prim-types.fs
- local.fsi
+ Collections/local.fsi
- local.fs
+ Collections/local.fs
- array2.fsi
+ Collections/array2.fsi
- array2.fs
+ Collections/array2.fs
- option.fsi
+ Collections/option.fsi
- option.fs
+ Collections/option.fs
- collections.fsi
+ Collections/collections.fsi
- collections.fs
+ Collections/collections.fs
- seq.fsi
+ Collections/seq.fsi
- seq.fs
+ Collections/seq.fs
- string.fsi
+ Collections/string.fsi
- string.fs
+ Collections/string.fs
- list.fsi
+ Collections/list.fsi
- list.fs
+ Collections/list.fs
- array.fsi
+ Collections/array.fsi
- array.fs
+ Collections/array.fs
- array3.fsi
+ Collections/array3.fsi
- array3.fs
+ Collections/array3.fs
- map.fsi
+ Collections/map.fsi
- map.fs
+ Collections/map.fs
- set.fsi
+ Collections/set.fsi
- set.fs
+ Collections/set.fs
- reflect.fsi
+ Reflection/reflect.fsi
- reflect.fs
+ Reflection/reflect.fs
- event.fsi
+ Event/event.fsi
- event.fs
+ Event/event.fs
- sformat.fsi
+ Printf/sformat.fsi
- sformat.fs
+ Printf/sformat.fs
- printf.fsi
+ Printf/printf.fsi
- printf.fs
+ Printf/printf.fs
- quotations.fsi
+ Quotations/quotations.fsi
- quotations.fs
+ Quotations/quotations.fs
- nativeptr.fsi
+ NativeInterop/nativeptr.fsi
- nativeptr.fs
+ NativeInterop/nativeptr.fs
- control.fsi
+ Async/control.fsi
- control.fs
+ Async/control.fs
- Linq.fsi
+ Queries/Linq.fsi
- Linq.fs
+ Queries/Linq.fs
- MutableTuple.fs
+ Queries/MutableTuple.fs
- QueryExtensions.fs
+ Queries/QueryExtensions.fs
- Query.fsi
+ Queries/Query.fsi
- Query.fs
+ Queries/Query.fs
- SI.fs
+ Units/SI.fs
- n.fsi
+ Numerics/n.fsi
- n.fs
+ Numerics/n.fs
- z.fsi
+ Numerics/z.fsi
- z.fs
+ Numerics/z.fs
- fslib-extra-pervasives.fsi
+ Extras/fslib-extra-pervasives.fsi
- fslib-extra-pervasives.fs
+ Extras/fslib-extra-pervasives.fs
assemblyinfo.FSharp.Core.dll.fs
@@ -212,12 +200,13 @@
-
+
+
-
+
-
+
diff --git a/src/fsharp/FSharp.Core/Linq.fs b/src/fsharp/FSharp.Core/Linq.fs
index 47622ba77f..bd1f0c477b 100755
--- a/src/fsharp/FSharp.Core/Linq.fs
+++ b/src/fsharp/FSharp.Core/Linq.fs
@@ -151,6 +151,11 @@ open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Quotations.Patterns
open Microsoft.FSharp.Quotations.DerivedPatterns
+#if FX_RESHAPED_REFLECTION
+open PrimReflectionAdapters
+open ReflectionAdapters
+#endif
+
module LeafExpressionConverter =
// The following is recognized as a LINQ 'member intialization pattern' in a quotation.
@@ -197,7 +202,12 @@ module LeafExpressionConverter =
let d = Map.ofArray (Array.zip x y)
q.Substitute(fun v -> v |> d.TryFind |> Option.map (fun x -> Expr.Value(x, v.Type))) |> Expr.Cast
- let showAll = BindingFlags.Public ||| BindingFlags.NonPublic
+ let showAll =
+#if FX_RESHAPED_REFLECTION
+ true
+#else
+ BindingFlags.Public ||| BindingFlags.NonPublic
+#endif
let NullableConstructor = typedefof>.GetConstructors().[0]
@@ -212,7 +222,7 @@ module LeafExpressionConverter =
#if FX_NO_REFLECTION_METADATA_TOKENS
#else
minfo.MetadataToken = minfo2.MetadataToken &&
-#endif
+#endif
if isg1 then minfo2.IsGenericMethod && gmd = minfo2.GetGenericMethodDefinition()
else minfo = minfo2
) ->
@@ -403,20 +413,10 @@ module LeafExpressionConverter =
| Patterns.Coerce(x, toTy) ->
let converted = ConvExprToLinqInContext env x
- // Linq to Entities doesn't like 'TypeAs' expressions (coercion from
- // IQueryable to IEnumerable) that are generated e.g. in:
- //
- // seq { for p in dx.Products do
- // for c in dx.Categories do yield p }
- //
- // However, the expression tree has 'C# semantics' so we don't need
- // explicit TypeAs if the coercion is statically type-safe. The rules are subtle,
- // so we don't generate TypeAs (at least) in a simple case when both are
- // reference types and the assignment is statically safe.
- // (see also ``Join using nested 'for' with 'String.Concat' call`` test in v40 build)
-
- if not toTy.IsValueType && not x.Type.IsValueType && toTy.IsAssignableFrom(x.Type) then converted
- else Expression.TypeAs(ConvExprToLinqInContext env x, toTy) |> asExpr
+ // Most of conversion scenarios in C# are covered by Expression.Convert
+ if x.Type.Equals toTy then converted // source and target types match - do nothing
+ elif not (x.Type.IsValueType || toTy.IsValueType) && toTy.IsAssignableFrom x.Type then converted // converting reference type to supertype - do nothing
+ else Expression.Convert(converted, toTy) |> asExpr // emit Expression.Convert
| Patterns.TypeTest(x, toTy) ->
Expression.TypeIs(ConvExprToLinqInContext env x, toTy) |> asExpr
@@ -733,15 +733,19 @@ module LeafExpressionConverter =
| Patterns.Lambda(v, body) ->
let vP = ConvVarToLinq v
let env = { env with varEnv = Map.add v (vP |> asExpr) env.varEnv }
+ let bodyP = ConvExprToLinqInContext env body
+ let lambdaTy, tyargs =
+ if bodyP.Type = typeof then
+ let tyargs = [| vP.Type |]
+ typedefof>, tyargs
+ else
+ let tyargs = [| vP.Type; bodyP.Type |]
#if FX_NO_CONVERTER
- let tyargs = [| v.Type; body.Type |]
- let bodyP = ConvExprToLinqInContext env body
- let convType = typedefof>.MakeGenericType tyargs
+ typedefof>, tyargs
#else
- let tyargs = [| v.Type; body.Type |]
- let bodyP = ConvExprToLinqInContext env body
- let convType = typedefof>.MakeGenericType tyargs
+ typedefof>, tyargs
#endif
+ let convType = lambdaTy.MakeGenericType tyargs
let convDelegate = Expression.Lambda(convType, bodyP, [| vP |]) |> asExpr
Expression.Call(typeof,"ToFSharpFunc", tyargs,[| convDelegate |]) |> asExpr
diff --git a/src/fsharp/FSharp.Core/Makefile.in b/src/fsharp/FSharp.Core/Makefile.in
index b05173688b..c6dd33d3b2 100644
--- a/src/fsharp/FSharp.Core/Makefile.in
+++ b/src/fsharp/FSharp.Core/Makefile.in
@@ -7,106 +7,8 @@ srcdir := @abs_srcdir@/
include @abs_top_builddir@/config.make
-FSC=$(protodir)fsc-proto.exe
-
-FLAGS_2_0 += \
- $(DELAY_SIGN_FLAGS) \
- --compiling-fslib \
- --nowarn:75,1204 \
- --target:library \
- --compiling-fslib-20:$(monogacdir40)/mscorlib.dll \
- --extraoptimizationloops:1
-
-FLAGS_2_1 += \
- $(DELAY_SIGN_FLAGS) \
- --compiling-fslib \
- --nowarn:75,1204 \
- --target:library \
- --extraoptimizationloops:1
-
-FLAGS_4_0 += \
- $(DELAY_SIGN_FLAGS) \
- --compiling-fslib \
- --nowarn:75,1204 \
- --target:library \
- --compiling-fslib-40 \
- --define:BE_SECURITY_TRANSPARENT \
- --define:QUERIES_IN_FSLIB \
- --define:PUT_TYPE_PROVIDERS_IN_FSCORE \
- --extraoptimizationloops:1
-
-DEFINES += \
- --define:RUNTIME
-
-sources = \
- prim-types-prelude.fsi \
- prim-types-prelude.fs \
- SR.fs \
- prim-types.fsi \
- prim-types.fs \
- local.fsi \
- local.fs \
- array2.fsi \
- array2.fs \
- option.fsi \
- option.fs \
- collections.fsi \
- collections.fs \
- seq.fsi \
- seq.fs \
- string.fsi \
- string.fs \
- list.fsi \
- list.fs \
- array.fsi \
- array.fs \
- array3.fsi \
- array3.fs \
- map.fsi \
- map.fs \
- set.fsi \
- set.fs \
- reflect.fsi \
- reflect.fs \
- event.fsi \
- event.fs \
- math/n.fsi \
- math/n.fs \
- math/z.fsi \
- math/z.fs \
- ../../utils/sformat.fsi \
- ../../utils/sformat.fs \
- printf.fsi \
- printf.fs \
- quotations.fsi \
- quotations.fs \
- nativeptr.fsi \
- nativeptr.fs \
- control.fsi \
- control.fs \
- Linq.fsi \
- Linq.fs \
- MutableTuple.fs \
- QueryExtensions.fs \
- Query.fsi \
- Query.fs \
- SI.fs \
- fslib-extra-pervasives.fsi \
- fslib-extra-pervasives.fs \
- ../../assemblyinfo/assemblyinfo.FSharp.Core.dll.fs
-
-RESOURCES = \
- $(tmpdir)FSCore.resources
-
-$(tmpdir)FSCore.resources: FSCore.resx
- resgen $< $@
-
include $(topdir)/src/fsharp/targets.make
-do-final: do-4-0 do-2-0 do-2-1
-
-clean: clean-4-0 clean-2-0 clean-2-1
-
-install: install-lib-4 install-lib-4-5 install-lib-2 install-lib-2-1
+install: install-lib install-lib-net45
diff --git a/src/fsharp/FSharp.Core/Query.fs b/src/fsharp/FSharp.Core/Query.fs
index 69752f5aab..b1b8f5be74 100755
--- a/src/fsharp/FSharp.Core/Query.fs
+++ b/src/fsharp/FSharp.Core/Query.fs
@@ -12,25 +12,13 @@ open System
open System.Linq
open System.Collections
open System.Collections.Generic
-open System.Linq.Expressions
-open System.Reflection
-#if FX_NO_REFLECTION_EMIT
-#else
-open System.Reflection.Emit
-#endif
+
open Microsoft.FSharp
open Microsoft.FSharp.Core
open Microsoft.FSharp.Core.Operators
-open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators
open Microsoft.FSharp.Collections
-open Microsoft.FSharp.Reflection
-open Microsoft.FSharp.Linq
-open Microsoft.FSharp.Linq.RuntimeHelpers.Adapters
-open Microsoft.FSharp.Linq.RuntimeHelpers
-open Microsoft.FSharp.Linq.RuntimeHelpers.LeafExpressionConverter
open Microsoft.FSharp.Quotations
-open Microsoft.FSharp.Quotations.Patterns
-open Microsoft.FSharp.Quotations.DerivedPatterns
+open Microsoft.FSharp.Linq.RuntimeHelpers
#nowarn "64"
@@ -40,7 +28,6 @@ type QuerySource<'T, 'Q> (source: seq<'T>) =
[]
module Helpers =
-
// This helps the somewhat complicated type inference for AverageByNullable and SumByNullable, by making both type in a '+' the same
let inline plus (x:'T) (y:'T) = Checked.(+) x y
@@ -54,9 +41,21 @@ module Helpers =
match source with
| :? System.Linq.IOrderedEnumerable<'T> as source -> source
| _ -> invalidArg "source" (SR.GetString(SR.thenByError))
+
+
+// used so we can define the implementation of QueryBuilder before the Query module (so in Query we can safely use methodhandleof)
+module ForwardDeclarations =
+ type IQueryMethods =
+ abstract Execute : Expr<'T> -> 'U
+ abstract EliminateNestedQueries : Expr -> Expr
+ let mutable Query =
+ {
+ new IQueryMethods with
+ member this.Execute(_) = failwith "IQueryMethods.Execute should never be called"
+ member this.EliminateNestedQueries(_) = failwith "IQueryMethods.EliminateNestedQueries should never be called"
+ }
type QueryBuilder() =
-
member __.For (source:QuerySource<'T,'Q>, body: 'T -> QuerySource<'Result,'Q2>) : QuerySource<'Result,'Q> = QuerySource (Seq.collect (fun x -> (body x).Source) source.Source)
member __.Zero () = QuerySource Seq.empty
member __.Yield x = QuerySource (Seq.singleton x)
@@ -207,6 +206,64 @@ type QueryBuilder() =
member __.LeftOuterJoin (outerSource:QuerySource<_,'Q>, innerSource: QuerySource<_,'Q>, outerKeySelector, innerKeySelector, elementSelector: _ -> seq<_> -> _) : QuerySource<_,'Q> =
QuerySource (System.Linq.Enumerable.GroupJoin(outerSource.Source, innerSource.Source, Func<_,_>(outerKeySelector), Func<_,_>(innerKeySelector), Func<_,_,_>(fun x g -> elementSelector x (g.DefaultIfEmpty()))))
+ member __.RunQueryAsValue (q:Quotations.Expr<'T>) : 'T = ForwardDeclarations.Query.Execute q
+
+ member __.RunQueryAsEnumerable (q:Quotations.Expr>) : IEnumerable<'T> =
+ let queryAfterEliminatingNestedQueries = ForwardDeclarations.Query.EliminateNestedQueries q
+ let queryAfterCleanup = Microsoft.FSharp.Linq.RuntimeHelpers.Adapters.CleanupLeaf queryAfterEliminatingNestedQueries
+ (LeafExpressionConverter.EvaluateQuotation queryAfterCleanup :?> QuerySource<'T,IEnumerable>).Source
+
+ member __.RunQueryAsQueryable (q:Quotations.Expr>) : IQueryable<'T> = ForwardDeclarations.Query.Execute q
+ member this.Run q = this.RunQueryAsQueryable q
+
+namespace Microsoft.FSharp.Linq.QueryRunExtensions
+
+ open Microsoft.FSharp.Core
+
+ []
+ module LowPriority =
+ type Microsoft.FSharp.Linq.QueryBuilder with
+ []
+ member this.Run (q: Microsoft.FSharp.Quotations.Expr<'T>) = this.RunQueryAsValue q
+
+ []
+ module HighPriority =
+ type Microsoft.FSharp.Linq.QueryBuilder with
+ []
+ member this.Run (q: Microsoft.FSharp.Quotations.Expr>) = this.RunQueryAsEnumerable q
+
+namespace Microsoft.FSharp.Linq
+
+open System
+open System.Linq
+open System.Collections
+open System.Collections.Generic
+open System.Linq.Expressions
+open System.Reflection
+#if FX_NO_REFLECTION_EMIT
+#else
+open System.Reflection.Emit
+#endif
+open Microsoft.FSharp
+open Microsoft.FSharp.Core
+open Microsoft.FSharp.Core.Operators
+open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators
+open Microsoft.FSharp.Collections
+open Microsoft.FSharp.Reflection
+open Microsoft.FSharp.Linq
+open Microsoft.FSharp.Linq.RuntimeHelpers.Adapters
+open Microsoft.FSharp.Linq.RuntimeHelpers
+open Microsoft.FSharp.Linq.RuntimeHelpers.LeafExpressionConverter
+open Microsoft.FSharp.Quotations
+open Microsoft.FSharp.Quotations.Patterns
+open Microsoft.FSharp.Quotations.DerivedPatterns
+
+open Microsoft.FSharp.Linq.QueryRunExtensions
+
+#if FX_RESHAPED_REFLECTION
+open PrimReflectionAdapters
+open ReflectionAdapters
+#endif
[]
module Query =
@@ -940,10 +997,11 @@ module Query =
| MacroReduction reduced -> Some (walk reduced)
| _ -> None)
-
- let (|CallQueryBuilderRunQueryable|_|) : Quotations.Expr -> _ = (|SpecificCallToMethod|_|) (typeof.GetMethod("Run").MethodHandle)
- let (|CallQueryBuilderRunValue|_|) : Quotations.Expr -> _ = (|SpecificCallToMethod|_|) (typeof.Assembly.GetType("Microsoft.FSharp.Linq.QueryRunExtensions.LowPriority").GetMethod("RunQueryAsValue").MethodHandle)
- let (|CallQueryBuilderRunEnumerable|_|) : Quotations.Expr -> _ = (|SpecificCallToMethod|_|) (typeof.Assembly.GetType("Microsoft.FSharp.Linq.QueryRunExtensions.HighPriority").GetMethod("RunQueryAsEnumerable").MethodHandle)
+ let (|CallQueryBuilderRunQueryable|_|) : Quotations.Expr -> _ = (|SpecificCallToMethod|_|) (methodhandleof (fun (b :QueryBuilder, v) -> b.Run(v)))
+ // (typeof.Assembly.GetType("Microsoft.FSharp.Linq.QueryRunExtensions.LowPriority").GetMethod("RunQueryAsValue").MethodHandle)
+ let (|CallQueryBuilderRunValue|_|) : Quotations.Expr -> _ = (|SpecificCallToMethod|_|) (methodhandleof (fun (b : QueryBuilder, v : Expr<'a>) -> b.Run(v)) : 'a) // type annotations here help overload resolution
+ // (typeof.Assembly.GetType("Microsoft.FSharp.Linq.QueryRunExtensions.HighPriority").GetMethod("RunQueryAsEnumerable").MethodHandle)
+ let (|CallQueryBuilderRunEnumerable|_|) : Quotations.Expr -> _ = (|SpecificCallToMethod|_|) (methodhandleof (fun (b : QueryBuilder, v : Expr> ) -> b.Run(v))) // type annotations here help overload resolution
let (|CallQueryBuilderFor|_|) : Quotations.Expr -> _ = (|SpecificCallToMethod|_|) (methodhandleof (fun (b:QueryBuilder,source:QuerySource,body) -> b.For(source,body)))
let (|CallQueryBuilderYield|_|) : Quotations.Expr -> _ = (|SpecificCall1|_|) (methodhandleof (fun (b:QueryBuilder,value) -> b.Yield value))
let (|CallQueryBuilderYieldFrom|_|) : Quotations.Expr -> _ = (|SpecificCallToMethod|_|) (methodhandleof (fun (b:QueryBuilder,values) -> b.YieldFrom values))
@@ -1493,7 +1551,7 @@ module Query =
let mutVar, mutToImmutSelector = ConvertImmutableConsumerToMutableConsumer sourceConv (immutVar, Expr.Var immutVar)
let immutExprEnumerable = MakeSelect(CanEliminate.Yes, false, mutSource, mutVar, mutToImmutSelector)
let mustReturnIQueryable =
- IsQuerySourceTy immutSourceTy && qTyIsIQueryable (immutSourceTy.GetGenericArguments().[0]) ||
+ IsQuerySourceTy immutSourceTy && qTyIsIQueryable (immutSourceTy.GetGenericArguments().[1]) ||
IsIQueryableTy immutSourceTy
let immutExprFinal =
if mustReturnIQueryable then MakeAsQueryable(immutSourceElemTy,immutExprEnumerable)
@@ -1679,37 +1737,12 @@ module Query =
// We use Unchecked.unbox to allow headOrDefault, lastOrDefault and exactlyOneOrDefault to return Uncehcked.defaultof<_> values for F# types
Unchecked.unbox (EvalNonNestedOuter CanEliminate.No p)
-
-type QueryBuilder with
- member __.RunQueryAsValue (q:Quotations.Expr<'T>) : 'T = Query.QueryExecute q
-
- member __.RunQueryAsEnumerable (q:Quotations.Expr>) : IEnumerable<'T> =
- let queryAfterEliminatingNestedQueries = Query.EliminateNestedQueries q
- let queryAfterCleanup = Microsoft.FSharp.Linq.RuntimeHelpers.Adapters.CleanupLeaf queryAfterEliminatingNestedQueries
- (LeafExpressionConverter.EvaluateQuotation queryAfterCleanup :?> QuerySource<'T,IEnumerable>).Source
-
- member __.RunQueryAsQueryable (q:Quotations.Expr>) : IQueryable<'T> = Query.QueryExecute q
- member this.Run q = this.RunQueryAsQueryable q
-
-
-
-namespace Microsoft.FSharp.Linq.QueryRunExtensions
-
- open Microsoft.FSharp.Core
-
- []
- module LowPriority =
- type Microsoft.FSharp.Linq.QueryBuilder with
- []
- member this.Run (q: Microsoft.FSharp.Quotations.Expr<'T>) = this.RunQueryAsValue q
-
- []
- module HighPriority =
- type Microsoft.FSharp.Linq.QueryBuilder with
- []
- member this.Run (q: Microsoft.FSharp.Quotations.Expr>) = this.RunQueryAsEnumerable q
-
-
+ do ForwardDeclarations.Query <-
+ {
+ new ForwardDeclarations.IQueryMethods with
+ member this.Execute(q) = QueryExecute q
+ member this.EliminateNestedQueries(e) = EliminateNestedQueries e
+ }
#endif
diff --git a/src/fsharp/FSharp.Core/QueryExtensions.fs b/src/fsharp/FSharp.Core/QueryExtensions.fs
index 6ebbbff2af..1038f4064c 100755
--- a/src/fsharp/FSharp.Core/QueryExtensions.fs
+++ b/src/fsharp/FSharp.Core/QueryExtensions.fs
@@ -22,6 +22,10 @@ open System.Collections.Generic
open System.Linq
open System.Linq.Expressions
+#if FX_RESHAPED_REFLECTION
+open PrimReflectionAdapters
+open ReflectionAdapters
+#endif
// ----------------------------------------------------------------------------
@@ -194,7 +198,11 @@ module internal Adapters =
let (|RecordFieldGetSimplification|_|) (expr:Expr) =
match expr with
| Patterns.PropertyGet(Some (Patterns.NewRecord(typ,els)),propInfo,[]) ->
+#if FX_RESHAPED_REFLECTION
+ let fields = Microsoft.FSharp.Reflection.FSharpType.GetRecordFields(typ, true)
+#else
let fields = Microsoft.FSharp.Reflection.FSharpType.GetRecordFields(typ,System.Reflection.BindingFlags.Public|||System.Reflection.BindingFlags.NonPublic)
+#endif
match fields |> Array.tryFindIndex (fun p -> p = propInfo) with
| None -> None
| Some i -> if i < els.Length then Some els.[i] else None
diff --git a/src/fsharp/FSharp.Core/SR.fs b/src/fsharp/FSharp.Core/SR.fs
index a90ecb40a7..e09caba29f 100755
--- a/src/fsharp/FSharp.Core/SR.fs
+++ b/src/fsharp/FSharp.Core/SR.fs
@@ -1,7 +1,13 @@
namespace Microsoft.FSharp.Core
module internal SR =
+#if FX_RESHAPED_REFLECTION
+ open System.Reflection
+ type TypeInThisAssembly(_dummy : obj) = class end
+ let private resources = new System.Resources.ResourceManager("FSCore", TypeInThisAssembly(null).GetType().GetTypeInfo().Assembly)
+#else
let private resources = new System.Resources.ResourceManager("FSCore", System.Reflection.Assembly.GetExecutingAssembly())
+#endif
let matchCasesIncomplete = "matchCasesIncomplete"
let resetNotSupported = "resetNotSupported"
diff --git a/src/fsharp/FSharp.Core/control.fs b/src/fsharp/FSharp.Core/control.fs
index 737c0f560e..64b925aae2 100755
--- a/src/fsharp/FSharp.Core/control.fs
+++ b/src/fsharp/FSharp.Core/control.fs
@@ -307,6 +307,13 @@ namespace Microsoft.FSharp.Control
open Microsoft.FSharp.Control
open Microsoft.FSharp.Collections
+#if FX_RESHAPED_REFLECTION
+ open ReflectionAdapters
+ type BindingFlags = ReflectionAdapters.BindingFlags
+#else
+ type BindingFlags = System.Reflection.BindingFlags
+#endif
+
#if FX_NO_TASK
#else
open System.Threading
@@ -465,6 +472,34 @@ namespace Microsoft.FSharp.Control
cont <- Some action
| _ -> failwith "Internal error: attempting to install continuation twice"
+
+#if FSHARP_CORE_NETCORE_PORTABLE
+ // Imitation of desktop functionality for .NETCore
+ // 1. QueueUserWorkItem reimplemented as Task.Run
+ // 2. Thread.CurrentThread type in the code is typically used to check if continuation is called on the same thread that initiated the async computation
+ // if this condition holds we may decide to invoke continuation directly rather than queueing it.
+ // Thread type here is barely a wrapper over CurrentManagedThreadId value - it should be enough to uniquely identify the actual thread
+
+ []
+ type internal WaitCallback = WaitCallback of (obj -> unit)
+
+ type ThreadPool =
+ static member QueueUserWorkItem(WaitCallback(cb), state : obj) =
+ System.Threading.Tasks.Task.Run (fun () -> cb(state)) |> ignore
+ true
+
+ []
+ type Thread(threadId : int) =
+ static member CurrentThread = Thread(Environment.CurrentManagedThreadId)
+ member this.ThreadId = threadId
+ override this.GetHashCode() = threadId
+ override this.Equals(other : obj) =
+ match other with
+ | :? Thread as other -> threadId = other.ThreadId
+ | _ -> false
+
+#endif
+
type TrampolineHolder() as this =
let mutable trampoline = null
@@ -865,8 +900,6 @@ namespace Microsoft.FSharp.Control
bindA p1 (fun () -> p2)
-
-
open AsyncBuilderImpl
[]
@@ -1295,9 +1328,11 @@ namespace Microsoft.FSharp.Control
static member CancelDefaultToken() =
let cts = !defaultCancellationTokenSource
- cts.Cancel()
+ // set new CancellationTokenSource before calling Cancel - otherwise if Cancel throws token will stay unchanged
defaultCancellationTokenSource := new CancellationTokenSource()
// we do not dispose the old default CTS - let GC collect it
+ cts.Cancel()
+ // we do not dispose the old default CTS - let GC collect it
static member Catch (p: Async<'T>) =
unprotectedPrimitive (fun ({ aux = aux } as args) ->
@@ -1347,7 +1382,8 @@ namespace Microsoft.FSharp.Control
let trampolineHolder = aux.trampolineHolder
let finishTask(remaining) =
- if (remaining=0) then
+ if (remaining = 0) then
+ innerCTS.Dispose()
match (!firstExn) with
| None -> trampolineHolder.Protect(fun () -> args.cont results)
| Some (Choice1Of2 exn) -> trampolineHolder.Protect(fun () -> aux.econt exn)
@@ -1360,27 +1396,21 @@ namespace Microsoft.FSharp.Control
let recordSuccess i res =
results.[i] <- res;
- let remaining =
- lock count (fun () ->
- decr count;
- if !count = 0 then
- innerCTS.Dispose()
- !count)
- finishTask(remaining)
+ finishTask(Interlocked.Decrement count)
let recordFailure exn =
- let remaining =
- lock count (fun () ->
- decr count;
- match !firstExn with
- | None -> firstExn := Some exn // save the cancellation as the first exception
- | _ -> ()
- if !count = 0 then
- innerCTS.Dispose()
- else
- innerCTS.Cancel()
- !count)
- finishTask(remaining)
+ // capture first exception and then decrement the counter to avoid race when
+ // - thread 1 decremented counter and preempted by the scheduler
+ // - thread 2 decremented counter and called finishTask
+ // since exception is not yet captured - finishtask will fall into success branch
+ match Interlocked.CompareExchange(firstExn, Some exn, None) with
+ | None ->
+ // signal cancellation before decrementing the counter - this guarantees that no other thread can sneak to finishTask and dispose innerCTS
+ // NOTE: Cancel may introduce reentrancy - i.e. when handler registered for the cancellation token invokes cancel continuation that will call 'recordFailure'
+ // to correctly handle this we need to return decremented value, not the current value of 'count' otherwise we may invoke finishTask with value '0' several times
+ innerCTS.Cancel()
+ | _ -> ()
+ finishTask(Interlocked.Decrement count)
tasks |> Array.iteri (fun i p ->
queueAsync
@@ -1395,6 +1425,34 @@ namespace Microsoft.FSharp.Control
|> unfake);
FakeUnit))
+#if FX_NO_TASK
+#else
+ // Contains helpers that will attach continuation to the given task.
+ // Should be invoked as a part of protectedPrimitive(withResync) call
+ module TaskHelpers =
+ let continueWith (task : Task<'T>, ({ aux = aux } as args)) =
+ let continuation (completedTask : Task<_>) : unit =
+ aux.trampolineHolder.Protect((fun () ->
+ if completedTask.IsCanceled then
+ aux.ccont (new OperationCanceledException())
+ elif completedTask.IsFaulted then
+ aux.econt (upcast completedTask.Exception)
+ else
+ args.cont completedTask.Result)) |> unfake
+ task.ContinueWith(Action>(continuation), TaskContinuationOptions.None) |> ignore |> fake
+
+ let continueWithUnit (task : Task, ({ aux = aux } as args)) =
+ let continuation (completedTask : Task) : unit =
+ aux.trampolineHolder.Protect((fun () ->
+ if completedTask.IsCanceled then
+ aux.ccont (new OperationCanceledException())
+ elif completedTask.IsFaulted then
+ aux.econt (upcast completedTask.Exception)
+ else
+ args.cont ())) |> unfake
+ task.ContinueWith(Action(continuation), TaskContinuationOptions.None) |> ignore |> fake
+#endif
+
#if FX_NO_REGISTERED_WAIT_HANDLES
[]
[]
@@ -1405,8 +1463,12 @@ namespace Microsoft.FSharp.Control
member this.IsCompleted =
#if FX_NO_WAITONE_MILLISECONDS
wh.WaitOne(TimeSpan(0L))
+#else
+#if FX_NO_EXIT_CONTEXT_FLAGS
+ wh.WaitOne(0)
#else
wh.WaitOne(0,exitContext=false)
+#endif
#endif
member this.CompletedSynchronously = false // always reschedule
#endif
@@ -1420,6 +1482,13 @@ namespace Microsoft.FSharp.Control
static member StartImmediate(a:Async,?cancellationToken) : unit =
Async.StartWithContinuations(a,id,raise,ignore,?cancellationToken=cancellationToken)
+#if FSHARP_CORE_NETCORE_PORTABLE
+ static member Sleep(dueTime : int) : Async =
+ // use combo protectedPrimitiveWithResync + continueWith instead of AwaitTask so we can pass cancellation token to the Delay task
+ unprotectedPrimitiveWithResync ( fun ({ aux = aux} as args) ->
+ TaskHelpers.continueWithUnit(Task.Delay(dueTime, aux.token), args)
+ )
+#else
static member Sleep(dueTime) : Async =
unprotectedPrimitiveWithResync (fun ({ aux = aux } as args) ->
let timer = ref (None : Timer option)
@@ -1463,6 +1532,7 @@ namespace Microsoft.FSharp.Control
| exn ->
aux.econt exn
)
+#endif
static member AwaitWaitHandle(waitHandle:WaitHandle,?millisecondsTimeout:int) =
let millisecondsTimeout = defaultArg millisecondsTimeout Threading.Timeout.Infinite
@@ -1523,7 +1593,6 @@ namespace Microsoft.FSharp.Control
#endif
// if user has specified timeout different from Timeout.Infinite
// then start another async to track timeout expiration
- // StartWithContinuations already installs trampoline so we can invoke continuation directly
if millisecondsTimeout <> Timeout.Infinite then
Async.StartWithContinuations
(
@@ -1531,7 +1600,7 @@ namespace Microsoft.FSharp.Control
cont = (fun () ->
if latch.Enter() then
registration.Dispose()
- scont false
+ aux.trampolineHolder.Protect(fun () -> scont false)
|> unfake),
econt = ignore, // we do not expect exceptions here
ccont = cancel,
@@ -1827,7 +1896,7 @@ namespace Microsoft.FSharp.Control
resultCell.RegisterResult(res,reuseThread=true) |> unfake)
and del =
#if FX_ATLEAST_PORTABLE
- let invokeMeth = (typeof>).GetMethod("Invoke", System.Reflection.BindingFlags.NonPublic ||| System.Reflection.BindingFlags.Public ||| System.Reflection.BindingFlags.Instance)
+ let invokeMeth = (typeof>).GetMethod("Invoke", BindingFlags.Public ||| BindingFlags.NonPublic ||| BindingFlags.Instance)
System.Delegate.CreateDelegate(typeof<'Delegate>, obj, invokeMeth) :?> 'Delegate
#else
System.Delegate.CreateDelegate(typeof<'Delegate>, obj, "Invoke") :?> 'Delegate
@@ -1906,18 +1975,10 @@ namespace Microsoft.FSharp.Control
#if FX_NO_TASK
#else
- static member AwaitTask (task:Task<'T>) : Async<'T> =
- protectedPrimitiveWithResync(fun ({aux = aux} as args) ->
- let continuation (completedTask : Task<_>) : unit =
- aux.trampolineHolder.Protect((fun () ->
- if completedTask.IsCanceled then
- aux.ccont (new OperationCanceledException())
- elif completedTask.IsFaulted then
- aux.econt (upcast completedTask.Exception)
- else
- args.cont completedTask.Result)) |> unfake
- task.ContinueWith(Action>(continuation), TaskContinuationOptions.None) |> ignore |> fake
- )
+ static member AwaitTask (task:Task<'T>) : Async<'T> =
+ protectedPrimitiveWithResync (fun args ->
+ TaskHelpers.continueWith(task, args)
+ )
#endif
module CommonExtensions =
@@ -1930,7 +1991,14 @@ namespace Microsoft.FSharp.Control
member stream.AsyncRead(buffer: byte[],?offset,?count) =
let offset = defaultArg offset 0
let count = defaultArg count buffer.Length
+#if FSHARP_CORE_NETCORE_PORTABLE
+ // use combo protectedPrimitiveWithResync + continueWith instead of AwaitTask so we can pass cancellation token to the ReadAsync task
+ protectedPrimitiveWithResync (fun ({ aux = aux } as args) ->
+ TaskHelpers.continueWith(stream.ReadAsync(buffer, offset, count, aux.token), args)
+ )
+#else
Async.FromBeginEnd (buffer,offset,count,stream.BeginRead,stream.EndRead)
+#endif
[] // give the extension member a 'nice', unmangled compiled name, unique within this module
member stream.AsyncRead(count) =
@@ -1947,7 +2015,14 @@ namespace Microsoft.FSharp.Control
member stream.AsyncWrite(buffer:byte[], ?offset:int, ?count:int) =
let offset = defaultArg offset 0
let count = defaultArg count buffer.Length
+#if FSHARP_CORE_NETCORE_PORTABLE
+ // use combo protectedPrimitiveWithResync + continueWith instead of AwaitTask so we can pass cancellation token to the WriteAsync task
+ protectedPrimitiveWithResync ( fun ({ aux = aux} as args) ->
+ TaskHelpers.continueWithUnit(stream.WriteAsync(buffer, offset, count, aux.token), args)
+ )
+#else
Async.FromBeginEnd (buffer,offset,count,stream.BeginWrite,stream.EndWrite)
+#endif
type System.Threading.WaitHandle with
member waitHandle.AsyncWaitOne(?millisecondsTimeout:int) = // only used internally, not a public API
diff --git a/src/fsharp/FSharp.Core/control.fsi b/src/fsharp/FSharp.Core/control.fsi
index 585aa97e53..16e827e333 100644
--- a/src/fsharp/FSharp.Core/control.fsi
+++ b/src/fsharp/FSharp.Core/control.fsi
@@ -1,4 +1,3 @@
-
//----------------------------------------------------------------------------
// Copyright (c) 2002-2012 Microsoft Corporation.
//
diff --git a/src/fsharp/FSharp.Core/event.fs b/src/fsharp/FSharp.Core/event.fs
index 02bddcb91e..1ae53eb17e 100755
--- a/src/fsharp/FSharp.Core/event.fs
+++ b/src/fsharp/FSharp.Core/event.fs
@@ -20,6 +20,11 @@ namespace Microsoft.FSharp.Control
open System.Reflection
open System.Diagnostics
+#if FX_RESHAPED_REFLECTION
+ open ReflectionAdapters
+ type BindingFlags = ReflectionAdapters.BindingFlags
+#endif
+
#if FX_NO_DELEGATE_DYNAMIC_METHOD
#else
@@ -145,7 +150,7 @@ namespace Microsoft.FSharp.Control
multicast <- System.Delegate.Remove(multicast, d) :?> 'Delegate
interface System.IObservable<'Args> with
member e.Subscribe(observer) =
- let obj = new EventDelegee<'Args>(observer)
+ let obj = new EventDelegee<'Args>(observer)
let h = System.Delegate.CreateDelegate(typeof<'Delegate>, obj, invokeInfo) :?> 'Delegate
(e :?> IDelegateEvent<'Delegate>).AddHandler(h)
{ new System.IDisposable with
diff --git a/src/fsharp/FSharp.Core/prim-types.fs b/src/fsharp/FSharp.Core/prim-types.fs
index 9972f8de2a..c62d6c93e5 100755
--- a/src/fsharp/FSharp.Core/prim-types.fs
+++ b/src/fsharp/FSharp.Core/prim-types.fs
@@ -75,7 +75,6 @@ namespace Microsoft.FSharp.Core
open System.Globalization
open System.Text
-
//-------------------------------------------------------------------------
// enumerations
@@ -112,8 +111,7 @@ namespace Microsoft.FSharp.Core
clone
open ICloneableExtensions
-#else
-#endif
+#endif
[]
type SealedAttribute(value:bool) =
@@ -392,6 +390,27 @@ namespace Microsoft.FSharp.Core
[] type int16<[] 'Measure> = int16
[] type int64<[] 'Measure> = int64
+#if FX_RESHAPED_REFLECTION
+ module PrimReflectionAdapters =
+
+ open System.Reflection
+ open System.Linq
+ // copied from BasicInlinedOperations
+ let inline box (x:'T) = (# "box !0" type ('T) x : obj #)
+ let inline unboxPrim<'T>(x:obj) = (# "unbox.any !0" type ('T) x : 'T #)
+ type System.Type with
+ member inline this.IsGenericType = this.GetTypeInfo().IsGenericType
+ member inline this.IsValueType = this.GetTypeInfo().IsValueType
+ member inline this.IsAssignableFrom(otherTy : Type) = this.GetTypeInfo().IsAssignableFrom(otherTy.GetTypeInfo())
+ member inline this.GetProperty(name) = this.GetRuntimeProperty(name)
+ member inline this.GetMethod(name, parameterTypes) = this.GetRuntimeMethod(name, parameterTypes)
+ member inline this.GetCustomAttributes(attrTy : Type, inherits : bool) : obj[] =
+ unboxPrim<_> (box (CustomAttributeExtensions.GetCustomAttributes(this.GetTypeInfo(), attrTy, false).ToArray()))
+
+ open PrimReflectionAdapters
+
+#endif
+
module BasicInlinedOperations =
let inline unboxPrim<'T>(x:obj) = (# "unbox.any !0" type ('T) x : 'T #)
@@ -443,10 +462,10 @@ namespace Microsoft.FSharp.Core
let inline typeof<'T> =
let tok = (# "ldtoken !0" type('T) : System.RuntimeTypeHandle #)
- System.Type.GetTypeFromHandle(tok)
+ System.Type.GetTypeFromHandle(tok)
let inline typedefof<'T> =
- let ty = typeof<'T>
+ let ty = typeof<'T>
if ty.IsGenericType then ty.GetGenericTypeDefinition() else ty
let inline sizeof<'T> =
@@ -678,10 +697,12 @@ namespace Microsoft.FSharp.Core
open IntrinsicOperators
+#if FX_RESHAPED_REFLECTION
+ open PrimReflectionAdapters
+#endif
[] // nested module OK
module IntrinsicFunctions =
- //-------------------------------------------------------------------------
// Unboxing, type casts, type tests
type TypeNullnessSemantics = int
@@ -704,17 +725,17 @@ namespace Microsoft.FSharp.Core
let ty = typeof<'T>
if ty.IsValueType
then TypeNullnessSemantics_NullNever else
- let mappingAttrs = ty.GetCustomAttributes(typeof,false)
+ let mappingAttrs = ty.GetCustomAttributes(typeof, false)
if mappingAttrs.Length = 0
then TypeNullnessSemantics_NullIsExtraValue
elif ty.Equals(typeof) then
TypeNullnessSemantics_NullTrueValue
- elif typeof.IsAssignableFrom(ty) then
+ elif typeof.IsAssignableFrom(ty) then
TypeNullnessSemantics_NullIsExtraValue
- elif ty.GetCustomAttributes(typeof,false).Length > 0 then
+ elif ty.GetCustomAttributes(typeof, false).Length > 0 then
TypeNullnessSemantics_NullIsExtraValue
else
- let reprAttrs = ty.GetCustomAttributes(typeof,false)
+ let reprAttrs = ty.GetCustomAttributes(typeof, false)
if reprAttrs.Length = 0 then
TypeNullnessSemantics_NullNotLiked
else
@@ -2288,7 +2309,11 @@ namespace Microsoft.FSharp.Core
let sign = getSign32 s &p l
let specifier = get0OXB s &p l
if p >= l then formatError() else
- match Char.ToLower(specifier,CultureInfo.InvariantCulture(*FxCop:1304*)) with
+#if FX_NO_TO_LOWER_INVARIANT
+ match Char.ToLower(specifier, CultureInfo.InvariantCulture(*FxCop:1304*)) with
+#else
+ match Char.ToLowerInvariant(specifier) with
+#endif
| 'x' -> sign * (int32OfUInt32 (Convert.ToUInt32(UInt64.Parse(s.Substring(p), NumberStyles.AllowHexSpecifier,CultureInfo.InvariantCulture))))
| 'b' -> sign * (int32OfUInt32 (Convert.ToUInt32(parseBinaryUInt64 s p l)))
| 'o' -> sign * (int32OfUInt32 (Convert.ToUInt32(parseOctalUInt64 s p l)))
@@ -2303,7 +2328,11 @@ namespace Microsoft.FSharp.Core
let sign = getSign64 s &p l
let specifier = get0OXB s &p l
if p >= l then formatError() else
- match Char.ToLower(specifier,CultureInfo.InvariantCulture(*FxCop:1304*)) with
+#if FX_NO_TO_LOWER_INVARIANT
+ match Char.ToLower(specifier, CultureInfo.InvariantCulture(*FxCop:1304*)) with
+#else
+ match Char.ToLowerInvariant(specifier) with
+#endif
| 'x' -> sign *. Int64.Parse(s.Substring(p), NumberStyles.AllowHexSpecifier,CultureInfo.InvariantCulture)
| 'b' -> sign *. (int64OfUInt64 (parseBinaryUInt64 s p l))
| 'o' -> sign *. (int64OfUInt64 (parseOctalUInt64 s p l))
@@ -3135,6 +3164,7 @@ namespace Microsoft.FSharp.Core
type FuncConvert =
static member ToFSharpFunc( f : Action<_>) = (fun t -> f.Invoke(t))
#if FX_NO_CONVERTER
+ static member ToFSharpFunc( f : System.Func<_, _>) = (fun t -> f.Invoke(t))
#else
static member ToFSharpFunc( f : Converter<_,_>) = (fun t -> f.Invoke(t))
#endif
@@ -4631,6 +4661,9 @@ namespace Microsoft.FSharp.Core
open System.Collections
+#if FX_RESHAPED_REFLECTION
+ open PrimReflectionAdapters
+#endif
let notStarted() = raise (new System.InvalidOperationException(SR.GetString(SR.enumerationNotStarted)))
let alreadyFinished() = raise (new System.InvalidOperationException(SR.GetString(SR.enumerationAlreadyFinished)))
@@ -4911,82 +4944,114 @@ namespace Microsoft.FSharp.Core
let inline GetArraySlice (arr: _[]) start finish =
- let start = (match start with None -> 0 | Some n -> n)
- let finish = (match finish with None -> arr.Length - 1 | Some n -> n)
- GetArraySub arr start (finish - start + 1)
+ let start = (match start with None -> 0 | Some n -> n)
+ let finish = (match finish with None -> arr.Length - 1 | Some n -> n)
+ GetArraySub arr start (finish - start + 1)
let inline SetArraySlice (dst: _[]) start finish (src:_[]) =
- let start = (match start with None -> 0 | Some n -> n)
- let finish = (match finish with None -> dst.Length - 1 | Some n -> n)
- SetArraySub dst start (finish - start + 1) src
+ let start = (match start with None -> 0 | Some n -> n)
+ let finish = (match finish with None -> dst.Length - 1 | Some n -> n)
+ SetArraySub dst start (finish - start + 1) src
let GetArraySlice2D (arr: _[,]) start1 finish1 start2 finish2 =
- let start1 = (match start1 with None -> 0 | Some n -> n)
- let start2 = (match start2 with None -> 0 | Some n -> n)
- let finish1 = (match finish1 with None -> GetArray2DLength1 arr - 1 | Some n -> n)
- let finish2 = (match finish2 with None -> GetArray2DLength2 arr - 1 | Some n -> n)
- let len1 = (finish1 - start1 + 1)
- let len2 = (finish2 - start2 + 1)
- GetArray2DSub arr start1 start2 len1 len2
+ let start1 = (match start1 with None -> 0 | Some n -> n)
+ let start2 = (match start2 with None -> 0 | Some n -> n)
+ let finish1 = (match finish1 with None -> GetArray2DLength1 arr - 1 | Some n -> n)
+ let finish2 = (match finish2 with None -> GetArray2DLength2 arr - 1 | Some n -> n)
+ let len1 = (finish1 - start1 + 1)
+ let len2 = (finish2 - start2 + 1)
+ GetArray2DSub arr start1 start2 len1 len2
+
+ let inline GetArraySlice2DFixed1 (arr: _[,]) fixed1 start2 finish2 =
+ let start2 = (match start2 with None -> 0 | Some n -> n)
+ let finish2 = (match finish2 with None -> GetArray2DLength2 arr - 1 | Some n -> n)
+ let len2 = (finish2 - start2 + 1)
+ let dst = zeroCreate len2
+ for j = 0 to len2 - 1 do
+ SetArray dst j (GetArray2D arr fixed1 (start2+j))
+ dst
+
+ let inline GetArraySlice2DFixed2 (arr: _[,]) start1 finish1 fixed2 =
+ let start1 = (match start1 with None -> 0 | Some n -> n)
+ let finish1 = (match finish1 with None -> GetArray2DLength1 arr - 1 | Some n -> n)
+ let len1 = (finish1 - start1 + 1)
+ let dst = zeroCreate len1
+ for i = 0 to len1 - 1 do
+ SetArray dst i (GetArray2D arr (start1+i) fixed2)
+ dst
+
+ let inline SetArraySlice2DFixed1 (dst: _[,]) fixed1 start2 finish2 (src:_[]) =
+ let start2 = (match start2 with None -> 0 | Some n -> n)
+ let finish2 = (match finish2 with None -> GetArray2DLength2 dst - 1 | Some n -> n)
+ let len2 = (finish2 - start2 + 1)
+ for j = 0 to len2 - 1 do
+ SetArray2D dst fixed1 (start2+j) (GetArray src j)
+
+ let inline SetArraySlice2DFixed2 (dst: _[,]) start1 finish1 fixed2 (src:_[]) =
+ let start1 = (match start1 with None -> 0 | Some n -> n)
+ let finish1 = (match finish1 with None -> GetArray2DLength1 dst - 1 | Some n -> n)
+ let len1 = (finish1 - start1 + 1)
+ for i = 0 to len1 - 1 do
+ SetArray2D dst (start1+i) fixed2 (GetArray src i)
let SetArraySlice2D (dst: _[,]) start1 finish1 start2 finish2 (src:_[,]) =
- let start1 = (match start1 with None -> 0 | Some n -> n)
- let start2 = (match start2 with None -> 0 | Some n -> n)
- let finish1 = (match finish1 with None -> GetArray2DLength1 dst - 1 | Some n -> n)
- let finish2 = (match finish2 with None -> GetArray2DLength2 dst - 1 | Some n -> n)
- SetArray2DSub dst start1 start2 (finish1 - start1 + 1) (finish2 - start2 + 1) src
+ let start1 = (match start1 with None -> 0 | Some n -> n)
+ let start2 = (match start2 with None -> 0 | Some n -> n)
+ let finish1 = (match finish1 with None -> GetArray2DLength1 dst - 1 | Some n -> n)
+ let finish2 = (match finish2 with None -> GetArray2DLength2 dst - 1 | Some n -> n)
+ SetArray2DSub dst start1 start2 (finish1 - start1 + 1) (finish2 - start2 + 1) src
let GetArraySlice3D (arr: _[,,]) start1 finish1 start2 finish2 start3 finish3 =
- let start1 = (match start1 with None -> 0 | Some n -> n)
- let start2 = (match start2 with None -> 0 | Some n -> n)
- let start3 = (match start3 with None -> 0 | Some n -> n)
- let finish1 = (match finish1 with None -> GetArray3DLength1 arr - 1 | Some n -> n)
- let finish2 = (match finish2 with None -> GetArray3DLength2 arr - 1 | Some n -> n)
- let finish3 = (match finish3 with None -> GetArray3DLength3 arr - 1 | Some n -> n)
- let len1 = (finish1 - start1 + 1)
- let len2 = (finish2 - start2 + 1)
- let len3 = (finish3 - start3 + 1)
- GetArray3DSub arr start1 start2 start3 len1 len2 len3
+ let start1 = (match start1 with None -> 0 | Some n -> n)
+ let start2 = (match start2 with None -> 0 | Some n -> n)
+ let start3 = (match start3 with None -> 0 | Some n -> n)
+ let finish1 = (match finish1 with None -> GetArray3DLength1 arr - 1 | Some n -> n)
+ let finish2 = (match finish2 with None -> GetArray3DLength2 arr - 1 | Some n -> n)
+ let finish3 = (match finish3 with None -> GetArray3DLength3 arr - 1 | Some n -> n)
+ let len1 = (finish1 - start1 + 1)
+ let len2 = (finish2 - start2 + 1)
+ let len3 = (finish3 - start3 + 1)
+ GetArray3DSub arr start1 start2 start3 len1 len2 len3
let SetArraySlice3D (dst: _[,,]) start1 finish1 start2 finish2 start3 finish3 (src:_[,,]) =
- let start1 = (match start1 with None -> 0 | Some n -> n)
- let start2 = (match start2 with None -> 0 | Some n -> n)
- let start3 = (match start3 with None -> 0 | Some n -> n)
- let finish1 = (match finish1 with None -> GetArray3DLength1 dst - 1 | Some n -> n)
- let finish2 = (match finish2 with None -> GetArray3DLength2 dst - 1 | Some n -> n)
- let finish3 = (match finish3 with None -> GetArray3DLength3 dst - 1 | Some n -> n)
- SetArray3DSub dst start1 start2 start3 (finish1 - start1 + 1) (finish2 - start2 + 1) (finish3 - start3 + 1) src
+ let start1 = (match start1 with None -> 0 | Some n -> n)
+ let start2 = (match start2 with None -> 0 | Some n -> n)
+ let start3 = (match start3 with None -> 0 | Some n -> n)
+ let finish1 = (match finish1 with None -> GetArray3DLength1 dst - 1 | Some n -> n)
+ let finish2 = (match finish2 with None -> GetArray3DLength2 dst - 1 | Some n -> n)
+ let finish3 = (match finish3 with None -> GetArray3DLength3 dst - 1 | Some n -> n)
+ SetArray3DSub dst start1 start2 start3 (finish1 - start1 + 1) (finish2 - start2 + 1) (finish3 - start3 + 1) src
let GetArraySlice4D (arr: _[,,,]) start1 finish1 start2 finish2 start3 finish3 start4 finish4 =
- let start1 = (match start1 with None -> 0 | Some n -> n)
- let start2 = (match start2 with None -> 0 | Some n -> n)
- let start3 = (match start3 with None -> 0 | Some n -> n)
- let start4 = (match start4 with None -> 0 | Some n -> n)
- let finish1 = (match finish1 with None -> Array4DLength1 arr - 1 | Some n -> n)
- let finish2 = (match finish2 with None -> Array4DLength2 arr - 1 | Some n -> n)
- let finish3 = (match finish3 with None -> Array4DLength3 arr - 1 | Some n -> n)
- let finish4 = (match finish4 with None -> Array4DLength4 arr - 1 | Some n -> n)
- let len1 = (finish1 - start1 + 1)
- let len2 = (finish2 - start2 + 1)
- let len3 = (finish3 - start3 + 1)
- let len4 = (finish4 - start4 + 1)
- GetArray4DSub arr start1 start2 start3 start4 len1 len2 len3 len4
+ let start1 = (match start1 with None -> 0 | Some n -> n)
+ let start2 = (match start2 with None -> 0 | Some n -> n)
+ let start3 = (match start3 with None -> 0 | Some n -> n)
+ let start4 = (match start4 with None -> 0 | Some n -> n)
+ let finish1 = (match finish1 with None -> Array4DLength1 arr - 1 | Some n -> n)
+ let finish2 = (match finish2 with None -> Array4DLength2 arr - 1 | Some n -> n)
+ let finish3 = (match finish3 with None -> Array4DLength3 arr - 1 | Some n -> n)
+ let finish4 = (match finish4 with None -> Array4DLength4 arr - 1 | Some n -> n)
+ let len1 = (finish1 - start1 + 1)
+ let len2 = (finish2 - start2 + 1)
+ let len3 = (finish3 - start3 + 1)
+ let len4 = (finish4 - start4 + 1)
+ GetArray4DSub arr start1 start2 start3 start4 len1 len2 len3 len4
let SetArraySlice4D (dst: _[,,,]) start1 finish1 start2 finish2 start3 finish3 start4 finish4 (src:_[,,,]) =
- let start1 = (match start1 with None -> 0 | Some n -> n)
- let start2 = (match start2 with None -> 0 | Some n -> n)
- let start3 = (match start3 with None -> 0 | Some n -> n)
- let start4 = (match start4 with None -> 0 | Some n -> n)
- let finish1 = (match finish1 with None -> Array4DLength1 dst - 1 | Some n -> n)
- let finish2 = (match finish2 with None -> Array4DLength2 dst - 1 | Some n -> n)
- let finish3 = (match finish3 with None -> Array4DLength3 dst - 1 | Some n -> n)
- let finish4 = (match finish4 with None -> Array4DLength4 dst - 1 | Some n -> n)
- SetArray4DSub dst start1 start2 start3 start4 (finish1 - start1 + 1) (finish2 - start2 + 1) (finish3 - start3 + 1) (finish4 - start4 + 1) src
+ let start1 = (match start1 with None -> 0 | Some n -> n)
+ let start2 = (match start2 with None -> 0 | Some n -> n)
+ let start3 = (match start3 with None -> 0 | Some n -> n)
+ let start4 = (match start4 with None -> 0 | Some n -> n)
+ let finish1 = (match finish1 with None -> Array4DLength1 dst - 1 | Some n -> n)
+ let finish2 = (match finish2 with None -> Array4DLength2 dst - 1 | Some n -> n)
+ let finish3 = (match finish3 with None -> Array4DLength3 dst - 1 | Some n -> n)
+ let finish4 = (match finish4 with None -> Array4DLength4 dst - 1 | Some n -> n)
+ SetArray4DSub dst start1 start2 start3 start4 (finish1 - start1 + 1) (finish2 - start2 + 1) (finish3 - start3 + 1) (finish4 - start4 + 1) src
let inline GetStringSlice (str:string) start finish =
- let start = (match start with None -> 0 | Some n -> n)
- let finish = (match finish with None -> str.Length - 1 | Some n -> n)
- str.Substring(start, finish-start+1)
+ let start = (match start with None -> 0 | Some n -> n)
+ let finish = (match finish with None -> str.Length - 1 | Some n -> n)
+ str.Substring(start, finish-start+1)
[]
@@ -5409,6 +5474,13 @@ namespace Microsoft.FSharp.Core
when ^T : byte = RangeByte (retype n) (retype step) (retype m)
+ type ``[,]``<'T> with
+ member arr.GetSlice(x : int, y1 : int option, y2 : int option) = GetArraySlice2DFixed1 arr x y1 y2
+ member arr.GetSlice(x1 : int option, x2 : int option, y : int) = GetArraySlice2DFixed2 arr x1 x2 y
+
+ member arr.SetSlice(x : int, y1 : int option, y2 : int option, source:'T[]) = SetArraySlice2DFixed1 arr x y1 y2 source
+ member arr.SetSlice(x1 : int option, x2 : int option, y : int, source:'T[]) = SetArraySlice2DFixed2 arr x1 x2 y source
+
[]
let inline abs (x: ^T) : ^T =
AbsDynamic x
diff --git a/src/fsharp/FSharp.Core/prim-types.fsi b/src/fsharp/FSharp.Core/prim-types.fsi
index e92f3b81e3..9387675744 100755
--- a/src/fsharp/FSharp.Core/prim-types.fsi
+++ b/src/fsharp/FSharp.Core/prim-types.fsi
@@ -1346,6 +1346,20 @@ namespace Microsoft.FSharp.Core
open System
open Microsoft.FSharp.Core
+#if FX_RESHAPED_REFLECTION
+ module internal PrimReflectionAdapters =
+
+ open System.Reflection
+
+ type System.Type with
+ member inline IsGenericType : bool
+ member inline IsValueType : bool
+ member inline GetMethod : string * parameterTypes : Type[] -> MethodInfo
+ member inline GetProperty : string -> PropertyInfo
+ member inline IsAssignableFrom : otherType : Type -> bool
+ member inline GetCustomAttributes : attributeType : Type * inherits: bool -> obj[]
+#endif
+
//-------------------------------------------------------------------------
// F# Choice Types
@@ -1903,12 +1917,12 @@ namespace Microsoft.FSharp.Core
/// The result of the operation.
val inline (>>>) : value:^T -> shift:int32 -> ^T when ^T : (static member (>>>) : ^T * int32 -> ^T) and default ^T : int
- /// Overloaded logical-NOT operator
+ /// Overloaded bitwise-NOT operator
/// The input value.
/// The result of the operation.
val inline (~~~) : value:^T -> ^T when ^T : (static member (~~~) : ^T -> ^T) and default ^T : int
- /// Overloaded prefix=plus operator
+ /// Overloaded prefix-plus operator
/// The input value.
/// The result of the operation.
val inline (~+) : value:^T -> ^T when ^T : (static member (~+) : ^T -> ^T) and default ^T : int
@@ -2671,7 +2685,7 @@ namespace Microsoft.FSharp.Core
/// The source array.
val inline SetArraySlice : target:'T[] -> start:int option -> finish:int option -> source:'T[] -> unit
- /// Gets a slice of an array
+ /// Gets a region slice of an array
/// The source array.
/// The start index of the first dimension.
/// The end index of the first dimension.
@@ -2680,7 +2694,23 @@ namespace Microsoft.FSharp.Core
/// The two dimensional sub array from the input indices.
val GetArraySlice2D : source:'T[,] -> start1:int option -> finish1:int option -> start2:int option -> finish2:int option -> 'T[,]
- /// Sets a slice of an array
+ /// Gets a vector slice of a 2D array. The index of the first dimension is fixed.
+ /// The source array.
+ /// The index of the first dimension.
+ /// The start index of the second dimension.
+ /// The end index of the second dimension.
+ /// The sub array from the input indices.
+ val inline GetArraySlice2DFixed1 : source:'T[,] -> index1:int -> start2:int option -> finish2:int option -> 'T[]
+
+ /// Gets a vector slice of a 2D array. The index of the second dimension is fixed.
+ /// The source array.
+ /// The start index of the first dimension.
+ /// The end index of the first dimension.
+ /// The fixed index of the second dimension.
+ /// The sub array from the input indices.
+ val inline GetArraySlice2DFixed2 : source:'T[,] -> start1:int option -> finish1:int option -> index2: int -> 'T[]
+
+ /// Sets a region slice of an array
/// The target array.
/// The start index of the first dimension.
/// The end index of the first dimension.
@@ -2689,6 +2719,22 @@ namespace Microsoft.FSharp.Core
/// The source array.
val SetArraySlice2D : target:'T[,] -> start1:int option -> finish1:int option -> start2:int option -> finish2:int option -> source:'T[,] -> unit
+ /// Sets a vector slice of a 2D array. The index of the first dimension is fixed.
+ /// The target array.
+ /// The index of the first dimension.
+ /// The start index of the second dimension.
+ /// The end index of the second dimension.
+ /// The source array.
+ val inline SetArraySlice2DFixed1 : target:'T[,] -> index1:int -> start2:int option -> finish2:int option -> source:'T[] -> unit
+
+ /// Sets a vector slice of a 2D array. The index of the second dimension is fixed.
+ /// The target array.
+ /// The start index of the first dimension.
+ /// The end index of the first dimension.
+ /// The index of the second dimension.
+ /// The source array.
+ val inline SetArraySlice2DFixed2 : target:'T[,] -> start1:int option -> finish1:int option -> index2:int -> source:'T[] -> unit
+
/// Gets a slice of an array
/// The source array.
/// The start index of the first dimension.
diff --git a/src/fsharp/FSharp.Core/printf.fs b/src/fsharp/FSharp.Core/printf.fs
index ad06604fbf..4396858875 100755
--- a/src/fsharp/FSharp.Core/printf.fs
+++ b/src/fsharp/FSharp.Core/printf.fs
@@ -11,619 +11,1370 @@
namespace Microsoft.FSharp.Core
-open Microsoft.FSharp.Core
-open Microsoft.FSharp.Core.Operators
-open Microsoft.FSharp.Collections
-open Microsoft.FSharp.Reflection
-open Microsoft.FSharp.Text.StructuredPrintfImpl
-open System.Globalization
-open System.IO
-open System.Text
-
-type PrintfFormat<'printer,'state,'residue,'result>(value:string) =
+type PrintfFormat<'Printer,'State,'Residue,'Result>(value:string) =
member x.Value = value
-type PrintfFormat<'printer,'state,'residue,'result,'tuple>(value:string) =
- inherit PrintfFormat<'printer,'state,'residue,'result>(value)
+type PrintfFormat<'Printer,'State,'Residue,'Result,'Tuple>(value:string) =
+ inherit PrintfFormat<'Printer,'State,'Residue,'Result>(value)
-type Format<'printer,'state,'residue,'result> = PrintfFormat<'printer,'state,'residue,'result>
-type Format<'printer,'state,'residue,'result,'tuple> = PrintfFormat<'printer,'state,'residue,'result,'tuple>
+type Format<'Printer,'State,'Residue,'Result> = PrintfFormat<'Printer,'State,'Residue,'Result>
+type Format<'Printer,'State,'Residue,'Result,'Tuple> = PrintfFormat<'Printer,'State,'Residue,'Result,'Tuple>
-module PrintfImpl =
+#if FX_RESHAPED_REFLECTION
- open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators
- open Microsoft.FSharp.Reflection
+open Microsoft.FSharp.Core.PrimReflectionAdapters
+open Microsoft.FSharp.Core.ReflectionAdapters
+
+#endif
+
+module internal PrintfImpl =
+
+ /// Basic idea of implementation:
+ /// Every Printf.* family should returns curried function that collects arguments and then somehow prints them.
+ /// Idea - instead of building functions on fly argument by argument we instead introduce some predefined parts and then construct functions from these parts
+ /// Parts include:
+ /// Plain ones:
+ /// 1. Final pieces (1..5) - set of functions with arguments number 1..5.
+ /// Primary characteristic - these functions produce final result of the *printf* operation
+ /// 2. Chained pieces (1..5) - set of functions with arguments number 1..5.
+ /// Primary characteristic - these functions doesn not produce final result by itself, instead they tailed with some another piece (chained or final).
+ /// Plain parts correspond to simple format specifiers (that are projected to just one parameter of the function, say %d or %s). However we also have
+ /// format specifiers that can be projected to more than one argument (i.e %a, %t or any simple format specified with * width or precision).
+ /// For them we add special cases (both chained and final to denote that they can either return value themselves or continue with some other piece)
+ /// These primitives allow us to construct curried functions with arbitrary signatures.
+ /// For example:
+ /// - function that corresponds to %s%s%s%s%s (string -> string -> string -> string -> string -> T) will be represented by one piece final 5.
+ /// - function that has more that 5 arguments will include chained parts: %s%s%s%s%s%d%s => chained2 -> final 5
+ /// Primary benefits:
+ /// 1. creating specialized version of any part requires only one reflection call. This means that we can handle up to 5 simple format specifiers
+ /// with just one reflection call
+ /// 2. we can make combinable parts independent from particular printf implementation. Thus final result can be cached and shared.
+ /// i.e when first calll to printf "%s %s" will trigger creation of the specialization. Subsequent calls will pick existing specialization
+ open System
+ open System.IO
+ open System.Collections.Generic
open System.Reflection
+ open Microsoft.FSharp.Core
+ open Microsoft.FSharp.Core.Operators
+ open Microsoft.FSharp.Collections
+ open LanguagePrimitives.IntrinsicOperators
+
+ []
+ type FormatFlags =
+ | None = 0
+ | LeftJustify = 1
+ | PadWithZeros = 2
+ | PlusForPositives = 4
+ | SpaceForPositives = 8
+
+ let inline hasFlag flags (expected : FormatFlags) = (flags &&& expected) = expected
+ let inline isLeftJustify flags = hasFlag flags FormatFlags.LeftJustify
+ let inline isPadWithZeros flags = hasFlag flags FormatFlags.PadWithZeros
+ let inline isPlusForPositives flags = hasFlag flags FormatFlags.PlusForPositives
+ let inline isSpaceForPositives flags = hasFlag flags FormatFlags.SpaceForPositives
+
+ /// Used for width and precision to denote that user has specified '*' flag
+ []
+ let StarValue = -1
+ /// Used for width and precision to denote that corresponding value was omitted in format string
+ []
+ let NotSpecifiedValue = -2
+
+ []
+ []
+ type FormatSpecifier =
+ {
+ TypeChar : char
+ Precision : int
+ Width : int
+ Flags : FormatFlags
+ }
+ member this.IsStarPrecision = this.Precision = StarValue
+ member this.IsPrecisionSpecified = this.Precision <> NotSpecifiedValue
+ member this.IsStarWidth = this.Width = StarValue
+ member this.IsWidthSpecified = this.Width <> NotSpecifiedValue
+
+ override this.ToString() =
+ let valueOf n = match n with StarValue -> "*" | NotSpecifiedValue -> "-" | n -> n.ToString()
+ System.String.Format
+ (
+ "'{0}', Precision={1}, Width={2}, Flags={3}",
+ this.TypeChar,
+ (valueOf this.Precision),
+ (valueOf this.Width),
+ this.Flags
+ )
+
+ /// Set of helpers to parse format string
+ module private FormatString =
+ let inline isDigit c = c >= '0' && c <= '9'
+ let intFromString (s : string) pos =
+ let rec go acc i =
+ if isDigit s.[i] then
+ let n = int s.[i] - int '0'
+ go (acc * 10 + n) (i + 1)
+ else acc, i
+ go 0 pos
+
+ let parseFlags (s : string) i : FormatFlags * int =
+ let rec go flags i =
+ match s.[i] with
+ | '0' -> go (flags ||| FormatFlags.PadWithZeros) (i + 1)
+ | '+' -> go (flags ||| FormatFlags.PlusForPositives) (i + 1)
+ | ' ' -> go (flags ||| FormatFlags.SpaceForPositives) (i + 1)
+ | '-' -> go (flags ||| FormatFlags.LeftJustify) (i + 1)
+ | _ -> flags, i
+ go FormatFlags.None i
+
+ let parseWidth (s : string) i : int * int =
+ if s.[i] = '*' then StarValue, (i + 1)
+ elif isDigit (s.[i]) then intFromString s i
+ else NotSpecifiedValue, i
+
+ let parsePrecision (s : string) i : int * int =
+ if s.[i] = '.' then
+ if s.[i + 1] = '*' then StarValue, i + 2
+ elif isDigit (s.[i + 1]) then intFromString s (i + 1)
+ else raise (ArgumentException("invalid precision value"))
+ else NotSpecifiedValue, i
+
+ let parseTypeChar (s : string) i : char * int =
+ s.[i], (i + 1)
+
+ let findNextFormatSpecifier (s : string) i =
+ let rec go i (buf : Text.StringBuilder) =
+ if i >= s.Length then
+ s.Length, buf.ToString()
+ else
+ let c = s.[i]
+ if c = '%' then
+ if i + 1 < s.Length then
+ let _, i1 = parseFlags s (i + 1)
+ let w, i2 = parseWidth s i1
+ let p, i3 = parsePrecision s i2
+ let typeChar, i4 = parseTypeChar s i3
+ // shortcut for the simpliest case
+ // if typeChar is not % or it has star as width\precision - resort to long path
+ if typeChar = '%' && not (w = StarValue || p = StarValue) then
+ buf.Append('%') |> ignore
+ go i4 buf
+ else
+ i, buf.ToString()
+ else
+ raise (ArgumentException("Missing format specifier"))
+ else
+ buf.Append(c) |> ignore
+ go (i + 1) buf
+ go i (Text.StringBuilder())
+
+ /// Abstracts generated printer from the details of particular environment: how to write text, how to produce results etc...
+ []
+ type PrintfEnv<'State, 'Residue, 'Result> =
+ val State : 'State
+ new(s : 'State) = { State = s }
+ abstract Finalize : unit -> 'Result
+ abstract Write : string -> unit
+ abstract WriteT : 'Residue -> unit
+
+ type Utils =
+ static member inline Write (env : PrintfEnv<_, _, _>, a, b) =
+ env.Write a
+ env.Write b
+ static member inline Write (env : PrintfEnv<_, _, _>, a, b, c) =
+ Utils.Write(env, a, b)
+ env.Write c
+ static member inline Write (env : PrintfEnv<_, _, _>, a, b, c, d) =
+ Utils.Write(env, a, b)
+ Utils.Write(env, c, d)
+ static member inline Write (env : PrintfEnv<_, _, _>, a, b, c, d, e) =
+ Utils.Write(env, a, b, c)
+ Utils.Write(env, d, e)
+ static member inline Write (env : PrintfEnv<_, _, _>, a, b, c, d, e, f) =
+ Utils.Write(env, a, b, c, d)
+ Utils.Write(env, e, f)
+ static member inline Write (env : PrintfEnv<_, _, _>, a, b, c, d, e, f, g) =
+ Utils.Write(env, a, b, c, d, e)
+ Utils.Write(env, f, g)
+ static member inline Write (env : PrintfEnv<_, _, _>, a, b, c, d, e, f, g, h) =
+ Utils.Write(env, a, b, c, d, e, f)
+ Utils.Write(env, g, h)
+ static member inline Write (env : PrintfEnv<_, _, _>, a, b, c, d, e, f, g, h, i) =
+ Utils.Write(env, a, b, c, d, e, f, g)
+ Utils.Write(env, h ,i)
+ static member inline Write (env : PrintfEnv<_, _, _>, a, b, c, d, e, f, g, h, i, j) =
+ Utils.Write(env, a, b, c, d, e, f, g, h)
+ Utils.Write(env, i, j)
+ static member inline Write (env : PrintfEnv<_, _, _>, a, b, c, d, e, f, g, h, i, j, k) =
+ Utils.Write(env, a, b, c, d, e, f, g, h, i)
+ Utils.Write(env, j, k)
+ static member inline Write (env : PrintfEnv<_, _, _>, a, b, c, d, e, f, g, h, i, j, k, l, m) =
+ Utils.Write(env, a, b, c, d, e, f, g, h, i, j, k)
+ Utils.Write(env, l, m)
+
+ /// Type of results produced by specialization
+ /// This is function that accepts thunk to create PrintfEnv on demand and returns concrete instance of Printer (curried function)
+ /// After all arguments is collected, specialization obtains concrete PrintfEnv from the thunk and use it to output collected data.
+ type PrintfFactory<'State, 'Residue, 'Result, 'Printer> = (unit -> PrintfEnv<'State, 'Residue, 'Result>) -> 'Printer
+
+ []
+ let MaxArgumentsInSpecialization = 5
+
+ /// Specializations are created via factory methods. These methods accepts 2 kinds of arguments
+ /// - parts of format string that corresponds to raw text
+ /// - functions that can transform collected values to strings
+ /// basic shape of the signature of specialization
+ /// + + + ... +
+ type Specializations<'State, 'Residue, 'Result> private ()=
+
+ static member Final1<'A>
+ (
+ s0, conv1, s1
+ ) =
+ (fun (env : unit -> PrintfEnv<'State, 'Residue, 'Result>) ->
+ (fun (a : 'A) ->
+ let env = env()
+ Utils.Write(env, s0, (conv1 a), s1)
+ env.Finalize()
+ )
+ )
+ static member Final2<'A, 'B>
+ (
+ s0, conv1, s1, conv2, s2
+ ) =
+ (fun (env : unit -> PrintfEnv<'State, 'Residue, 'Result>) ->
+ (fun (a : 'A) (b : 'B) ->
+ let env = env()
+ Utils.Write(env, s0, (conv1 a), s1, (conv2 b), s2)
+ env.Finalize()
+ )
+ )
+
+ static member Final3<'A, 'B, 'C>
+ (
+ s0, conv1, s1, conv2, s2, conv3, s3
+ ) =
+ (fun (env : unit -> PrintfEnv<'State, 'Residue, 'Result>) ->
+ (fun (a : 'A) (b : 'B) (c : 'C) ->
+ let env = env()
+ Utils.Write(env, s0, (conv1 a), s1, (conv2 b), s2, (conv3 c), s3)
+ env.Finalize()
+ )
+ )
+
+ static member Final4<'A, 'B, 'C, 'D>
+ (
+ s0, conv1, s1, conv2, s2, conv3, s3, conv4, s4
+ ) =
+ (fun (env : unit -> PrintfEnv<'State, 'Residue, 'Result>) ->
+ (fun (a : 'A) (b : 'B) (c : 'C) (d : 'D)->
+ let env = env()
+ Utils.Write(env, s0, (conv1 a), s1, (conv2 b), s2, (conv3 c), s3, (conv4 d), s4)
+ env.Finalize()
+ )
+ )
+ static member Final5<'A, 'B, 'C, 'D, 'E>
+ (
+ s0, conv1, s1, conv2, s2, conv3, s3, conv4, s4, conv5, s5
+ ) =
+ (fun (env : unit -> PrintfEnv<'State, 'Residue, 'Result>) ->
+ (fun (a : 'A) (b : 'B) (c : 'C) (d : 'D) (e : 'E)->
+ let env = env()
+ Utils.Write(env, s0, (conv1 a), s1, (conv2 b), s2, (conv3 c), s3, (conv4 d), s4, (conv5 e), s5)
+ env.Finalize()
+ )
+ )
+ static member Chained1<'A, 'Tail>
+ (
+ s0, conv1,
+ next
+ ) =
+ (fun (env : unit -> PrintfEnv<'State, 'Residue, 'Result>) ->
+ (fun (a : 'A) ->
+ let env() =
+ let env = env()
+ Utils.Write(env, s0, (conv1 a))
+ env
+ next env : 'Tail
+ )
+ )
+ static member Chained2<'A, 'B, 'Tail>
+ (
+ s0, conv1, s1, conv2,
+ next
+ ) =
+ (fun (env : unit -> PrintfEnv<'State, 'Residue, 'Result>) ->
+ (fun (a : 'A) (b : 'B) ->
+ let env() =
+ let env = env()
+ Utils.Write(env, s0, (conv1 a), s1, (conv2 b))
+ env
+ next env : 'Tail
+ )
+ )
+
+ static member Chained3<'A, 'B, 'C, 'Tail>
+ (
+ s0, conv1, s1, conv2, s2, conv3,
+ next
+ ) =
+ (fun (env : unit -> PrintfEnv<'State, 'Residue, 'Result>) ->
+ (fun (a : 'A) (b : 'B) (c : 'C) ->
+ let env() =
+ let env = env()
+ Utils.Write(env, s0, (conv1 a), s1, (conv2 b), s2, (conv3 c))
+ env
+ next env : 'Tail
+ )
+ )
+
+ static member Chained4<'A, 'B, 'C, 'D, 'Tail>
+ (
+ s0, conv1, s1, conv2, s2, conv3, s3, conv4,
+ next
+ ) =
+ (fun (env : unit -> PrintfEnv<'State, 'Residue, 'Result>) ->
+ (fun (a : 'A) (b : 'B) (c : 'C) (d : 'D)->
+ let env() =
+ let env = env()
+ Utils.Write(env, s0, (conv1 a), s1, (conv2 b), s2, (conv3 c), s3, (conv4 d))
+ env
+ next env : 'Tail
+ )
+ )
+ static member Chained5<'A, 'B, 'C, 'D, 'E, 'Tail>
+ (
+ s0, conv1, s1, conv2, s2, conv3, s3, conv4, s4, conv5,
+ next
+ ) =
+ (fun (env : unit -> PrintfEnv<'State, 'Residue, 'Result>) ->
+ (fun (a : 'A) (b : 'B) (c : 'C) (d : 'D) (e : 'E)->
+ let env() =
+ let env = env()
+ Utils.Write(env, s0, (conv1 a), s1, (conv2 b), s2, (conv3 c), s3, (conv4 d), s4, (conv5 e))
+ env
+ next env : 'Tail
+ )
+ )
+
+ static member TFinal(s1 : string, s2 : string) =
+ (fun (env : unit -> PrintfEnv<'State, 'Residue, 'Result>) ->
+ (fun (f : 'State -> 'Residue) ->
+ let env = env()
+ env.Write(s1)
+ env.WriteT(f env.State)
+ env.Write s2
+ env.Finalize()
+ )
+ )
+ static member TChained<'Tail>(s1 : string, next : PrintfFactory<'State, 'Residue, 'Result,'Tail>) =
+ (fun (env : unit -> PrintfEnv<'State, 'Residue, 'Result>) ->
+ (fun (f : 'State -> 'Residue) ->
+ let env() =
+ let env = env()
+ env.Write(s1)
+ env.WriteT(f env.State)
+ env
+ next(env) : 'Tail
+ )
+ )
+
+ static member LittleAFinal<'A>(s1 : string, s2 : string) =
+ (fun (env : unit -> PrintfEnv<'State, 'Residue, 'Result>) ->
+ (fun (f : 'State -> 'A ->'Residue) (a : 'A) ->
+ let env = env()
+ env.Write s1
+ env.WriteT(f env.State a)
+ env.Write s2
+ env.Finalize()
+ )
+ )
+ static member LittleAChained<'A, 'Tail>(s1 : string, next : PrintfFactory<'State, 'Residue, 'Result,'Tail>) =
+ (fun (env : unit -> PrintfEnv<'State, 'Residue, 'Result>) ->
+ (fun (f : 'State -> 'A ->'Residue) (a : 'A) ->
+ let env() =
+ let env = env()
+ env.Write s1
+ env.WriteT(f env.State a)
+ env
+ next env : 'Tail
+ )
+ )
+ static member StarFinal1<'A>(s1 : string, conv, s2 : string) =
+ (fun (env : unit -> PrintfEnv<'State, 'Residue, 'Result>) ->
+ (fun (star1 : int) (a : 'A) ->
+ let env = env()
+ env.Write s1
+ env.Write (conv a star1 : string)
+ env.Write s2
+ env.Finalize()
+ )
+ )
+
+ static member PercentStarFinal1(s1 : string, s2 : string) =
+ (fun (env : unit -> PrintfEnv<'State, 'Residue, 'Result>) ->
+ (fun (_star1 : int) ->
+ let env = env()
+ env.Write s1
+ env.Write("%")
+ env.Write s2
+ env.Finalize()
+ )
+ )
+
+ static member StarFinal2<'A>(s1 : string, conv, s2 : string) =
+ (fun (env : unit -> PrintfEnv<'State, 'Residue, 'Result>) ->
+ (fun (star1 : int) (star2 : int) (a : 'A) ->
+ let env = env()
+ env.Write s1
+ env.Write (conv a star1 star2: string)
+ env.Write s2
+ env.Finalize()
+ )
+ )
+
+ /// Handles case when '%*.*%' is used at the end of string
+ static member PercentStarFinal2(s1 : string, s2 : string) =
+ (fun (env : unit -> PrintfEnv<'State, 'Residue, 'Result>) ->
+ (fun (_star1 : int) (_star2 : int) ->
+ let env = env()
+ env.Write s1
+ env.Write("%")
+ env.Write s2
+ env.Finalize()
+ )
+ )
+
+ static member StarChained1<'A, 'Tail>(s1 : string, conv, next : PrintfFactory<'State, 'Residue, 'Result,'Tail>) =
+ (fun (env : unit -> PrintfEnv<'State, 'Residue, 'Result>) ->
+ (fun (star1 : int) (a : 'A) ->
+ let env() =
+ let env = env()
+ env.Write s1
+ env.Write(conv a star1 : string)
+ env
+ next env : 'Tail
+ )
+ )
+
+ /// Handles case when '%*%' is used in the middle of the string so it needs to be chained to another printing block
+ static member PercentStarChained1<'Tail>(s1 : string, next : PrintfFactory<'State, 'Residue, 'Result,'Tail>) =
+ (fun (env : unit -> PrintfEnv<'State, 'Residue, 'Result>) ->
+ (fun (_star1 : int) ->
+ let env() =
+ let env = env()
+ env.Write s1
+ env.Write("%")
+ env
+ next env : 'Tail
+ )
+ )
+
+ static member StarChained2<'A, 'Tail>(s1 : string, conv, next : PrintfFactory<'State, 'Residue, 'Result,'Tail>) =
+ (fun (env : unit -> PrintfEnv<'State, 'Residue, 'Result>) ->
+ (fun (star1 : int) (star2 : int) (a : 'A) ->
+ let env() =
+ let env = env()
+ env.Write s1
+ env.Write(conv a star1 star2 : string)
+ env
+ next env : 'Tail
+ )
+ )
+
+ /// Handles case when '%*.*%' is used in the middle of the string so it needs to be chained to another printing block
+ static member PercentStarChained2<'Tail>(s1 : string, next : PrintfFactory<'State, 'Residue, 'Result,'Tail>) =
+ (fun (env : unit -> PrintfEnv<'State, 'Residue, 'Result>) ->
+ (fun (_star1 : int) (_star2 : int) ->
+ let env() =
+ let env = env()
+ env.Write s1
+ env.Write("%")
+ env
+ next env : 'Tail
+ )
+ )
+
+ let inline (===) a b = Object.ReferenceEquals(a, b)
+ let invariantCulture = System.Globalization.CultureInfo.InvariantCulture
+
+ let inline boolToString v = if v then "true" else "false"
+ let inline stringToSafeString v = if v = null then "" else v
+
+ []
+ let DefaultPrecision = 6
+
+ let getFormatForFloat (ch : char) (prec : int) = ch.ToString() + prec.ToString()
+ let normalizePrecision prec = min (max prec 0) 99
+
+ /// Contains helpers to convert printer functions to functions that prints value with respect to specified justification
+ /// There are two kinds to printers:
+ /// 'T -> string - converts value to string - used for strings, basic integers etc..
+ /// string -> 'T -> string - converts value to string with given format string - used by numbers with floating point, typically precision is set via format string
+ /// To support both categories there are two entry points:
+ /// - withPadding - adapts first category
+ /// - withPaddingFormatted - adapts second category
+ module Padding =
+ /// pad here is function that converts T to string with respect of justification
+ /// basic - function that converts T to string without appying justification rules
+ /// adaptPaddedFormatted returns boxed function that has various number of arguments depending on if width\precision flags has '*' value
+ let inline adaptPaddedFormatted (spec : FormatSpecifier) getFormat (basic : string -> 'T -> string) (pad : string -> int -> 'T -> string) =
+ if spec.IsStarWidth then
+ if spec.IsStarPrecision then
+ // width=*, prec=*
+ box(fun v width prec ->
+ let fmt = getFormat (normalizePrecision prec)
+ pad fmt width v
+ )
+ else
+ // width=*, prec=?
+ let prec = if spec.IsPrecisionSpecified then normalizePrecision spec.Precision else DefaultPrecision
+ let fmt = getFormat prec
+ box(fun v width ->
+ pad fmt width v
+ )
+ elif spec.IsStarPrecision then
+ if spec.IsWidthSpecified then
+ // width=val, prec=*
+ box(fun v prec ->
+ let fmt = getFormat prec
+ pad fmt spec.Width v
+ )
+ else
+ // width=X, prec=*
+ box(fun v prec ->
+ let fmt = getFormat prec
+ basic fmt v
+ )
+ else
+ let prec = if spec.IsPrecisionSpecified then normalizePrecision spec.Precision else DefaultPrecision
+ let fmt = getFormat prec
+ if spec.IsWidthSpecified then
+ // width=val, prec=*
+ box(fun v ->
+ pad fmt spec.Width v
+ )
+ else
+ // width=X, prec=*
+ box(fun v ->
+ basic fmt v
+ )
+
+ /// pad here is function that converts T to string with respect of justification
+ /// basic - function that converts T to string without appying justification rules
+ /// adaptPadded returns boxed function that has various number of arguments depending on if width flags has '*' value
+ let inline adaptPadded (spec : FormatSpecifier) (basic : 'T -> string) (pad : int -> 'T -> string) =
+ if spec.IsStarWidth then
+ // width=*, prec=?
+ box(fun v width ->
+ pad width v
+ )
+ else
+ if spec.IsWidthSpecified then
+ // width=val, prec=*
+ box(fun v ->
+ pad spec.Width v
+ )
+ else
+ // width=X, prec=*
+ box(fun v ->
+ basic v
+ )
+
+ let inline withPaddingFormatted (spec : FormatSpecifier) getFormat (defaultFormat : string) (f : string -> 'T -> string) left right =
+ if not (spec.IsWidthSpecified || spec.IsPrecisionSpecified) then
+ box (f defaultFormat)
+ else
+ if isLeftJustify spec.Flags then
+ adaptPaddedFormatted spec getFormat f left
+ else
+ adaptPaddedFormatted spec getFormat f right
+
+ let inline withPadding (spec : FormatSpecifier) (f : 'T -> string) left right =
+ if not (spec.IsWidthSpecified) then
+ box f
+ else
+ if isLeftJustify spec.Flags then
+ adaptPadded spec f left
+ else
+ adaptPadded spec f right
+
+ let inline isNumber (x: ^T) =
+ not (^T: (static member IsPositiveInfinity: 'T -> bool) x) && not (^T: (static member IsNegativeInfinity: 'T -> bool) x) && not (^T: (static member IsNaN: 'T -> bool) x)
- type buf = System.Text.StringBuilder
-
- let stringOfChar (c:char) = System.Char.ToString(c)
- let stringOfInt (i:int) = i.ToString()
-
- []
- type PrintfInfo =
- { mutable leftJustify : bool;
- mutable numPrefixIfPos : char option;
- mutable addZeros : bool; }
-
- let outputSignAndLeftSpace(outputChar,info,pos,width,numDigits) =
- let used =
- if pos then
- match info.numPrefixIfPos with
- | None -> 0
- | Some _ -> 1
- else 1
- let len = numDigits + used
- if not info.leftJustify && not info.addZeros then
- match width with
- | None -> ()
- | Some w ->
- for i = 1 to (w - len) do
- outputChar ' ';
- begin
- if pos then
- match info.numPrefixIfPos with
- | None -> ()
- | Some c -> outputChar c
- else outputChar '-';
- end;
- if not info.leftJustify && info.addZeros then
- match width with
- | None -> ()
- | Some w ->
- for i = 1 to (w - len) do
- outputChar (if info.addZeros then '0' else ' ');
- used
-
- let decode (c:char) = System.Convert.ToInt32(c)
- let encode (x:int) = System.Convert.ToChar(x)
-
- let outputDigit(outputChar,intFormatChar,digit) =
- let digitc =
- if digit < 10
- then decode '0' + digit
- else decode (if intFormatChar = 'x' then 'a' else 'A') + (digit - 10)
- outputChar (encode digitc)
-
- let outputSpace(outputChar,width,len) =
- match width with
- | None -> ()
- | Some width ->
- for i = 1 to (width - len) do
- outputChar ' ';
-
- let outputZeros(outputChar,width,len) =
- match width with
- | None -> ()
- | Some width ->
- for i = 1 to (width - len) do
- outputChar '0'
-
- let outputRightSpace(outputChar,leftJustify,width,len) =
- if leftJustify then outputSpace(outputChar,width,len)
-
- let outputUInt64(outputChar,intFormatChar,width,info,(n:uint64)) =
- let nbase = match intFormatChar with 'o' -> 8uL | 'x' | 'X' -> 16uL | _ -> 10uL
- let numDigits =
- let mutable numDigits = 1
- let mutable nval = n / nbase
- while nval > 0UL do
- numDigits <- numDigits + 1;
- nval <- nval / nbase;
- numDigits
- let topdiv =
- let mutable topdiv = 1UL
- for i = 1 to numDigits - 1 do
- topdiv <- topdiv * nbase;
- topdiv
-
- let len = numDigits + (outputSignAndLeftSpace(outputChar,info,true,width,numDigits))
+ let inline isInteger n =
+ n % LanguagePrimitives.GenericOne = LanguagePrimitives.GenericZero
+
+ let inline isPositive n =
+ n >= LanguagePrimitives.GenericZero
+
+ /// contains functions to handle left\right justifications for non-numeric types (strings\bools)
+ module Basic =
+ let inline leftJustify f padChar =
+ fun (w : int) v ->
+ (f v : string).PadRight(w, padChar)
+
+ let inline rightJustify f padChar =
+ fun (w : int) v ->
+ (f v : string).PadLeft(w, padChar)
+
+
+ /// contains functions to handle left\right and no justification case for numbers
+ module GenericNumber =
+ /// handles right justification when pad char = '0'
+ /// this case can be tricky:
+ /// - negative numbers, -7 should be printed as '-007', not '00-7'
+ /// - positive numbers when prefix for positives is set: 7 should be '+007', not '00+7'
+ let inline rightJustifyWithZeroAsPadChar (str : string) isNumber isPositive w (prefixForPositives : string) =
+ System.Diagnostics.Debug.Assert(prefixForPositives.Length = 0 || prefixForPositives.Length = 1)
+ if isNumber then
+ if isPositive then
+ prefixForPositives + (if w = 0 then str else str.PadLeft(w - prefixForPositives.Length, '0')) // save space to
+ else
+ if str.[0] = '-' then
+ let str = str.Substring(1)
+ "-" + (if w = 0 then str else str.PadLeft(w - 1, '0'))
+ else
+ str.PadLeft(w, '0')
+ else
+ str.PadLeft(w, ' ')
- let mutable residue = n
- let mutable divisor = topdiv
- while divisor > 0UL do
- let digit = residue / divisor
- outputDigit(outputChar,intFormatChar, int32(int64 digit));
- residue <- residue % divisor;
- divisor <- divisor / nbase;
- outputRightSpace(outputChar,info.leftJustify,width,len)
-
- let outputInt64(outputChar,intFormatChar,width,info,(n:int64)) =
- let nbase = match intFormatChar with 'o' -> 8L | 'x' | 'X' -> 16L | _ -> 10L
- let numDigits =
- let mutable numDigits = 1
- let mutable nval = if n >= 0L then n / nbase else - (n / nbase)
- while nval > 0L do
- numDigits <- numDigits + 1;
- nval <- nval / nbase;
- numDigits
- let topdiv =
- let mutable topdiv = 1L
- for i = 1 to numDigits - 1 do
- topdiv <- topdiv * nbase;
- topdiv
+ /// handler right justification when pad char = ' '
+ let inline rightJustifyWithSpaceAsPadChar (str : string) isNumber isPositive w (prefixForPositives : string) =
+ System.Diagnostics.Debug.Assert(prefixForPositives.Length = 0 || prefixForPositives.Length = 1)
+ (if isNumber && isPositive then prefixForPositives + str else str).PadLeft(w, ' ')
- let len = numDigits + (outputSignAndLeftSpace(outputChar,info,(n >= 0L),width,numDigits) )
+ /// handles left justification with formatting with 'G'\'g' - either for decimals or with 'g'\'G' is explicitly set
+ let inline leftJustifyWithGFormat (str : string) isNumber isInteger isPositive w (prefixForPositives : string) padChar =
+ if isNumber then
+ let str = if isPositive then prefixForPositives + str else str
+ // NOTE: difference - for 'g' format we use isInt check to detect situations when '5.0' is printed as '5'
+ // in this case we need to override padding and always use ' ', otherwise we'll produce incorrect results
+ if isInteger then
+ str.PadRight(w, ' ') // don't pad integer numbers with '0' when 'g' format is specified (may yield incorrect results)
+ else
+ str.PadRight(w, padChar) // non-integer => string representation has point => can pad with any character
+ else
+ str.PadRight(w, ' ') // pad NaNs with ' '
+
+ let inline leftJustifyWithNonGFormat (str : string) isNumber isPositive w (prefixForPositives : string) padChar =
+ if isNumber then
+ let str = if isPositive then prefixForPositives + str else str
+ str.PadRight(w, padChar)
+ else
+ str.PadRight(w, ' ') // pad NaNs with ' '
- let mutable residue =
- if n = System.Int64.MinValue then System.Int64.MaxValue
- elif n < 0L then - n
- else n
- let mutable divisor = topdiv
- while divisor > 0L do
- let digit =
- if n = System.Int64.MinValue && divisor = 1L
- then (match intFormatChar with 'd' | 'i' -> 8L | _ -> 100L) // nb. special case for min_int
- else residue / divisor
- outputDigit(outputChar,intFormatChar,int32 digit);
- residue <- residue % divisor;
- divisor <- divisor / nbase;
- outputRightSpace(outputChar,info.leftJustify,width,len)
-
- // The general technique used this file is to interpret
- // a format string and use reflection to construct a function value that matches
- // the specification of the format string.
- //
- // Generics add some serious complications here - we have to generate
- // a function value of exactly the right runtime type, though the most
- // natural scheme is to produce one of type 'obj -> obj'. We get around
- // this by using a semi-reflective approach to creating and invoking
- // function values of the right type. This comes with some
- // overheads (though they are not too bad) and thus could and should be
- // optimized in some special cases, e.g. where a format string
- // just contains a single simple format specifier such as '%x'
-#if FX_ATLEAST_PORTABLE
- let staticInvokeFlags = BindingFlags.Public ||| BindingFlags.Static
-#else
- let staticInvokeFlags = BindingFlags.Public ||| BindingFlags.InvokeMethod ||| BindingFlags.Static
-#endif
- let mkFunctionValue (tys: System.Type[]) (impl:obj->obj) =
- FSharpValue.MakeFunction(FSharpType.MakeFunctionType(tys.[0],tys.[1]), impl)
-
- let funTyC = typeof<(obj -> obj)>.GetGenericTypeDefinition()
- let mkFunTy a b = funTyC.MakeGenericType([| a;b |])
-
- let isNamedType(ty:System.Type) = not (ty.IsArray || ty.IsByRef || ty.IsPointer)
- let isFunctionType (ty1:System.Type) =
- isNamedType(ty1) && ty1.IsGenericType && (ty1.GetGenericTypeDefinition()).Equals(funTyC)
-
- let rec destFunTy (ty:System.Type) =
- if isFunctionType ty then
- ty, ty.GetGenericArguments()
- else
- match ty.BaseType with
- | null -> raise <| System.InvalidOperationException(SR.GetString(SR.printfNotAFunType))
- | b -> destFunTy b
-#if FX_ATLEAST_PORTABLE
- let instanceInvokeFlags = BindingFlags.Public ||| BindingFlags.Instance
-#else
- let instanceInvokeFlags = BindingFlags.Public ||| BindingFlags.InvokeMethod ||| BindingFlags.Instance
-#endif
- let invokeFunctionValue (f:obj) (x:obj) =
- let fTy,_ = destFunTy (f.GetType())
-#if FX_ATLEAST_PORTABLE
- let meth = fTy.GetMethod("Invoke",instanceInvokeFlags)
- meth.Invoke(f,[| x |])
-#else
-#if FX_NO_CULTURE_INFO_ARGS
- fTy.InvokeMember("Invoke",instanceInvokeFlags,(null:Binder),f,[| x |])
+ /// processes given string based depending on values isNumber\isPositive
+ let inline noJustificationCore (str : string) isNumber isPositive prefixForPositives =
+ if isNumber && isPositive then prefixForPositives + str
+ else str
+
+ /// noJustification handler for f : 'T -> string - basic integer types
+ let inline noJustification f (prefix : string) isUnsigned =
+ if isUnsigned then
+ fun v -> noJustificationCore (f v) true true prefix
+ else
+ fun v -> noJustificationCore (f v) true (isPositive v) prefix
+
+ /// noJustification handler for f : string -> 'T -> string - floating point types
+ let inline noJustificationWithFormat f (prefix : string) =
+ fun (fmt : string) v -> noJustificationCore (f fmt v) true (isPositive v) prefix
+
+ /// leftJustify handler for f : 'T -> string - basic integer types
+ let inline leftJustify isGFormat f (prefix : string) padChar isUnsigned =
+ if isUnsigned then
+ if isGFormat then
+ fun (w : int) v ->
+ leftJustifyWithGFormat (f v) true (isInteger v) true w prefix padChar
+ else
+ fun (w : int) v ->
+ leftJustifyWithNonGFormat (f v) true true w prefix padChar
+ else
+ if isGFormat then
+ fun (w : int) v ->
+ leftJustifyWithGFormat (f v) true (isInteger v) (isPositive v) w prefix padChar
+ else
+ fun (w : int) v ->
+ leftJustifyWithNonGFormat (f v) true (isPositive v) w prefix padChar
+
+ /// leftJustify handler for f : string -> 'T -> string - floating point types
+ let inline leftJustifyWithFormat isGFormat f (prefix : string) padChar =
+ if isGFormat then
+ fun (fmt : string) (w : int) v ->
+ leftJustifyWithGFormat (f fmt v) true (isInteger v) (isPositive v) w prefix padChar
+ else
+ fun (fmt : string) (w : int) v ->
+ leftJustifyWithNonGFormat (f fmt v) true (isPositive v) w prefix padChar
+
+ /// rightJustify handler for f : 'T -> string - basic integer types
+ let inline rightJustify f (prefixForPositives : string) padChar isUnsigned =
+ if isUnsigned then
+ if padChar = '0' then
+ fun (w : int) v ->
+ rightJustifyWithZeroAsPadChar (f v) true true w prefixForPositives
+ else
+ System.Diagnostics.Debug.Assert((padChar = ' '))
+ fun (w : int) v ->
+ rightJustifyWithSpaceAsPadChar (f v) true true w prefixForPositives
+ else
+ if padChar = '0' then
+ fun (w : int) v ->
+ rightJustifyWithZeroAsPadChar (f v) true (isPositive v) w prefixForPositives
+
+ else
+ System.Diagnostics.Debug.Assert((padChar = ' '))
+ fun (w : int) v ->
+ rightJustifyWithSpaceAsPadChar (f v) true (isPositive v) w prefixForPositives
+
+ /// rightJustify handler for f : string -> 'T -> string - floating point types
+ let inline rightJustifyWithFormat f (prefixForPositives : string) padChar =
+ if padChar = '0' then
+ fun (fmt : string) (w : int) v ->
+ rightJustifyWithZeroAsPadChar (f fmt v) true (isPositive v) w prefixForPositives
+
+ else
+ System.Diagnostics.Debug.Assert((padChar = ' '))
+ fun (fmt : string) (w : int) v ->
+ rightJustifyWithSpaceAsPadChar (f fmt v) true (isPositive v) w prefixForPositives
+ module Float =
+ let inline noJustification f (prefixForPositives : string) =
+ fun (fmt : string) v ->
+ GenericNumber.noJustificationCore (f fmt v) (isNumber v) (isPositive v) prefixForPositives
+
+ let inline leftJustify isGFormat f (prefix : string) padChar =
+ if isGFormat then
+ fun (fmt : string) (w : int) v ->
+ GenericNumber.leftJustifyWithGFormat (f fmt v) (isNumber v) (isInteger v) (isPositive v) w prefix padChar
+ else
+ fun (fmt : string) (w : int) v ->
+ GenericNumber.leftJustifyWithNonGFormat (f fmt v) (isNumber v) (isPositive v) w prefix padChar
+
+ let inline rightJustify f (prefixForPositives : string) padChar =
+ if padChar = '0' then
+ fun (fmt : string) (w : int) v ->
+ GenericNumber.rightJustifyWithZeroAsPadChar (f fmt v) (isNumber v) (isPositive v) w prefixForPositives
+ else
+ System.Diagnostics.Debug.Assert((padChar = ' '))
+ fun (fmt : string) (w : int) v ->
+ GenericNumber.rightJustifyWithSpaceAsPadChar (f fmt v) (isNumber v) (isPositive v) w prefixForPositives
+
+ let isDecimalFormatSpecifier (spec : FormatSpecifier) =
+ spec.TypeChar = 'M'
+
+ let getPadAndPrefix allowZeroPadding (spec : FormatSpecifier) =
+ let padChar = if allowZeroPadding && isPadWithZeros spec.Flags then '0' else ' ';
+ let prefix =
+ if isPlusForPositives spec.Flags then "+"
+ elif isSpaceForPositives spec.Flags then " "
+ else ""
+ padChar, prefix
+
+ let isGFormat(spec : FormatSpecifier) =
+ isDecimalFormatSpecifier spec || System.Char.ToLower(spec.TypeChar) = 'g'
+
+ let inline basicWithPadding (spec : FormatSpecifier) f =
+ let padChar, _ = getPadAndPrefix false spec
+ Padding.withPadding spec f (Basic.leftJustify f padChar) (Basic.rightJustify f padChar)
+
+ let inline numWithPadding (spec : FormatSpecifier) isUnsigned f =
+ let allowZeroPadding = not (isLeftJustify spec.Flags) || isDecimalFormatSpecifier spec
+ let padChar, prefix = getPadAndPrefix allowZeroPadding spec
+ let isGFormat = isGFormat spec
+ Padding.withPadding spec (GenericNumber.noJustification f prefix isUnsigned) (GenericNumber.leftJustify isGFormat f prefix padChar isUnsigned) (GenericNumber.rightJustify f prefix padChar isUnsigned)
+
+ let inline decimalWithPadding (spec : FormatSpecifier) getFormat defaultFormat f =
+ let padChar, prefix = getPadAndPrefix true spec
+ let isGFormat = isGFormat spec
+ Padding.withPaddingFormatted spec getFormat defaultFormat (GenericNumber.noJustificationWithFormat f prefix) (GenericNumber.leftJustifyWithFormat isGFormat f prefix padChar) (GenericNumber.rightJustifyWithFormat f prefix padChar)
+
+ let inline floatWithPadding (spec : FormatSpecifier) getFormat defaultFormat f =
+ let padChar, prefix = getPadAndPrefix true spec
+ let isGFormat = isGFormat spec
+ Padding.withPaddingFormatted spec getFormat defaultFormat (Float.noJustification f prefix) (Float.leftJustify isGFormat f prefix padChar) (Float.rightJustify f prefix padChar)
+
+ let inline identity v = v
+ let inline toString v = (^T : (member ToString : IFormatProvider -> string)(v, invariantCulture))
+ let inline toFormattedString fmt = fun (v : ^T) -> (^T : (member ToString : string * IFormatProvider -> string)(v, fmt, invariantCulture))
+
+ let inline numberToString c spec alt unsignedConv =
+ if c = 'd' || c = 'i' then
+ numWithPadding spec false (alt >> toString : ^T -> string)
+ elif c = 'u' then
+ numWithPadding spec true (alt >> unsignedConv >> toString : ^T -> string)
+ elif c = 'x' then
+ numWithPadding spec true (alt >> toFormattedString "x" : ^T -> string)
+ elif c = 'X' then
+ numWithPadding spec true (alt >> toFormattedString "X" : ^T -> string )
+ elif c = 'o' then
+ numWithPadding spec true (fun (v : ^T) -> Convert.ToString(int64(unsignedConv (alt v)), 8))
+ else raise (ArgumentException())
+
+ type ObjectPrinter =
+ static member ObjectToString<'T>(spec : FormatSpecifier) =
+ basicWithPadding spec (fun (v : 'T) -> match box v with null -> "" | x -> x.ToString())
+
+ static member GenericToStringCore(v : 'T, opts : Microsoft.FSharp.Text.StructuredPrintfImpl.FormatOptions, bindingFlags) =
+ // printfn %0A is considered to mean 'print width zero'
+ match box v with
+ | null -> ""
+ | _ -> Microsoft.FSharp.Text.StructuredPrintfImpl.Display.anyToStringForPrintf opts bindingFlags v
+
+ static member GenericToString<'T>(spec : FormatSpecifier) =
+ let bindingFlags =
+#if FX_RESHAPED_REFLECTION
+ isPlusForPositives spec.Flags // true - show non-public
#else
- fTy.InvokeMember("Invoke",instanceInvokeFlags,(null:Binder),f,[| x |],CultureInfo.InvariantCulture(*FxCop:1304*))
+ if isPlusForPositives spec.Flags then BindingFlags.Public ||| BindingFlags.NonPublic
+ else BindingFlags.Public
#endif
-#endif
-
- let buildFunctionForOneArgPat (ty: System.Type) impl =
- let _,tys = destFunTy ty
- let rty = tys.[1]
- // PERF: this technique is a bit slow (e.g. in simple cases, like 'sprintf "%x"')
- mkFunctionValue tys (fun inp -> impl rty inp)
-
- let buildFunctionForTwoArgPat args ty i go =
- let _,tys1 = destFunTy ty
- let rty1 = tys1.[1]
- let _,tys2 = destFunTy rty1
- let rty2 = tys2.[1]
- mkFunctionValue tys1 (fun inpf ->
- mkFunctionValue tys2 (fun inpx ->
- go (inpx::inpf::args) rty2 (i+1)))
-
- let buildFunctionForOneFunArgPat args ty i go =
- let _,tys1 = destFunTy ty
- let rty1 = tys1.[1]
- mkFunctionValue tys1 (fun inpf -> go (inpf::args) rty1 (i+1))
-
- let isDigit c = ('0' <= c && c <= '9')
- let rec parseFlags info (fmt:string) i =
- if i >= fmt.Length then raise <| System.ArgumentException (SR.GetString(SR.printfMissingFormatSpecifier));
- match fmt.[i] with
- | '-' -> info.leftJustify <- true; parseFlags info fmt (i+1)
- | '+' -> info.numPrefixIfPos <- Some '+'; parseFlags info fmt (i+1)
- | '0' -> info.addZeros <- true; parseFlags info fmt (i+1)
- | ' ' -> info.numPrefixIfPos <- Some ' '; parseFlags info fmt (i+1)
- | '#' -> raise <| System.ArgumentException (SR.GetString(SR.printfHashFormatSpecifierIllegal));
- | _ -> i
-
- let rec parseDigitsPrecision (fmt:string) len i =
- if i >= len then raise <| System.ArgumentException (SR.GetString(SR.printfPrecisonSpecifierIllegal));
- match fmt.[i] with
- | c when isDigit c -> parseDigitsPrecision fmt len (i+1)
- | _ -> i
-
- let parsePrecision (fmt:string) len i =
- if i >= len then raise <| System.ArgumentException (SR.GetString(SR.printfPrecisonSpecifierIllegal));
- match fmt.[i] with
- | c when isDigit c -> false,parseDigitsPrecision fmt len (i+1)
- | '*' -> true,(i+1)
- | _ -> false,i
-
- let rec parseSliceDotAndPrecision (fmt:string) len i =
- match fmt.[i] with
- | '.' ->
- let w1 = i
- let precisionArg,i = parsePrecision fmt len (i+1)
- w1,Some (precisionArg,i),i
- | _ -> i,None,i
-
- let rec parseSliceWidthAndPrecision (fmt:string) len i =
- if i >= len then raise <| System.ArgumentException (SR.GetString(SR.printfWidthSpecifierIllegal));
- match fmt.[i] with
- | c when isDigit c -> parseSliceWidthAndPrecision fmt len (i+1)
- | '*' -> true,parseSliceDotAndPrecision fmt len (i+1)
- | _ -> false,parseSliceDotAndPrecision fmt len i
- let invariantCulture = System.Globalization.CultureInfo.InvariantCulture
- let parseWidthAndPrecision fmt len i =
- let w0 = i
- let widthArg,(w1,w2,i) = parseSliceWidthAndPrecision fmt len i
- let width =
- if (w0 = w1) then None
- elif widthArg then Some(None)
- else Some (Some(System.Int32.Parse (fmt.[w0..w1-1],invariantCulture)) )
- let precision =
- match w2 with
- | None -> None
- | Some (precisionArg,w2') ->
- if precisionArg then Some(None)
- else Some (Some(System.Int32.Parse (fmt.[w1+1..w2'-1],invariantCulture)) )
- width,precision,i
-
- let newInfo ()=
- { leftJustify = false;
- numPrefixIfPos = None;
- addZeros = false; }
-
- let defaultInfo = newInfo()
-
- let formatString outputChar info width (s:string) isNum =
- match s with
- | null -> outputSpace(outputChar,width,0)
+ let useZeroWidth = isPadWithZeros spec.Flags
+ let opts =
+ let o = Microsoft.FSharp.Text.StructuredPrintfImpl.FormatOptions.Default
+ let o =
+ if useZeroWidth then { o with PrintWidth = 0}
+ elif spec.IsWidthSpecified then { o with PrintWidth = spec.Width}
+ else o
+ if spec.IsPrecisionSpecified then { o with PrintSize = spec.Precision}
+ else o
+ match spec.IsStarWidth, spec.IsStarPrecision with
+ | true, true ->
+ box (fun (v : 'T) (width : int) (prec : int) ->
+ let opts = { opts with PrintSize = prec }
+ let opts = if not useZeroWidth then { opts with PrintWidth = width} else opts
+ ObjectPrinter.GenericToStringCore(v, opts, bindingFlags)
+ )
+ | true, false ->
+ box (fun (v : 'T) (width : int) ->
+ let opts = if not useZeroWidth then { opts with PrintWidth = width} else opts
+ ObjectPrinter.GenericToStringCore(v, opts, bindingFlags)
+ )
+ | false, true ->
+ box (fun (v : 'T) (prec : int) ->
+ let opts = { opts with PrintSize = prec }
+ ObjectPrinter.GenericToStringCore(v, opts, bindingFlags)
+ )
+ | false, false ->
+ box (fun (v : 'T) ->
+ ObjectPrinter.GenericToStringCore(v, opts, bindingFlags)
+ )
+
+ let basicNumberToString (ty : Type) (spec : FormatSpecifier) =
+ System.Diagnostics.Debug.Assert(not spec.IsPrecisionSpecified, "not spec.IsPrecisionSpecified")
+
+ let ch = spec.TypeChar
+
+ match Type.GetTypeCode(ty) with
+ | TypeCode.Int32 -> numberToString ch spec identity (uint32 : int -> uint32)
+ | TypeCode.Int64 -> numberToString ch spec identity (uint64 : int64 -> uint64)
+ | TypeCode.Byte -> numberToString ch spec identity (byte : byte -> byte)
+ | TypeCode.SByte -> numberToString ch spec identity (byte : sbyte -> byte)
+ | TypeCode.Int16 -> numberToString ch spec identity (uint16 : int16 -> uint16)
+ | TypeCode.UInt16 -> numberToString ch spec identity (uint16 : uint16 -> uint16)
+ | TypeCode.UInt32 -> numberToString ch spec identity (uint32 : uint32 -> uint32)
+ | TypeCode.UInt64 -> numberToString ch spec identity (uint64 : uint64 -> uint64)
+ | _ ->
+ if ty === typeof then
+ if IntPtr.Size = 4 then
+ numberToString ch spec (fun (v : IntPtr) -> v.ToInt32()) uint32
+ else
+ numberToString ch spec (fun (v : IntPtr) -> v.ToInt64()) uint64
+ elif ty === typeof then
+ if IntPtr.Size = 4 then
+ numberToString ch spec (fun (v : UIntPtr) -> v.ToUInt32()) uint32
+ else
+ numberToString ch spec (fun (v : UIntPtr) -> v.ToUInt64()) uint64
+
+ else raise (ArgumentException(ty.Name + " not a basic integer type"))
+
+ let basicFloatToString ty spec =
+ let defaultFormat = getFormatForFloat spec.TypeChar DefaultPrecision
+ match Type.GetTypeCode(ty) with
+ | TypeCode.Single -> floatWithPadding spec (getFormatForFloat spec.TypeChar) defaultFormat (fun fmt (v : float32) -> toFormattedString fmt v)
+ | TypeCode.Double -> floatWithPadding spec (getFormatForFloat spec.TypeChar) defaultFormat (fun fmt (v : float) -> toFormattedString fmt v)
+ | TypeCode.Decimal -> decimalWithPadding spec (getFormatForFloat spec.TypeChar) defaultFormat (fun fmt (v : decimal) -> toFormattedString fmt v)
+ | _ -> raise (ArgumentException(ty.Name + " not a basic floating point type"))
+
+ let private NonPublicStatics = BindingFlags.NonPublic ||| BindingFlags.Static
+
+ let private getValueConverter (ty : Type) (spec : FormatSpecifier) : obj =
+ match spec.TypeChar with
+ | 'b' ->
+ System.Diagnostics.Debug.Assert(ty === typeof, "ty === typeof")
+ basicWithPadding spec boolToString
+ | 's' ->
+ System.Diagnostics.Debug.Assert(ty === typeof, "ty === typeof")
+ basicWithPadding spec stringToSafeString
+ | 'c' ->
+ System.Diagnostics.Debug.Assert(ty === typeof, "ty === typeof")
+ basicWithPadding spec (fun (c : char) -> c.ToString())
+ | 'M' ->
+ System.Diagnostics.Debug.Assert(ty === typeof, "ty === typeof")
+ decimalWithPadding spec (fun _ -> "G") "G" (fun fmt (v : decimal) -> toFormattedString fmt v) // %M ignores precision
+ | 'd' | 'i' | 'x' | 'X' | 'u' | 'o'->
+ basicNumberToString ty spec
+ | 'e' | 'E'
+ | 'f' | 'F'
+ | 'g' | 'G' ->
+ basicFloatToString ty spec
+ | 'A' ->
+ let mi = typeof.GetMethod("GenericToString", NonPublicStatics)
+ let mi = mi.MakeGenericMethod(ty)
+ mi.Invoke(null, [| box spec |])
+ | 'O' ->
+ let mi = typeof.GetMethod("ObjectToString", NonPublicStatics)
+ let mi = mi.MakeGenericMethod(ty)
+ mi.Invoke(null, [| box spec |])
| _ ->
- if not info.leftJustify then
- if isNum && info.addZeros then outputZeros(outputChar,width,s.Length)
- else outputSpace(outputChar,width,s.Length);
- s |> String.iter outputChar;
- if info.leftJustify then
- if isNum && info.addZeros then outputZeros(outputChar,width,s.Length)
- else outputSpace(outputChar,width,s.Length)
-
- let capture1 (fmt:string) i args ty (go : obj list -> System.Type -> int -> obj) : obj =
- let info = newInfo()
- let len = fmt.Length
- let i = parseFlags info fmt i
- let width,precision,i = parseWidthAndPrecision fmt len i
- let intFormatChar = fmt.[i]
-
- let captureCoreArgs args ty =
- match intFormatChar with
- | '%' -> go args ty (i+1)
- | 'd' | 'i' | 'o' | 'u' | 'x' | 'X' -> buildFunctionForOneArgPat ty (fun rty n -> go (n::args) rty (i+1))
- | 'l' -> buildFunctionForOneArgPat ty (fun rty n -> go (n::args) rty (i+2))
- | 'n' -> buildFunctionForOneArgPat ty (fun rty n -> go (n::args) rty (i+2))
- | 'L' -> buildFunctionForOneArgPat ty (fun rty n -> go (n::args) rty (i+2))
-
- | 'U' ->
- let i = i+1
- let intFormatChar = fmt.[i]
- match intFormatChar with
- | 'd' | 'i' | 'o' | 'u' | 'x' | 'X' -> buildFunctionForOneArgPat ty (fun rty n -> go (n::args) rty (i+1))
- | 'l' -> buildFunctionForOneArgPat ty (fun rty n -> go (n::args) rty (i+2))
- | 'n' -> buildFunctionForOneArgPat ty (fun rty n -> go (n::args) rty (i+2))
- | 'L' -> buildFunctionForOneArgPat ty (fun rty n -> go (n::args) rty (i+2))
- | _ -> raise <| System.ArgumentException (SR.GetString1(SR.printfSpecifierAfterIllegal, "U"))
-
- | 'f' | 'F' | 'e' | 'E' | 'g' | 'G' -> buildFunctionForOneArgPat ty (fun rty n -> go (n::args) rty (i+1))
- | 'M' -> buildFunctionForOneArgPat ty (fun rty n -> go (n::args) rty (i+1))
- | 's' -> buildFunctionForOneArgPat ty (fun rty n -> go (n::args) rty (i+1))
- | 'c' -> buildFunctionForOneArgPat ty (fun rty n -> go (n::args) rty (i+1))
- | 'b' -> buildFunctionForOneArgPat ty (fun rty n -> go (n::args) rty (i+1))
- | 'O' -> buildFunctionForOneArgPat ty (fun rty xobj -> go (xobj::args) rty (i+1))
- | 'A' -> buildFunctionForOneArgPat ty (fun rty xobj -> go (xobj::args) rty (i+1))
- | 'a' -> buildFunctionForTwoArgPat args ty i go
- | 't' -> buildFunctionForOneFunArgPat args ty i go
- | _ -> raise <| System.ArgumentException(SR.GetString1(SR.printfBadFormatSpecifier,intFormatChar.ToString()))
- let capturePrecisionArg args ty =
- match precision with
- | None | Some(Some _) -> captureCoreArgs args ty
- | Some(None) -> buildFunctionForOneArgPat ty (fun rty n -> captureCoreArgs (n :: args) rty)
- let captureWidthArg args ty =
- match width with
- | None | Some(Some _) -> capturePrecisionArg args ty
- | Some(None) -> buildFunctionForOneArgPat ty (fun rty n -> capturePrecisionArg (n :: args) rty)
- captureWidthArg args ty
+ raise (ArgumentException(SR.GetString(SR.printfBadFormatSpecifier)))
+
+ let extractCurriedArguments (ty : Type) n =
+ System.Diagnostics.Debug.Assert(n = 1 || n = 2 || n = 3, "n = 1 || n = 2 || n = 3")
+ let buf = Array.zeroCreate (n + 1)
+ let rec go (ty : Type) i =
+ if i < n then
+ match ty.GetGenericArguments() with
+ | [| argTy; retTy|] ->
+ buf.[i] <- argTy
+ go retTy (i + 1)
+ | _ -> failwith (String.Format("Expected function with {0} arguments", n))
+ else
+ System.Diagnostics.Debug.Assert((i = n), "i = n")
+ buf.[i] <- ty
+ buf
+ go ty 0
+
+ []
+ let ContinuationOnStack = -1
+
+ type private PrintfBuilderStack() =
+ let args = Stack(10)
+ let types = Stack(5)
+
+ let stackToArray size start count (s : Stack<_>) =
+ let arr = Array.zeroCreate size
+ for i = 0 to count - 1 do
+ arr.[start + i] <- s.Pop()
+ arr
+ member this.GetArgumentAndTypesAsArrays
+ (
+ argsArraySize, argsArrayStartPos, argsArrayTotalCount,
+ typesArraySize, typesArrayStartPos, typesArrayTotalCount
+ ) =
+ let argsArray = stackToArray argsArraySize argsArrayStartPos argsArrayTotalCount args
+ let typesArray = stackToArray typesArraySize typesArrayStartPos typesArrayTotalCount types
+ argsArray, typesArray
+
+ member this.PopContinuationWithType() =
+ System.Diagnostics.Debug.Assert(args.Count = 1, "args.Count = 1")
+ System.Diagnostics.Debug.Assert(types.Count = 1, "types.Count = 1")
+
+ let cont = args.Pop()
+ let contTy = types.Pop()
- let unboxAsInt64 (n:obj) =
- match n with
- | :? sbyte as x -> x |> int64
- | :? int16 as x -> x |> int64
- | :? int32 as x -> x |> int64
- | :? nativeint as x -> x |> int64
- | :? int64 as x -> x
- | :? byte as x -> x |> uint64 |> int64
- | :? uint16 as x -> x |> uint64 |> int64
- | :? uint32 as x -> x |> uint64 |> int64
- | :? uint64 as x -> x |> int64
- | :? unativeint as x -> x |> uint64 |> int64
- | _ -> raise <| System.ArgumentException (SR.GetString(SR.printfBadIntegerForDynamicFomatter))
-
- let unboxAsUInt64 (n:obj) =
- let unsigned =
- match n with
- | :? sbyte as x -> x |> byte |> box
- | :? int16 as x -> x |> uint16 |> box
- | :? int32 as x -> x |> uint32 |> box
- | :? int64 as x -> x |> uint64 |> box
- | :? nativeint as x -> x |> unativeint |> box
- | _ -> n
- unboxAsInt64 unsigned |> uint64
-
- let formatOne (outa: 'c -> unit) (outputChar: char -> unit) (os : 'b) (fmt:string) i args : (int * obj list) =
- let info = newInfo()
- let len = fmt.Length
- let i = parseFlags info fmt i
- let width,precision,i = parseWidthAndPrecision fmt len i
- let intFormatChar = fmt.[i]
-
- let width,args =
- match width,args with
- | None,args -> None,args
- | Some(Some w),args -> Some w,args
- | Some(None),n::args -> Some (unbox n), args
- | _ -> raise <| System.ArgumentException (SR.GetString(SR.printfExpectedWidth))
-
- let precision,args =
- match precision,args with
- | None,args -> None,args
- | Some(Some w),args -> Some w,args
- | Some(None),n::args -> Some (unbox n), args
- | _ -> raise <| System.ArgumentException (SR.GetString(SR.printfExpectedPrecision))
-
- match intFormatChar,args with
- | '%',args ->
- outputChar intFormatChar; i+1, args
- | ('d' | 'i'),n::args ->
- match n with
- | (:? byte | :? uint16 | :? uint32 | :? uint64 | :? unativeint) ->
- outputUInt64(outputChar,intFormatChar,width,info,(unboxAsUInt64 n));
- | _ ->
- outputInt64(outputChar,intFormatChar,width,info,(unboxAsInt64 n));
- i+1,args
- | ('o' | 'u' | 'x' | 'X'),n::args ->
- outputUInt64(outputChar,intFormatChar,width,info,(unboxAsUInt64 n));
- i+1,args
- | ('l' | 'L'),n::args ->
- let i = i+1
- let intFormatChar = fmt.[i]
- match intFormatChar with
- | 'd' | 'i' ->
- outputInt64(outputChar,intFormatChar,width,info,(unboxAsInt64 n));
- i+1,args
- | 'o' | 'u' | 'x' | 'X' ->
- outputUInt64(outputChar,intFormatChar,width,info,(unboxAsUInt64 n));
- i+1,args
- | _ -> raise <| System.ArgumentException (SR.GetString1(SR.printfSpecifierAfterIllegal, "n"))
- | 'n',n::args ->
- let i = i+1
- let intFormatChar = fmt.[i]
- match intFormatChar with
- | 'd' | 'i' ->
- outputInt64(outputChar,intFormatChar,width,info,(unboxAsInt64 n));
- i+1,args
- | 'o' | 'u' | 'x' | 'X' ->
- outputUInt64(outputChar,intFormatChar,width,info,(unboxAsUInt64 n));
- i+1,args
- | _ -> raise <| System.ArgumentException (SR.GetString1(SR.printfSpecifierAfterIllegal, "l"))
- | 'U',n::args ->
- let i = i+1
- let intFormatChar = fmt.[i]
- match intFormatChar with
- | 'd' | 'i' | 'o' | 'u' | 'x' | 'X' ->
- outputUInt64(outputChar,intFormatChar,width,info,(unboxAsUInt64 n));
- i+1,args
- | 'l' ->
- let i = i+1
- let intFormatChar = fmt.[i]
- match intFormatChar with
- | 'd' | 'i' | 'o' | 'u' | 'x' | 'X' ->
- outputUInt64(outputChar,intFormatChar,width,info,(unboxAsUInt64 n));
- i+1,args
- | _ -> raise <| System.ArgumentException (SR.GetString1(SR.printfSpecifierAfterIllegal, "Ul"))
- | 'n' ->
- let i = i+1
- let intFormatChar = fmt.[i]
- match intFormatChar with
- | 'd' | 'i' | 'o' | 'u' | 'x' | 'X' ->
- outputUInt64(outputChar,intFormatChar,width,info,(unboxAsUInt64 n));
- i+1,args
- | _ -> raise <| System.ArgumentException (SR.GetString1(SR.printfSpecifierAfterIllegal, "Un"))
- | 'L' ->
- let i = i+1
- let intFormatChar = fmt.[i]
- match intFormatChar with
- | 'd' | 'i' | 'o' | 'u' | 'x' | 'X' ->
- outputUInt64(outputChar,intFormatChar,width,info,(unboxAsUInt64 n));
- i+1,args
- | _ -> raise <| System.ArgumentException (SR.GetString1(SR.printfSpecifierAfterIllegal, "UL"))
- | _ -> raise <| System.ArgumentException (SR.GetString1(SR.printfSpecifierAfterIllegal, "U"))
-
- | ('f' | 'F' | 'e' | 'E' | 'g' | 'G'),n::args ->
- let s, number, positive =
- match n with
- | :? float as f -> f.ToString(stringOfChar intFormatChar + (match precision with None -> "6" | Some n -> stringOfInt (max (min n 99) 0)),invariantCulture), not (f = infinity || f = -infinity || System.Double.IsNaN f), f >= 0.
- | :? float32 as f -> f.ToString(stringOfChar intFormatChar + (match precision with None -> "6" | Some n -> stringOfInt (max (min n 99) 0)),invariantCulture), not (f = infinityf || f = -infinityf || System.Single.IsNaN f), f >= 0.f
- | :? decimal as f -> f.ToString(stringOfChar intFormatChar + (match precision with None -> "6" | Some n -> stringOfInt (max (min n 99) 0)),invariantCulture), true, f >= 0M
- | _ -> raise <| System.ArgumentException (SR.GetString(SR.printfBadFloatValue))
-
- let s = match info.numPrefixIfPos with Some c when positive -> stringOfChar c + s | _ -> s
- formatString outputChar info width s number;
- i+1,args
- | 'M',n::args ->
- let d = (unbox n : System.Decimal)
- let s = d.ToString("G",invariantCulture)
- let s = match info.numPrefixIfPos with Some c when d >= 0M -> stringOfChar c + s | _ -> s
- formatString outputChar info width s true;
- i+1,args
- | 's',nobj::args -> formatString outputChar info width (unbox nobj) false; i+1,args
- | 'c',nobj::args -> formatString outputChar info width (stringOfChar (unbox nobj)) false; i+1,args
- | 'b',nobj::args -> formatString outputChar info width (if (unbox nobj) then "true" else "false") false; i+1,args
- | 'O',xobj::args -> formatString outputChar info width (match xobj with null -> "" | _ -> xobj.ToString()) false; i+1,args
- | 'A',xobj::args ->
- let bindingFlags =
- match info.numPrefixIfPos with
- | None -> BindingFlags.Public // Default see Public only
- | Some '+' -> BindingFlags.Public ||| BindingFlags.NonPublic // %+A, sees anything possible
- | Some c -> failwith ("internal: %A has an unexpected numeric prefix '" + string c + "'")
- let opts = FormatOptions.Default
- let opts = match width with None -> opts | Some w -> { opts with PrintWidth = w }
- // printfn %0A is considered to mean 'print width zero'
- let opts = if info.addZeros then { opts with PrintWidth = 0 } else opts
+ cont, contTy
+
+ member this.PopValueUnsafe() = args.Pop()
+
+ member this.PushContinuationWithType (cont : obj, contTy : Type) =
+ System.Diagnostics.Debug.Assert(this.IsEmpty, "this.IsEmpty")
+ System.Diagnostics.Debug.Assert(
+ (
+ let _arg, retTy = Microsoft.FSharp.Reflection.FSharpType.GetFunctionElements(cont.GetType())
+ contTy.IsAssignableFrom retTy
+ ),
+ "incorrect type"
+ )
+
+ this.PushArgumentWithType(cont, contTy)
+
+ member this.PushArgument(value : obj) =
+ args.Push value
+
+ member this.PushArgumentWithType(value : obj, ty) =
+ args.Push value
+ types.Push ty
+
+ member this.HasContinuationOnStack(expectedNumberOfArguments) =
+ types.Count = expectedNumberOfArguments + 1
+
+ member this.IsEmpty =
+ System.Diagnostics.Debug.Assert(args.Count = types.Count, "args.Count = types.Count")
+ args.Count = 0
+
+ /// Parses format string and creates result printer function.
+ /// First it recursively consumes format string up to the end, then during unwinding builds printer using PrintfBuilderStack as storage for arguments.
+ /// idea of implementation is very simple: every step can either push argument to the stack (if current block of 5 format specifiers is not yet filled)
+ // or grab the content of stack, build intermediate printer and push it back to stack (so it can later be consumed by as argument)
+ type private PrintfBuilder<'S, 'Re, 'Res>() =
+
+ let mutable count = 0
+
+ let verifyMethodInfoWasTaken (_mi : System.Reflection.MemberInfo) =
+#if DEBUG
+ if _mi = null then
+ ignore (System.Diagnostics.Debugger.Launch())
+#else
+ ()
+#endif
- let opts = match precision with None -> opts | Some w -> { opts with PrintSize = w }
- let txt =
- match xobj with
- | null -> ""
- | _ ->
- Display.anyToStringForPrintf opts bindingFlags xobj
-
- txt |> String.iter outputChar;
- i+1,args
- | 'a',fobj::xobj::args ->
- outa (unbox (invokeFunctionValue (invokeFunctionValue fobj (box os)) xobj));
- i+1,args
- | 't',f::args -> outa ((unbox f) os); i+1,args
- | _ -> raise <| System.ArgumentException (SR.GetString(SR.printfBadFormatSpecifier))
-
-
- let gprintf (initialize : unit -> 'b * ('c -> unit) * (char -> unit) * (unit -> 'd)) (fmt : PrintfFormat<'a,'b,'c,'d>) : 'a =
- let fmt = fmt.Value
- match fmt with
- // optimize some common cases
- | "%s" -> unbox (box (fun (s:string) -> let _,_,outputChar,finalize = initialize() in formatString outputChar defaultInfo None s false; finalize()))
- // | "%x" -> unbox (box (fun (n:int) -> let os,outa,outputChar,finalize = initialize() in outputUInt64 outputChar 'x' None defaultInfo (int32_to_uint64 n); finalize()))
- // | "%d" -> unbox (box (fun (n:int) -> let os,outa,outputChar,finalize = initialize() in outputInt64 outputChar 'd' None defaultInfo (int32_to_int64 n); finalize()))
- | _ ->
- let len = fmt.Length
-
- /// After all arguments are captures we reinterpret and execute the actions
- let run args =
- let os,outa,outputChar,finalize = initialize()
- let rec go args i =
- if i >= len || (fmt.[i] = '%' && i+1 >= len) then (box (finalize()))
- elif System.Char.IsSurrogatePair(fmt,i) then
- outputChar fmt.[i];
- outputChar fmt.[i+1];
- go args (i+2)
+ let buildSpecialChained(spec : FormatSpecifier, argTys : Type[], prefix : string, tail : obj, retTy) =
+ if spec.TypeChar = 'a' then
+ let mi = typeof>.GetMethod("LittleAChained", NonPublicStatics)
+ verifyMethodInfoWasTaken mi
+ let mi = mi.MakeGenericMethod([| argTys.[1]; retTy |])
+ let args = [| box prefix; tail |]
+ mi.Invoke(null, args)
+ elif spec.TypeChar = 't' then
+ let mi = typeof>.GetMethod("TChained", NonPublicStatics)
+ verifyMethodInfoWasTaken mi
+ let mi = mi.MakeGenericMethod([| retTy |])
+ let args = [| box prefix; tail |]
+ mi.Invoke(null, args)
+ else
+ System.Diagnostics.Debug.Assert(spec.IsStarPrecision || spec.IsStarWidth , "spec.IsStarPrecision || spec.IsStarWidth ")
+
+ let mi =
+ let n = if spec.IsStarWidth = spec.IsStarPrecision then 2 else 1
+ let prefix = if spec.TypeChar = '%' then "PercentStarChained" else "StarChained"
+ let name = prefix + (string n)
+ typeof>.GetMethod(name, NonPublicStatics)
+
+ verifyMethodInfoWasTaken mi
+
+ let argTypes, args =
+ if spec.TypeChar = '%' then
+ [| retTy |], [| box prefix; tail |]
+ else
+ let argTy = argTys.[argTys.Length - 2]
+ let conv = getValueConverter argTy spec
+ [| argTy; retTy |], [| box prefix; box conv; tail |]
+
+ let mi = mi.MakeGenericMethod argTypes
+ mi.Invoke(null, args)
+
+ let buildSpecialFinal(spec : FormatSpecifier, argTys : Type[], prefix : string, suffix : string) =
+ if spec.TypeChar = 'a' then
+ let mi = typeof>.GetMethod("LittleAFinal", NonPublicStatics)
+ verifyMethodInfoWasTaken mi
+ let mi = mi.MakeGenericMethod(argTys.[1] : Type)
+ let args = [| box prefix; box suffix |]
+ mi.Invoke(null, args)
+ elif spec.TypeChar = 't' then
+ let mi = typeof>.GetMethod("TFinal", NonPublicStatics)
+ verifyMethodInfoWasTaken mi
+ let args = [| box prefix; box suffix |]
+ mi.Invoke(null, args)
+ else
+ System.Diagnostics.Debug.Assert(spec.IsStarPrecision || spec.IsStarWidth , "spec.IsStarPrecision || spec.IsStarWidth ")
+
+ let mi =
+ let n = if spec.IsStarWidth = spec.IsStarPrecision then 2 else 1
+ let prefix = if spec.TypeChar = '%' then "PercentStarFinal" else "StarFinal"
+ let name = prefix + (string n)
+ typeof>.GetMethod(name, NonPublicStatics)
+
+ verifyMethodInfoWasTaken mi
+
+ let mi, args =
+ if spec.TypeChar = '%' then
+ mi, [| box prefix; box suffix |]
+ else
+ let argTy = argTys.[argTys.Length - 2]
+ let mi = mi.MakeGenericMethod(argTy)
+ let conv = getValueConverter argTy spec
+ mi, [| box prefix; box conv; box suffix |]
+
+ mi.Invoke(null, args)
+
+ let buildPlainFinal(args : obj[], argTypes : Type[]) =
+ let mi = typeof>.GetMethod("Final" + (argTypes.Length.ToString()), NonPublicStatics)
+ verifyMethodInfoWasTaken mi
+ let mi = mi.MakeGenericMethod(argTypes)
+ mi.Invoke(null, args)
+
+ let buildPlainChained(args : obj[], argTypes : Type[]) =
+ let mi = typeof>.GetMethod("Chained" + ((argTypes.Length - 1).ToString()), NonPublicStatics)
+ verifyMethodInfoWasTaken mi
+ let mi = mi.MakeGenericMethod(argTypes)
+ mi.Invoke(null, args)
+
+ let builderStack = PrintfBuilderStack()
+
+ let ContinuationOnStack = -1
+
+ let buildPlain numberOfArgs prefix =
+ let n = numberOfArgs * 2
+ let hasCont = builderStack.HasContinuationOnStack numberOfArgs
+
+ let extra = if hasCont then 1 else 0
+ let plainArgs, plainTypes =
+ builderStack.GetArgumentAndTypesAsArrays(n + 1, 1, n, (numberOfArgs + extra), 0, numberOfArgs)
+
+ plainArgs.[0] <- box prefix
+
+ if hasCont then
+ let cont, contTy = builderStack.PopContinuationWithType()
+ plainArgs.[plainArgs.Length - 1] <- cont
+ plainTypes.[plainTypes.Length - 1] <- contTy
+
+ buildPlainChained(plainArgs, plainTypes)
+ else
+ buildPlainFinal(plainArgs, plainTypes)
+
+ let rec parseFromFormatSpecifier (prefix : string) (s : string) (funcTy : Type) i : int =
+
+ if i >= s.Length then 0
+ else
+
+ System.Diagnostics.Debug.Assert(s.[i] = '%', "s.[i] = '%'")
+ count <- count + 1
+
+ let flags, i = FormatString.parseFlags s (i + 1)
+ let width, i = FormatString.parseWidth s i
+ let precision, i = FormatString.parsePrecision s i
+ let typeChar, i = FormatString.parseTypeChar s i
+ let spec = { TypeChar = typeChar; Precision = precision; Flags = flags; Width = width}
+
+ let next, suffix = FormatString.findNextFormatSpecifier s i
+ let argTys =
+ let n =
+ if spec.TypeChar = 'a' then 2
+ elif spec.IsStarWidth || spec.IsStarPrecision then
+ if spec.IsStarWidth = spec.IsStarPrecision then 3
+ else 2
+ else 1
+
+ let n = if spec.TypeChar = '%' then n - 1 else n
+
+ System.Diagnostics.Debug.Assert(n <> 0, "n <> 0")
+
+ extractCurriedArguments funcTy n
+
+ let retTy = argTys.[argTys.Length - 1]
+
+ let numberOfArgs = parseFromFormatSpecifier suffix s retTy next
+
+ if spec.TypeChar = 'a' || spec.TypeChar = 't' || spec.IsStarWidth || spec.IsStarPrecision then
+ if numberOfArgs = ContinuationOnStack then
+
+ let cont, contTy = builderStack.PopContinuationWithType()
+ let currentCont = buildSpecialChained(spec, argTys, prefix, cont, contTy)
+ builderStack.PushContinuationWithType(currentCont, funcTy)
+
+ ContinuationOnStack
+ else
+ if numberOfArgs = 0 then
+ System.Diagnostics.Debug.Assert(builderStack.IsEmpty, "builderStack.IsEmpty")
+
+ let currentCont = buildSpecialFinal(spec, argTys, prefix, suffix)
+ builderStack.PushContinuationWithType(currentCont, funcTy)
+ ContinuationOnStack
else
+
+
+ let hasCont = builderStack.HasContinuationOnStack(numberOfArgs)
+
+ let expectedNumberOfItemsOnStack = numberOfArgs * 2
+ let sizeOfTypesArray =
+ if hasCont then numberOfArgs + 1
+ else numberOfArgs
+
+ let plainArgs, plainTypes =
+ builderStack.GetArgumentAndTypesAsArrays(expectedNumberOfItemsOnStack + 1, 1, expectedNumberOfItemsOnStack, sizeOfTypesArray, 0, numberOfArgs )
+
+ plainArgs.[0] <- box suffix
+
+ let next =
+ if hasCont then
+ let nextCont, nextContTy = builderStack.PopContinuationWithType()
+ plainArgs.[plainArgs.Length - 1] <- nextCont
+ plainTypes.[plainTypes.Length - 1] <- nextContTy
+ buildPlainChained(plainArgs, plainTypes)
+ else
+ buildPlainFinal(plainArgs, plainTypes)
+
+ let next = buildSpecialChained(spec, argTys, prefix, next, retTy)
+ builderStack.PushContinuationWithType(next, funcTy)
+
+ ContinuationOnStack
+ else
+ if numberOfArgs = ContinuationOnStack then
+ let idx = argTys.Length - 2
+ builderStack.PushArgument suffix
+ builderStack.PushArgumentWithType((getValueConverter argTys.[idx] spec), argTys.[idx])
+ 1
+ else
+ builderStack.PushArgument suffix
+ builderStack.PushArgumentWithType((getValueConverter argTys.[0] spec), argTys.[0])
- match fmt.[i] with
- | '%' ->
- let i,args = formatOne outa outputChar os fmt (i+1) args
- go args i
- | c ->
- outputChar c; go args (i+1)
- go args 0
-
- /// Function to capture the arguments and then run.
- let rec capture args ty i =
- if i >= len || (fmt.[i] = '%' && i+1 >= len) then
- run (List.rev args)
- elif System.Char.IsSurrogatePair(fmt,i) then
- capture args ty (i+2)
+ if numberOfArgs = MaxArgumentsInSpecialization - 1 then
+ let cont = buildPlain (numberOfArgs + 1) prefix
+ builderStack.PushContinuationWithType(cont, funcTy)
+ ContinuationOnStack
+ else
+ numberOfArgs + 1
+
+ let parseFormatString (s : string) (funcTy : System.Type) : obj =
+ let prefixPos, prefix = FormatString.findNextFormatSpecifier s 0
+ if prefixPos = s.Length then
+ box (fun (env : unit -> PrintfEnv<'S, 'Re, 'Res>) ->
+ let env = env()
+ env.Write prefix
+ env.Finalize()
+ )
+ else
+ let n = parseFromFormatSpecifier prefix s funcTy prefixPos
+
+ if n = ContinuationOnStack || n = 0 then
+ builderStack.PopValueUnsafe()
else
- match fmt.[i] with
- | '%' ->
- let i = i+1
- capture1 fmt i args ty capture
- | _ ->
- capture args ty (i+1)
+ buildPlain n prefix
+
+ member this.Build<'T>(s : string) : PrintfFactory<'S, 'Re, 'Res, 'T> * int =
+ parseFormatString s typeof<'T> :?> _, (2 * count + 1) // second component is used in SprintfEnv as value for internal buffer
+
+ /// Type of element that is stored in cache
+ /// Pair: factory for the printer + number of text blocks that printer will produce (used to preallocate buffers)
+ type CachedItem<'T, 'State, 'Residue, 'Result> = PrintfFactory<'State, 'Residue, 'Result, 'T> * int
+
+ /// 2-level cache.
+ /// 1st-level stores last value that was consumed by the current thread in thread-static field thus providing shortcuts for scenarios when
+ /// printf is called in tight loop
+ /// 2nd level is global dictionary that maps format string to the corresponding PrintfFactory
+ type Cache<'T, 'State, 'Residue, 'Result>() =
+ static let generate(fmt) = PrintfBuilder<'State, 'Residue, 'Result>().Build<'T>(fmt)
+#if FSHARP_CORE_4_5
+ static let mutable map = System.Collections.Concurrent.ConcurrentDictionary>()
+ static let getOrAddFunc = Func<_, _>(generate)
+#else
+ static let mutable map = Dictionary>()
+#endif
- (unbox (capture [] (typeof<'a>) 0) : 'a)
+ static let get(key : string) =
+#if FSHARP_CORE_4_5
+ map.GetOrAdd(key, getOrAddFunc)
+#else
+ lock map (fun () ->
+ let mutable res = Unchecked.defaultof<_>
+ if map.TryGetValue(key, &res) then res
+ else
+ let v =
+#if DEBUG
+ try
+ generate(key)
+ with
+ e -> raise (ArgumentException("PRINTF::" + key, e))
+#else
+ generate(key)
+#endif
+ map.Add(key, v)
+ v
+ )
+#endif
+
+ []
+#if FX_NO_THREAD_STATIC
+#else
+ []
+#endif
+ static val mutable private last : string * CachedItem<'T, 'State, 'Residue, 'Result>
+
+ static member Get(key : Format<'T, 'State, 'Residue, 'Result>) =
+ if not (Cache<'T, 'State, 'Residue, 'Result>.last === null)
+ && key.Value.Equals (fst Cache<'T, 'State, 'Residue, 'Result>.last) then
+ snd Cache<'T, 'State, 'Residue, 'Result>.last
+ else
+ let v = get(key.Value)
+ Cache<'T, 'State, 'Residue, 'Result>.last <- (key.Value, v)
+ v
+
+ type StringPrintfEnv<'Result>(k, n) =
+ inherit PrintfEnv(())
+
+ let buf : string[] = Array.zeroCreate n
+ let mutable ptr = 0
+
+ override this.Finalize() : 'Result = k (String.Concat(buf))
+ override this.Write(s : string) =
+ buf.[ptr] <- s
+ ptr <- ptr + 1
+ override this.WriteT(s) = this.Write s
+
+ type StringBuilderPrintfEnv<'Result>(k, buf) =
+ inherit PrintfEnv(buf)
+ override this.Finalize() : 'Result = k ()
+ override this.Write(s : string) = ignore(buf.Append(s))
+ override this.WriteT(()) = ()
+
+ type TextWriterPrintfEnv<'Result>(k, tw : IO.TextWriter) =
+ inherit PrintfEnv(tw)
+ override this.Finalize() : 'Result = k()
+ override this.Write(s : string) = tw.Write s
+ override this.WriteT(()) = ()
+
+ let inline doPrintf fmt f =
+ let formatter, n = Cache<_, _, _, _>.Get fmt
+ let env() = f(n)
+ formatter env
[]
-module Printf =
+module Printf =
- open System.Text
- open System.Diagnostics
open PrintfImpl
- type BuilderFormat<'T,'Result> = Format<'T, StringBuilder, unit, 'Result>
+ type BuilderFormat<'T,'Result> = Format<'T, System.Text.StringBuilder, unit, 'Result>
type StringFormat<'T,'Result> = Format<'T, unit, string, 'Result>
- type TextWriterFormat<'T,'Result> = Format<'T, TextWriter, unit, 'Result>
+ type TextWriterFormat<'T,'Result> = Format<'T, System.IO.TextWriter, unit, 'Result>
type BuilderFormat<'T> = BuilderFormat<'T,unit>
type StringFormat<'T> = StringFormat<'T,string>
type TextWriterFormat<'T> = TextWriterFormat<'T,unit>
-#if EXTRAS_FOR_SILVERLIGHT_COMPILER
- let outWriter = ref System.Console.Out
- let errorWriter = ref System.Console.Error
+ []
+ let ksprintf continutation (format : StringFormat<'T, 'Result>) : 'T =
+ doPrintf format (fun n ->
+ StringPrintfEnv(continutation, n) :> PrintfEnv<_, _, _>
+ )
- let setWriter (out : System.IO.TextWriter) = outWriter := out
- let setError (error : System.IO.TextWriter) = errorWriter := error
-#endif
-
[]
- let ksprintf (f : string -> 'd) (fp : StringFormat<'a,'d>) =
- let init () =
- let buf = new StringBuilder()
- let outputChar (c:char) = ignore (buf.Append(c))
- let outa (s:string) = ignore (buf.Append(s))
- let finish () = f (buf.ToString())
- (),outa,outputChar,finish
- PrintfImpl.gprintf init fp
+ let sprintf (format : StringFormat<'T>) = ksprintf id format
[]
let kprintf f fmt = ksprintf f fmt
- let kprintf_imperative f handle outputChar fmt =
- let init () =
- let outa () = ()
- handle,outa,outputChar,f
- PrintfImpl.gprintf init fmt
-
[]
- let kbprintf f (buf: StringBuilder) fmt = kprintf_imperative f buf (fun c -> ignore (buf.Append(c))) fmt
-
+ let kbprintf f (buf: System.Text.StringBuilder) fmt =
+ doPrintf fmt (fun _ ->
+ StringBuilderPrintfEnv(f, buf) :> PrintfEnv<_, _, _>
+ )
+
[]
- let kfprintf f os fmt = kprintf_imperative f (os :> TextWriter) (fun c -> ignore (os.Write(c))) fmt
-
- []
- let sprintf fmt = ksprintf (fun x -> x) fmt
-
- []
- let failwithf fmt = ksprintf failwith fmt
+ let kfprintf f os fmt =
+ doPrintf fmt (fun _ ->
+ TextWriterPrintfEnv(f, os) :> PrintfEnv<_, _, _>
+ )
[]
- let bprintf buf fmt = kbprintf (fun _ -> ()) buf fmt
+ let bprintf buf fmt = kbprintf ignore buf fmt
[]
- let fprintf (os: TextWriter) fmt = kfprintf (fun _ -> ()) os fmt
+ let fprintf (os: System.IO.TextWriter) fmt = kfprintf ignore os fmt
[]
- let fprintfn (os: TextWriter) fmt = kfprintf (fun _ -> os.WriteLine()) os fmt
+ let fprintfn (os: System.IO.TextWriter) fmt = kfprintf (fun _ -> os.WriteLine()) os fmt
+
+ []
+ let failwithf fmt = ksprintf failwith fmt
#if FX_NO_SYSTEM_CONSOLE
#else
#if EXTRAS_FOR_SILVERLIGHT_COMPILER
+ let outWriter = ref System.Console.Out
+ let errorWriter = ref System.Console.Error
+
+ let setWriter (out : System.IO.TextWriter) = outWriter := out
+ let setError (error : System.IO.TextWriter) = errorWriter := error
+
[]
let printf fmt = fprintf (!outWriter) fmt
@@ -648,6 +1399,4 @@ module Printf =
[]
let eprintfn fmt = fprintfn System.Console.Error fmt
#endif
-#endif
-
-
+#endif
\ No newline at end of file
diff --git a/src/fsharp/FSharp.Core/quotations.fs b/src/fsharp/FSharp.Core/quotations.fs
index e2b3022fd5..c4c213c8de 100755
--- a/src/fsharp/FSharp.Core/quotations.fs
+++ b/src/fsharp/FSharp.Core/quotations.fs
@@ -30,6 +30,12 @@ open Microsoft.FSharp.Text.StructuredPrintfImpl.LayoutOps
#nowarn "52" // The value has been copied to ensure the original is not mutated by this operation
+#if FX_RESHAPED_REFLECTION
+open PrimReflectionAdapters
+open ReflectionAdapters
+type BindingFlags = ReflectionAdapters.BindingFlags
+#endif
+
//--------------------------------------------------------------------------
// RAW quotations - basic data types
//--------------------------------------------------------------------------
@@ -61,7 +67,11 @@ module Helpers =
let staticBindingFlags = BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic ||| BindingFlags.DeclaredOnly
let staticOrInstanceBindingFlags = BindingFlags.Instance ||| BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic ||| BindingFlags.DeclaredOnly
let instanceBindingFlags = BindingFlags.Instance ||| BindingFlags.Public ||| BindingFlags.NonPublic ||| BindingFlags.DeclaredOnly
- let publicOrPrivateBindingFlags = System.Reflection.BindingFlags.Public ||| System.Reflection.BindingFlags.NonPublic
+#if FX_RESHAPED_REFLECTION
+ let publicOrPrivateBindingFlags = true
+#else
+ let publicOrPrivateBindingFlags = BindingFlags.Public ||| BindingFlags.NonPublic
+#endif
let isDelegateType (typ:Type) =
if typ.IsSubclassOf(typeof) then
@@ -81,6 +91,8 @@ module Helpers =
| null -> nullArg argName
| _ -> ()
+ let getTypesFromParamInfos (infos : ParameterInfo[]) = infos |> Array.map (fun pi -> pi.ParameterType)
+
open Helpers
@@ -844,6 +856,14 @@ module Patterns =
//-------------------------------------------------------------------------
// General Method Binder
+ /// Usually functions in modules are not overloadable so having name is enough to recover the function.
+ /// However type extensions break this assumption - it is possible to have multiple extension methods in module that will have the same name.
+ /// This type is used to denote different binding results so we can distinguish the latter case and retry binding later when more information is available.
+ []
+ type ModuleDefinitionBindingResult<'T, 'R> =
+ | Unique of 'T
+ | Ambiguous of 'R
+
let typeEquals (s:Type) (t:Type) = s.Equals(t)
let typesEqual (ss:Type list) (tt:Type list) =
(ss.Length = tt.Length) && List.forall2 typeEquals ss tt
@@ -914,12 +934,92 @@ module Patterns =
match ty.GetProperty(nm,staticBindingFlags) with
| null -> raise <| System.InvalidOperationException (SR.GetString2(SR.QcannotBindProperty, nm, ty.ToString()))
| res -> res
-
-
+
+ // tries to locate unique function in a given type
+ // in case of multiple candidates returns None so bindModuleFunctionWithCallSiteArgs will be used for more precise resolution
let bindModuleFunction (ty:Type,nm) =
- match ty.GetMethod(nm,staticBindingFlags) with
- | null -> raise <| System.InvalidOperationException (SR.GetString2(SR.QcannotBindFunction, nm, ty.ToString()))
- | res -> res
+ match ty.GetMethods(staticBindingFlags) |> Array.filter (fun mi -> mi.Name = nm) with
+ | [||] -> raise <| System.InvalidOperationException (SR.GetString2(SR.QcannotBindFunction, nm, ty.ToString()))
+ | [| res |] -> Some res
+ | _ -> None
+
+ let bindModuleFunctionWithCallSiteArgs (ty:Type, nm, argTypes : Type list, tyArgs : Type list) =
+ let argTypes = List.toArray argTypes
+ let tyArgs = List.toArray tyArgs
+ let methInfo =
+ try
+#if FX_ATLEAST_PORTABLE
+ match ty.GetMethod(nm, argTypes) with
+#else
+ match ty.GetMethod(nm,staticOrInstanceBindingFlags,null, argTypes,null) with
+#endif
+ | null -> None
+ | res -> Some(res)
+ with :? AmbiguousMatchException -> None
+ match methInfo with
+ | Some methInfo -> methInfo
+ | _ ->
+ // narrow down set of candidates by removing methods with a different name\number of arguments\number of type parameters
+ let candidates =
+ ty.GetMethods(staticBindingFlags)
+ |> Array.filter(fun mi ->
+ mi.Name = nm &&
+ mi.GetParameters().Length = argTypes.Length &&
+ let methodTyArgCount = if mi.IsGenericMethod then mi.GetGenericArguments().Length else 0
+ methodTyArgCount = tyArgs.Length
+ )
+ let fail() = raise <| System.InvalidOperationException (SR.GetString2(SR.QcannotBindFunction, nm, ty.ToString()))
+ match candidates with
+ | [||] -> fail()
+ | [| solution |] -> solution
+ | candidates ->
+ let solution =
+ // no type arguments - just perform pairwise comparison of type in methods signature and argument type from the callsite
+ if tyArgs.Length = 0 then
+ candidates
+ |> Array.tryFind(fun mi ->
+ let paramTys = mi.GetParameters() |> Array.map (fun pi -> pi.ParameterType)
+ Array.forall2 (=) argTypes paramTys
+ )
+ else
+ let FAIL = -1
+ let MATCH = 2
+ let GENERIC_MATCH = 1
+ // if signature has type arguments then it is possible to have several candidates like
+ // - Foo(_ : 'a)
+ // - Foo(_ : int)
+ // and callsite
+ // - Foo(_ : int)
+ // here instantiation of first method we'll have two similar signatures
+ // however compiler will pick second one and we must do the same.
+
+ // here we compute weights for every signature
+ // for every parameter type:
+ // - non-matching with actual argument type stops computation and return FAIL as the final result
+ // - exact match with actual argument type adds MATCH value to the final result
+ // - parameter type is generic that after instantiation matches actual argument type adds GENERIC_MATCH to the final result
+ // - parameter type is generic that after instantiation doesn't actual argument type stops computation and return FAIL as the final result
+ let weight (mi : MethodInfo) =
+ let parameters = mi.GetParameters()
+ let rec iter i acc =
+ if i >= argTypes.Length then acc
+ else
+ let param = parameters.[i]
+ if param.ParameterType.IsGenericParameter then
+ let actualTy = tyArgs.[param.ParameterType.GenericParameterPosition]
+ if actualTy = argTypes.[i] then iter (i + 1) (acc + GENERIC_MATCH) else FAIL
+ else
+ if param.ParameterType = argTypes.[i] then iter (i + 1) (acc + MATCH) else FAIL
+ iter 0 0
+ let solution, weight =
+ candidates
+ |> Array.map (fun mi -> mi, weight mi)
+ |> Array.maxBy snd
+ if weight = FAIL then None
+ else Some solution
+ match solution with
+ | Some mi -> mi
+ | None -> fail()
let mkNamedType (tc:Type,tyargs) =
match tyargs with
@@ -933,13 +1033,50 @@ module Patterns =
let inst (tyargs:Type list) (i: Instantiable<'T>) = i (fun idx -> tyargs.[idx]) // Note, O(n) looks, but #tyargs is always small
+ let bindPropBySearchIfCandidateIsNull (ty : Type) propName retType argTypes candidate =
+ match candidate with
+ | null ->
+ let props =
+ ty.GetProperties(staticOrInstanceBindingFlags)
+ |> Array.filter (fun pi ->
+ let paramTypes = getTypesFromParamInfos (pi.GetIndexParameters())
+ pi.Name = propName &&
+ pi.PropertyType = retType &&
+ Array.length argTypes = paramTypes.Length &&
+ Array.forall2 (=) argTypes paramTypes
+ )
+ match props with
+ | [| pi |] -> pi
+ | _ -> null
+ | pi -> pi
+
+ let bindCtorBySearchIfCandidateIsNull (ty : Type) argTypes candidate =
+ match candidate with
+ | null ->
+ let ctors =
+ ty.GetConstructors(instanceBindingFlags)
+ |> Array.filter (fun ci ->
+ let paramTypes = getTypesFromParamInfos (ci.GetParameters())
+ Array.length argTypes = paramTypes.Length &&
+ Array.forall2 (=) argTypes paramTypes
+ )
+ match ctors with
+ | [| ctor |] -> ctor
+ | _ -> null
+ | ctor -> ctor
+
+
let bindProp (tc,propName,retType,argTypes,tyargs) =
// We search in the instantiated type, rather than searching the generic type.
let typ = mkNamedType(tc,tyargs)
let argtyps : Type list = argTypes |> inst tyargs
let retType : Type = retType |> inst tyargs |> removeVoid
#if FX_ATLEAST_PORTABLE
- typ.GetProperty(propName, retType, Array.ofList argtyps) |> checkNonNullResult ("propName", SR.GetString1(SR.QfailedToBindProperty, propName)) // fxcop may not see "propName" as an arg
+ try
+ typ.GetProperty(propName, staticOrInstanceBindingFlags)
+ with :? AmbiguousMatchException -> null // more than one property found with the specified name and matching binding constraints - return null to initiate manual search
+ |> bindPropBySearchIfCandidateIsNull typ propName retType (Array.ofList argtyps)
+ |> checkNonNullResult ("propName", SR.GetString1(SR.QfailedToBindProperty, propName)) // fxcop may not see "propName" as an arg
#else
typ.GetProperty(propName, staticOrInstanceBindingFlags, null, retType, Array.ofList argtyps, null) |> checkNonNullResult ("propName", SR.GetString1(SR.QfailedToBindProperty, propName)) // fxcop may not see "propName" as an arg
#endif
@@ -950,7 +1087,10 @@ module Patterns =
let bindGenericCtor (tc:Type,argTypes:Instantiable) =
let argtyps = instFormal (getGenericArguments tc) argTypes
#if FX_ATLEAST_PORTABLE
- tc.GetConstructor(Array.ofList argtyps) |> checkNonNullResult ("tc", SR.GetString(SR.QfailedToBindConstructor)) // fxcop may not see "tc" as an arg
+ let argTypes = Array.ofList argtyps
+ tc.GetConstructor(argTypes)
+ |> bindCtorBySearchIfCandidateIsNull tc argTypes
+ |> checkNonNullResult ("tc", SR.GetString(SR.QfailedToBindConstructor)) // fxcop may not see "tc" as an arg
#else
tc.GetConstructor(instanceBindingFlags,null,Array.ofList argtyps,null) |> checkNonNullResult ("tc", SR.GetString(SR.QfailedToBindConstructor)) // fxcop may not see "tc" as an arg
#endif
@@ -958,7 +1098,10 @@ module Patterns =
let typ = mkNamedType(tc,tyargs)
let argtyps = argTypes |> inst tyargs
#if FX_ATLEAST_PORTABLE
- typ.GetConstructor(Array.ofList argtyps) |> checkNonNullResult ("tc", SR.GetString(SR.QfailedToBindConstructor)) // fxcop may not see "tc" as an arg
+ let argTypes = Array.ofList argtyps
+ typ.GetConstructor(argTypes)
+ |> bindCtorBySearchIfCandidateIsNull typ argTypes
+ |> checkNonNullResult ("tc", SR.GetString(SR.QfailedToBindConstructor)) // fxcop may not see "tc" as an arg
#else
typ.GetConstructor(instanceBindingFlags,null,Array.ofList argtyps,null) |> checkNonNullResult ("tc", SR.GetString(SR.QfailedToBindConstructor)) // fxcop may not see "tc" as an arg
#endif
@@ -1114,7 +1257,11 @@ module Patterns =
if a = "" then mscorlib
elif a = "." then st.localAssembly
else
+#if FX_RESHAPED_REFLECTION
+ match System.Reflection.Assembly.Load(AssemblyName(a)) with
+#else
match System.Reflection.Assembly.Load(a) with
+#endif
| null -> raise <| System.InvalidOperationException(SR.GetString1(SR.QfailedToBindAssembly, a.ToString()))
| ass -> ass
@@ -1165,8 +1312,15 @@ module Patterns =
match tag with
| 0 -> u_tup3 u_constSpec u_dtypes (u_list u_Expr) st
|> (fun (a,b,args) (env:BindingEnv) ->
+ let args = List.map (fun e -> e env) args
+ let a =
+ match a with
+ | Unique v -> v
+ | Ambiguous f ->
+ let argTys = List.map typeOf args
+ f argTys
let tyargs = b env.typeInst
- E(CombTerm(a tyargs, List.map (fun e -> e env) args )))
+ E(CombTerm(a tyargs, args )))
| 1 -> let x = u_VarRef st
(fun env -> E(VarTerm (x env)))
| 2 -> let a = u_VarDecl st
@@ -1202,8 +1356,11 @@ module Patterns =
and u_ModuleDefn st =
let (ty,nm,isProp) = u_tup3 u_NamedType u_string u_bool st
- if isProp then StaticPropGetOp(bindModuleProperty(ty,nm))
- else StaticMethodCallOp(bindModuleFunction(ty,nm))
+ if isProp then Unique(StaticPropGetOp(bindModuleProperty(ty,nm)))
+ else
+ match bindModuleFunction(ty, nm) with
+ | Some mi -> Unique(StaticMethodCallOp(mi))
+ | None -> Ambiguous(fun argTypes tyargs -> StaticMethodCallOp(bindModuleFunctionWithCallSiteArgs(ty, nm, argTypes, tyargs)))
and u_MethodInfoData st =
u_tup5 u_NamedType (u_list u_dtype) u_dtype u_string u_int st
@@ -1219,8 +1376,9 @@ module Patterns =
match tag with
| 0 ->
match u_ModuleDefn st with
- | StaticMethodCallOp(minfo) -> (minfo :> MethodBase)
- | StaticPropGetOp(pinfo) -> (pinfo.GetGetMethod(true) :> MethodBase)
+ | Unique(StaticMethodCallOp(minfo)) -> (minfo :> MethodBase)
+ | Unique(StaticPropGetOp(pinfo)) -> (pinfo.GetGetMethod(true) :> MethodBase)
+ | Ambiguous(_) -> raise (System.Reflection.AmbiguousMatchException())
| _ -> failwith "unreachable"
| 1 ->
let data = u_MethodInfoData st
@@ -1235,61 +1393,68 @@ module Patterns =
and u_constSpec st =
let tag = u_byte_as_int st
- match tag with
- | 0 -> u_void st |> (fun () NoTyArgs -> IfThenElseOp)
- | 1 -> u_ModuleDefn st |> (fun op tyargs ->
- match op with
- | StaticMethodCallOp(minfo) -> StaticMethodCallOp(instMeth(minfo,tyargs))
- // OK to throw away the tyargs here since this only non-generic values in modules get represented by static properties
- | op -> op)
- | 2 -> u_void st |> (fun () NoTyArgs -> LetRecOp)
- | 3 -> u_NamedType st |> (fun x tyargs -> NewRecordOp (mkNamedType(x,tyargs)))
- | 4 -> u_RecdField st |> (fun prop tyargs -> InstancePropGetOp(prop tyargs))
- | 5 -> u_UnionCaseInfo st |> (fun unionCase tyargs -> NewUnionCaseOp(unionCase tyargs))
- | 6 -> u_UnionCaseField st |> (fun prop tyargs -> InstancePropGetOp(prop tyargs) )
- | 7 -> u_UnionCaseInfo st |> (fun unionCase tyargs -> UnionCaseTestOp(unionCase tyargs))
- | 8 -> u_void st |> (fun () (OneTyArg(tyarg)) -> NewTupleOp tyarg)
- | 9 -> u_int st |> (fun x (OneTyArg(tyarg)) -> TupleGetOp (tyarg,x))
- // Note, these get type args because they may be the result of reading literal field constants
- | 11 -> u_bool st |> (fun x (OneTyArg(tyarg)) -> mkLiftedValueOpG (x, tyarg))
- | 12 -> u_string st |> (fun x (OneTyArg(tyarg)) -> mkLiftedValueOpG (x, tyarg))
- | 13 -> u_float32 st |> (fun x (OneTyArg(tyarg)) -> mkLiftedValueOpG (x, tyarg))
- | 14 -> u_double st |> (fun a (OneTyArg(tyarg)) -> mkLiftedValueOpG (a, tyarg))
- | 15 -> u_char st |> (fun a (OneTyArg(tyarg)) -> mkLiftedValueOpG (a, tyarg))
- | 16 -> u_sbyte st |> (fun a (OneTyArg(tyarg)) -> mkLiftedValueOpG (a, tyarg))
- | 17 -> u_byte st |> (fun a (OneTyArg(tyarg)) -> mkLiftedValueOpG (a, tyarg))
- | 18 -> u_int16 st |> (fun a (OneTyArg(tyarg)) -> mkLiftedValueOpG (a, tyarg))
- | 19 -> u_uint16 st |> (fun a (OneTyArg(tyarg)) -> mkLiftedValueOpG (a, tyarg))
- | 20 -> u_int32 st |> (fun a (OneTyArg(tyarg)) -> mkLiftedValueOpG (a, tyarg))
- | 21 -> u_uint32 st |> (fun a (OneTyArg(tyarg)) -> mkLiftedValueOpG (a, tyarg))
- | 22 -> u_int64 st |> (fun a (OneTyArg(tyarg)) -> mkLiftedValueOpG (a, tyarg))
- | 23 -> u_uint64 st |> (fun a (OneTyArg(tyarg)) -> mkLiftedValueOpG (a, tyarg))
- | 24 -> u_void st |> (fun () NoTyArgs -> mkLiftedValueOpG ((), typeof))
- | 25 -> u_PropInfoData st |> (fun (a,b,c,d) tyargs -> let pinfo = bindProp(a,b,c,d,tyargs) in if pinfoIsStatic pinfo then StaticPropGetOp(pinfo) else InstancePropGetOp(pinfo))
- | 26 -> u_CtorInfoData st |> (fun (a,b) tyargs -> NewObjectOp (bindCtor(a,b,tyargs)))
- | 28 -> u_void st |> (fun () (OneTyArg(ty)) -> CoerceOp ty)
- | 29 -> u_void st |> (fun () NoTyArgs -> SequentialOp)
- | 30 -> u_void st |> (fun () NoTyArgs -> ForIntegerRangeLoopOp)
- | 31 -> u_MethodInfoData st |> (fun p tyargs -> let minfo = bindMeth(p,tyargs) in if minfo.IsStatic then StaticMethodCallOp(minfo) else InstanceMethodCallOp(minfo))
- | 32 -> u_void st |> (fun () (OneTyArg(ty)) -> NewArrayOp ty)
- | 33 -> u_void st |> (fun () (OneTyArg(ty)) -> NewDelegateOp ty)
- | 34 -> u_void st |> (fun () NoTyArgs -> WhileLoopOp)
- | 35 -> u_void st |> (fun () NoTyArgs -> LetOp)
- | 36 -> u_RecdField st |> (fun prop tyargs -> InstancePropSetOp(prop tyargs))
- | 37 -> u_tup2 u_NamedType u_string st |> (fun (a,b) tyargs -> let finfo = bindField(a,b,tyargs) in if finfo.IsStatic then StaticFieldGetOp(finfo) else InstanceFieldGetOp(finfo))
- | 38 -> u_void st |> (fun () NoTyArgs -> LetRecCombOp)
- | 39 -> u_void st |> (fun () NoTyArgs -> AppOp)
- | 40 -> u_void st |> (fun () (OneTyArg(ty)) -> ValueOp(null,ty))
- | 41 -> u_void st |> (fun () (OneTyArg(ty)) -> DefaultValueOp(ty))
- | 42 -> u_PropInfoData st |> (fun (a,b,c,d) tyargs -> let pinfo = bindProp(a,b,c,d,tyargs) in if pinfoIsStatic pinfo then StaticPropSetOp(pinfo) else InstancePropSetOp(pinfo))
- | 43 -> u_tup2 u_NamedType u_string st |> (fun (a,b) tyargs -> let finfo = bindField(a,b,tyargs) in if finfo.IsStatic then StaticFieldSetOp(finfo) else InstanceFieldSetOp(finfo))
- | 44 -> u_void st |> (fun () NoTyArgs -> AddressOfOp)
- | 45 -> u_void st |> (fun () NoTyArgs -> AddressSetOp)
- | 46 -> u_void st |> (fun () (OneTyArg(ty)) -> TypeTestOp(ty))
- | 47 -> u_void st |> (fun () NoTyArgs -> TryFinallyOp)
- | 48 -> u_void st |> (fun () NoTyArgs -> TryWithOp)
- | 49 -> u_void st |> (fun () NoTyArgs -> VarSetOp)
- | _ -> failwithf "u_constSpec, unrecognized tag %d" tag
+ if tag = 1 then
+ let bindModuleDefn r tyargs =
+ match r with
+ | StaticMethodCallOp(minfo) -> StaticMethodCallOp(instMeth(minfo,tyargs))
+ // OK to throw away the tyargs here since this only non-generic values in modules get represented by static properties
+ | x -> x
+ match u_ModuleDefn st with
+ | Unique(r) -> Unique(bindModuleDefn r)
+ | Ambiguous(f) -> Ambiguous(fun argTypes tyargs -> bindModuleDefn (f argTypes tyargs) tyargs)
+ else
+ let constSpec =
+ match tag with
+ | 0 -> u_void st |> (fun () NoTyArgs -> IfThenElseOp)
+ | 2 -> u_void st |> (fun () NoTyArgs -> LetRecOp)
+ | 3 -> u_NamedType st |> (fun x tyargs -> NewRecordOp (mkNamedType(x,tyargs)))
+ | 4 -> u_RecdField st |> (fun prop tyargs -> InstancePropGetOp(prop tyargs))
+ | 5 -> u_UnionCaseInfo st |> (fun unionCase tyargs -> NewUnionCaseOp(unionCase tyargs))
+ | 6 -> u_UnionCaseField st |> (fun prop tyargs -> InstancePropGetOp(prop tyargs) )
+ | 7 -> u_UnionCaseInfo st |> (fun unionCase tyargs -> UnionCaseTestOp(unionCase tyargs))
+ | 8 -> u_void st |> (fun () (OneTyArg(tyarg)) -> NewTupleOp tyarg)
+ | 9 -> u_int st |> (fun x (OneTyArg(tyarg)) -> TupleGetOp (tyarg,x))
+ // Note, these get type args because they may be the result of reading literal field constants
+ | 11 -> u_bool st |> (fun x (OneTyArg(tyarg)) -> mkLiftedValueOpG (x, tyarg))
+ | 12 -> u_string st |> (fun x (OneTyArg(tyarg)) -> mkLiftedValueOpG (x, tyarg))
+ | 13 -> u_float32 st |> (fun x (OneTyArg(tyarg)) -> mkLiftedValueOpG (x, tyarg))
+ | 14 -> u_double st |> (fun a (OneTyArg(tyarg)) -> mkLiftedValueOpG (a, tyarg))
+ | 15 -> u_char st |> (fun a (OneTyArg(tyarg)) -> mkLiftedValueOpG (a, tyarg))
+ | 16 -> u_sbyte st |> (fun a (OneTyArg(tyarg)) -> mkLiftedValueOpG (a, tyarg))
+ | 17 -> u_byte st |> (fun a (OneTyArg(tyarg)) -> mkLiftedValueOpG (a, tyarg))
+ | 18 -> u_int16 st |> (fun a (OneTyArg(tyarg)) -> mkLiftedValueOpG (a, tyarg))
+ | 19 -> u_uint16 st |> (fun a (OneTyArg(tyarg)) -> mkLiftedValueOpG (a, tyarg))
+ | 20 -> u_int32 st |> (fun a (OneTyArg(tyarg)) -> mkLiftedValueOpG (a, tyarg))
+ | 21 -> u_uint32 st |> (fun a (OneTyArg(tyarg)) -> mkLiftedValueOpG (a, tyarg))
+ | 22 -> u_int64 st |> (fun a (OneTyArg(tyarg)) -> mkLiftedValueOpG (a, tyarg))
+ | 23 -> u_uint64 st |> (fun a (OneTyArg(tyarg)) -> mkLiftedValueOpG (a, tyarg))
+ | 24 -> u_void st |> (fun () NoTyArgs -> mkLiftedValueOpG ((), typeof))
+ | 25 -> u_PropInfoData st |> (fun (a,b,c,d) tyargs -> let pinfo = bindProp(a,b,c,d,tyargs) in if pinfoIsStatic pinfo then StaticPropGetOp(pinfo) else InstancePropGetOp(pinfo))
+ | 26 -> u_CtorInfoData st |> (fun (a,b) tyargs -> NewObjectOp (bindCtor(a,b,tyargs)))
+ | 28 -> u_void st |> (fun () (OneTyArg(ty)) -> CoerceOp ty)
+ | 29 -> u_void st |> (fun () NoTyArgs -> SequentialOp)
+ | 30 -> u_void st |> (fun () NoTyArgs -> ForIntegerRangeLoopOp)
+ | 31 -> u_MethodInfoData st |> (fun p tyargs -> let minfo = bindMeth(p,tyargs) in if minfo.IsStatic then StaticMethodCallOp(minfo) else InstanceMethodCallOp(minfo))
+ | 32 -> u_void st |> (fun () (OneTyArg(ty)) -> NewArrayOp ty)
+ | 33 -> u_void st |> (fun () (OneTyArg(ty)) -> NewDelegateOp ty)
+ | 34 -> u_void st |> (fun () NoTyArgs -> WhileLoopOp)
+ | 35 -> u_void st |> (fun () NoTyArgs -> LetOp)
+ | 36 -> u_RecdField st |> (fun prop tyargs -> InstancePropSetOp(prop tyargs))
+ | 37 -> u_tup2 u_NamedType u_string st |> (fun (a,b) tyargs -> let finfo = bindField(a,b,tyargs) in if finfo.IsStatic then StaticFieldGetOp(finfo) else InstanceFieldGetOp(finfo))
+ | 38 -> u_void st |> (fun () NoTyArgs -> LetRecCombOp)
+ | 39 -> u_void st |> (fun () NoTyArgs -> AppOp)
+ | 40 -> u_void st |> (fun () (OneTyArg(ty)) -> ValueOp(null,ty))
+ | 41 -> u_void st |> (fun () (OneTyArg(ty)) -> DefaultValueOp(ty))
+ | 42 -> u_PropInfoData st |> (fun (a,b,c,d) tyargs -> let pinfo = bindProp(a,b,c,d,tyargs) in if pinfoIsStatic pinfo then StaticPropSetOp(pinfo) else InstancePropSetOp(pinfo))
+ | 43 -> u_tup2 u_NamedType u_string st |> (fun (a,b) tyargs -> let finfo = bindField(a,b,tyargs) in if finfo.IsStatic then StaticFieldSetOp(finfo) else InstanceFieldSetOp(finfo))
+ | 44 -> u_void st |> (fun () NoTyArgs -> AddressOfOp)
+ | 45 -> u_void st |> (fun () NoTyArgs -> AddressSetOp)
+ | 46 -> u_void st |> (fun () (OneTyArg(ty)) -> TypeTestOp(ty))
+ | 47 -> u_void st |> (fun () NoTyArgs -> TryFinallyOp)
+ | 48 -> u_void st |> (fun () NoTyArgs -> TryWithOp)
+ | 49 -> u_void st |> (fun () NoTyArgs -> VarSetOp)
+ | _ -> failwithf "u_constSpec, unrecognized tag %d" tag
+ Unique constSpec
let u_ReflectedDefinition = u_tup2 u_MethodBase u_Expr
let u_ReflectedDefinitions = u_list u_ReflectedDefinition
@@ -1396,17 +1561,117 @@ module Patterns =
#if FX_NO_REFLECTION_METADATA_TOKENS // not available on Compact Framework
[]
type ReflectedDefinitionTableKey =
- | Key of System.Type * int * System.Type[]
+ // Key is declaring type * type parameters count * name * parameter types * return type
+ // Registered reflected definitions can contain generic methods or constructors in generic types,
+ // however TryGetReflectedDefinition can be queried with concrete instantiations of the same methods that doesnt contain type parameters.
+ // To make these two cases match we apply the following transformations:
+ // 1. if declaring type is generic - key will contain generic type definition, otherwise - type itself
+ // 2. if method is instantiation of generic one - pick parameters from generic method definition, otherwise - from methods itself
+ // 3 if method is constructor and declaring type is generic then we'll use the following trick to treat C<'a>() and C() as the same type
+ // - we resolve method handle of the constructor using generic type definition - as a result for constructor from instantiated type we obtain matching constructor in generic type definition
+ | Key of System.Type * int * string * System.Type[] * System.Type
static member GetKey(methodBase:MethodBase) =
-#if FX_NO_REFLECTION_MODULES
- Key(methodBase.DeclaringType,
- (if methodBase.IsGenericMethod then methodBase.GetGenericArguments().Length else 0),
- methodBase.GetParameters() |> Array.map (fun p -> p.ParameterType))
+ let isGenericType = methodBase.DeclaringType.IsGenericType
+ let declaringType =
+ if isGenericType then
+ methodBase.DeclaringType.GetGenericTypeDefinition()
+ else methodBase.DeclaringType
+ let tyArgsCount =
+ if methodBase.IsGenericMethod then
+ methodBase.GetGenericArguments().Length
+ else 0
+#if FX_RESHAPED_REFLECTION
+ // this is very unfortunate consequence of limited Reflection capabilities on .NETCore
+ // what we want: having MethodBase for some concrete method or constructor we would like to locate corresponding MethodInfo\ConstructorInfo from the open generic type (cannonical form).
+ // It is necessary to build the key for the table of reflected definitions: reflection definition is saved for open generic type but user may request it using
+ // arbitrary instantiation.
+ let findMethodInOpenGenericType (mb : ('T :> MethodBase)) : 'T =
+ let candidates =
+ let bindingFlags =
+ (if mb.IsPublic then BindingFlags.Public else BindingFlags.NonPublic) |||
+ (if mb.IsStatic then BindingFlags.Static else BindingFlags.Instance)
+ let candidates : MethodBase[] =
+ downcast (
+ if mb.IsConstructor then
+ box (declaringType.GetConstructors(bindingFlags))
+ else
+ box (declaringType.GetMethods(bindingFlags))
+ )
+ candidates |> Array.filter (fun c ->
+ c.Name = mb.Name &&
+ (c.GetParameters().Length) = (mb.GetParameters().Length) &&
+ (c.IsGenericMethod = mb.IsGenericMethod) &&
+ (if c.IsGenericMethod then c.GetGenericArguments().Length = mb.GetGenericArguments().Length else true)
+ )
+ let solution =
+ if candidates.Length = 0 then failwith "Unexpected, failed to locate matching method"
+ elif candidates.Length = 1 then candidates.[0]
+ else
+ // here we definitely know that candidates
+ // a. has matching name
+ // b. has the same number of arguments
+ // c. has the same number of type parameters if any
+
+ let originalParameters = mb.GetParameters()
+ let originalTypeArguments = mb.DeclaringType.GetGenericArguments()
+ let EXACT_MATCHING_COST = 2
+ let GENERIC_TYPE_MATCHING_COST = 1
+
+ // loops through the parameters and computes the rate of the current candidate.
+ // having the argument:
+ // - rate is increased on EXACT_MATCHING_COST if type of argument that candidate has at position i exactly matched the type of argument for the original method.
+ // - rate is increased on GENERIC_TYPE_MATCHING_COST if candidate has generic argument at given position and its type matched the type of argument for the original method.
+ // - otherwise rate will be 0
+ let evaluateCandidate (mb : MethodBase) : int =
+ let parameters = mb.GetParameters()
+ let rec loop i resultSoFar =
+ if i >= parameters.Length then resultSoFar
+ else
+ let p = parameters.[i]
+ let orig = originalParameters.[i]
+ if p.ParameterType = orig.ParameterType then loop (i + 1) (resultSoFar + EXACT_MATCHING_COST) // exact matching
+ elif p.ParameterType.IsGenericParameter && p.ParameterType.DeclaringType = mb.DeclaringType then
+ let pos = p.ParameterType.GenericParameterPosition
+ if originalTypeArguments.[pos] = orig.ParameterType then loop (i + 1) (resultSoFar + GENERIC_TYPE_MATCHING_COST)
+ else 0
+ else
+ 0
+
+ loop 0 0
+
+ Array.maxBy evaluateCandidate candidates
+
+ solution :?> 'T
+#endif
+ match methodBase with
+ | :? MethodInfo as mi ->
+ let mi =
+ if mi.IsGenericMethod then
+ let mi = mi.GetGenericMethodDefinition()
+ if isGenericType then
+#if FX_RESHAPED_REFLECTION
+ findMethodInOpenGenericType mi
#else
- Key(methodBase.DeclaringType.Module.ModuleHandle,
- (if methodBase.IsGenericMethod then methodBase.GetGenericArguments().Length else 0),
- methodBase.GetParameters() |> Array.map (fun p -> p.Type))
-#endif
+ MethodBase.GetMethodFromHandle(mi.MethodHandle, declaringType.TypeHandle) :?> MethodInfo
+#endif
+ else
+ mi
+ else mi
+ let paramTypes = mi.GetParameters() |> getTypesFromParamInfos
+ Key(declaringType, tyArgsCount, methodBase.Name, paramTypes, mi.ReturnType)
+ | :? ConstructorInfo as ci ->
+ let mi =
+ if isGenericType then
+#if FX_RESHAPED_REFLECTION
+ findMethodInOpenGenericType ci
+#else
+ MethodBase.GetMethodFromHandle(ci. MethodHandle, declaringType.TypeHandle) :?> ConstructorInfo // convert ctor with concrete args to ctor with generic args
+#endif
+ else
+ ci
+ let paramTypes = mi.GetParameters() |> getTypesFromParamInfos
+ Key(declaringType, tyArgsCount, methodBase.Name, paramTypes, declaringType)
+ | _ -> failwith "Unexpected MethodBase type, %A" (methodBase.GetType()) // per MSDN ConstructorInfo and MethodInfo are the only derived types from MethodBase
#else
[]
type ReflectedDefinitionTableKey =
@@ -1847,4 +2112,4 @@ module ExprShape =
| HoleTerm _ -> invalidArg "expr" (SR.GetString(SR.QunexpectedHole))
loop (e :> Expr)
-#endif
\ No newline at end of file
+#endif
diff --git a/src/fsharp/FSharp.Core/reflect.fs b/src/fsharp/FSharp.Core/reflect.fs
index 406ffe2268..6a160ed5b2 100755
--- a/src/fsharp/FSharp.Core/reflect.fs
+++ b/src/fsharp/FSharp.Core/reflect.fs
@@ -12,8 +12,222 @@
// Reflection on F# values. Analyze an object to see if it the representation
// of an F# value.
+#if FX_RESHAPED_REFLECTION
+
+namespace Microsoft.FSharp.Core
+
+open System
+open System.Reflection
+
+open Microsoft.FSharp.Core
+open Microsoft.FSharp.Core.Operators
+open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators
+open Microsoft.FSharp.Collections
+open Microsoft.FSharp.Primitives.Basics
+
+module ReflectionAdapters =
+
+ []
+ type BindingFlags =
+ | DeclaredOnly = 2
+ | Instance = 4
+ | Static = 8
+ | Public = 16
+ | NonPublic = 32
+ let inline hasFlag (flag : BindingFlags) f = (f &&& flag) = flag
+ let isDeclaredFlag f = hasFlag BindingFlags.DeclaredOnly f
+ let isPublicFlag f = hasFlag BindingFlags.Public f
+ let isStaticFlag f = hasFlag BindingFlags.Static f
+ let isInstanceFlag f = hasFlag BindingFlags.Instance f
+ let isNonPublicFlag f = hasFlag BindingFlags.NonPublic f
+
+ []
+ type TypeCode =
+ | Int32 = 0
+ | Int64 = 1
+ | Byte = 2
+ | SByte = 3
+ | Int16 = 4
+ | UInt16 = 5
+ | UInt32 = 6
+ | UInt64 = 7
+ | Single = 8
+ | Double = 9
+ | Decimal = 10
+ | Other = 11
+
+ let isAcceptable bindingFlags isStatic isPublic =
+ // 1. check if member kind (static\instance) was specified in flags
+ ((isStaticFlag bindingFlags && isStatic) || (isInstanceFlag bindingFlags && not isStatic)) &&
+ // 2. check if member accessibility was specified in flags
+ ((isPublicFlag bindingFlags && isPublic) || (isNonPublicFlag bindingFlags && not isPublic))
+
+ let publicFlags = BindingFlags.Public ||| BindingFlags.Instance ||| BindingFlags.Static
+
+ let commit (results : _[]) =
+ match results with
+ | [||] -> null
+ | [| m |] -> m
+ | _ -> raise (AmbiguousMatchException())
+
+ let canUseAccessor (accessor : MethodInfo) nonPublic =
+ box accessor <> null && (accessor.IsPublic || nonPublic)
+
+ open PrimReflectionAdapters
+
+ type System.Type with
+ member this.GetNestedType (name, bindingFlags) =
+ // MSDN: http://msdn.microsoft.com/en-us/library/0dcb3ad5.aspx
+ // The following BindingFlags filter flags can be used to define which nested types to include in the search:
+ // You must specify either BindingFlags.Public or BindingFlags.NonPublic to get a return.
+ // Specify BindingFlags.Public to include public nested types in the search.
+ // Specify BindingFlags.NonPublic to include non-public nested types (that is, private, internal, and protected nested types) in the search.
+ // This method returns only the nested types of the current type. It does not search the base classes of the current type.
+ // To find types that are nested in base classes, you must walk the inheritance hierarchy, calling GetNestedType at each level.
+ let nestedTyOpt =
+ this.GetTypeInfo().DeclaredNestedTypes
+ |> Seq.tryFind (fun nestedTy ->
+ nestedTy.Name = name && (
+ (isPublicFlag bindingFlags && nestedTy.IsNestedPublic) ||
+ (isNonPublicFlag bindingFlags && (nestedTy.IsNestedPrivate || nestedTy.IsNestedFamily || nestedTy.IsNestedAssembly || nestedTy.IsNestedFamORAssem || nestedTy.IsNestedFamANDAssem))
+ )
+ )
+ |> Option.map (fun ti -> ti.AsType())
+ defaultArg nestedTyOpt null
+ // use different sources based on Declared flag
+ member this.GetMethods(bindingFlags) =
+ (if isDeclaredFlag bindingFlags then this.GetTypeInfo().DeclaredMethods else this.GetRuntimeMethods())
+ |> Seq.filter (fun m -> isAcceptable bindingFlags m.IsStatic m.IsPublic)
+ |> Seq.toArray
+ // use different sources based on Declared flag
+ member this.GetFields(bindingFlags) =
+ (if isDeclaredFlag bindingFlags then this.GetTypeInfo().DeclaredFields else this.GetRuntimeFields())
+ |> Seq.filter (fun f -> isAcceptable bindingFlags f.IsStatic f.IsPublic)
+ |> Seq.toArray
+ // use different sources based on Declared flag
+ member this.GetProperties(?bindingFlags) =
+ let bindingFlags = defaultArg bindingFlags publicFlags
+ (if isDeclaredFlag bindingFlags then this.GetTypeInfo().DeclaredProperties else this.GetRuntimeProperties())
+ |> Seq.filter (fun pi->
+ let mi = if pi.GetMethod <> null then pi.GetMethod else pi.SetMethod
+ assert (mi <> null)
+ isAcceptable bindingFlags mi.IsStatic mi.IsPublic
+ )
+ |> Seq.toArray
+ // use different sources based on Declared flag
+ member this.GetMethod(name, ?bindingFlags) =
+ let bindingFlags = defaultArg bindingFlags publicFlags
+ this.GetMethods(bindingFlags)
+ |> Array.filter(fun m -> m.Name = name)
+ |> commit
+ // use different sources based on Declared flag
+ member this.GetProperty(name, bindingFlags) =
+ this.GetProperties(bindingFlags)
+ |> Array.filter (fun pi -> pi.Name = name)
+ |> commit
+ member this.IsGenericTypeDefinition = this.GetTypeInfo().IsGenericTypeDefinition
+ member this.GetGenericArguments() =
+ if this.IsGenericTypeDefinition then this.GetTypeInfo().GenericTypeParameters
+ elif this.IsGenericType then this.GenericTypeArguments
+ else [||]
+ member this.BaseType = this.GetTypeInfo().BaseType
+ member this.GetConstructor(parameterTypes : Type[]) =
+ this.GetTypeInfo().DeclaredConstructors
+ |> Seq.filter (fun ci ->
+ let parameters = ci.GetParameters()
+ (parameters.Length = parameterTypes.Length) &&
+ (parameterTypes, parameters) ||> Array.forall2 (fun ty pi -> pi.ParameterType.Equals ty)
+ )
+ |> Seq.toArray
+ |> commit
+ // MSDN: returns an array of Type objects representing all the interfaces implemented or inherited by the current Type.
+ member this.GetInterfaces() = this.GetTypeInfo().ImplementedInterfaces |> Seq.toArray
+ member this.GetConstructors(?bindingFlags) =
+ let bindingFlags = defaultArg bindingFlags publicFlags
+ // type initializer will also be included in resultset
+ this.GetTypeInfo().DeclaredConstructors
+ |> Seq.filter (fun ci -> isAcceptable bindingFlags ci.IsStatic ci.IsPublic)
+ |> Seq.toArray
+ member this.GetMethods() = this.GetMethods(publicFlags)
+ member this.Assembly = this.GetTypeInfo().Assembly
+ member this.IsSubclassOf(otherTy : Type) = this.GetTypeInfo().IsSubclassOf(otherTy)
+ member this.IsEnum = this.GetTypeInfo().IsEnum;
+ member this.GetField(name, bindingFlags) =
+ this.GetFields(bindingFlags)
+ |> Array.filter (fun fi -> fi.Name = name)
+ |> commit
+ member this.GetProperty(name, propertyType, parameterTypes : Type[]) =
+ this.GetProperties()
+ |> Array.filter (fun pi ->
+ pi.Name = name &&
+ pi.PropertyType = propertyType &&
+ (
+ let parameters = pi.GetIndexParameters()
+ (parameters.Length = parameterTypes.Length) &&
+ (parameterTypes, parameters) ||> Array.forall2 (fun ty pi -> pi.ParameterType.Equals ty)
+ )
+ )
+ |> commit
+ static member GetTypeCode(ty : Type) =
+ if typeof.Equals ty then TypeCode.Int32
+ elif typeof.Equals ty then TypeCode.Int64
+ elif typeof.Equals ty then TypeCode.Byte
+ elif ty = typeof then TypeCode.SByte
+ elif ty = typeof then TypeCode.Int16
+ elif ty = typeof then TypeCode.UInt16
+ elif ty = typeof then TypeCode.UInt32
+ elif ty = typeof then TypeCode.UInt64
+ elif ty = typeof then TypeCode.Single
+ elif ty = typeof then TypeCode.Double
+ elif ty = typeof then TypeCode.Decimal
+ else TypeCode.Other
+
+ type System.Reflection.MemberInfo with
+ member this.GetCustomAttributes(attrTy, inherits) : obj[] = downcast box(CustomAttributeExtensions.GetCustomAttributes(this, attrTy, inherits) |> Seq.toArray)
+
+ type System.Reflection.MethodInfo with
+ member this.GetCustomAttributes(inherits : bool) : obj[] = downcast box(CustomAttributeExtensions.GetCustomAttributes(this, inherits) |> Seq.toArray)
+
+ type System.Reflection.PropertyInfo with
+ member this.GetGetMethod(nonPublic) =
+ let mi = this.GetMethod
+ if canUseAccessor mi nonPublic then mi
+ else null
+ member this.GetSetMethod(nonPublic) =
+ let mi = this.SetMethod
+ if canUseAccessor mi nonPublic then mi
+ else null
+
+ type System.Reflection.Assembly with
+ member this.GetTypes() =
+ this.DefinedTypes
+ |> Seq.map (fun ti -> ti.AsType())
+ |> Seq.toArray
+
+ type System.Delegate with
+ static member CreateDelegate(delegateType, methodInfo : MethodInfo) = methodInfo.CreateDelegate(delegateType)
+ static member CreateDelegate(delegateType, obj : obj, methodInfo : MethodInfo) = methodInfo.CreateDelegate(delegateType, obj)
+
+#endif
+
namespace Microsoft.FSharp.Reflection
+module internal ReflectionUtils =
+
+ open Microsoft.FSharp.Core.Operators
+
+#if FX_RESHAPED_REFLECTION
+ type BindingFlags = Microsoft.FSharp.Core.ReflectionAdapters.BindingFlags
+#else
+ type BindingFlags = System.Reflection.BindingFlags
+#endif
+
+ let toBindingFlags allowAccessToNonPublicMembers =
+ if allowAccessToNonPublicMembers then
+ BindingFlags.NonPublic ||| BindingFlags.Public
+ else
+ BindingFlags.Public
+
open System
open System.Globalization
open System.Reflection
@@ -27,10 +241,20 @@ module internal Impl =
let debug = false
+#if FX_RESHAPED_REFLECTION
+
+ open PrimReflectionAdapters
+ open ReflectionAdapters
+
+#endif
+
+ let getBindingFlags allowAccess = ReflectionUtils.toBindingFlags (defaultArg allowAccess false)
+
let inline checkNonNull argName (v: 'T) =
match box v with
| null -> nullArg argName
| _ -> ()
+
let emptyArray arr = (Array.length arr = 0)
let nonEmptyArray arr = Array.length arr > 0
@@ -53,7 +277,6 @@ module internal Impl =
//-----------------------------------------------------------------
// GENERAL UTILITIES
-
#if FX_ATLEAST_PORTABLE
let instancePropertyFlags = BindingFlags.Instance
let staticPropertyFlags = BindingFlags.Static
@@ -80,7 +303,6 @@ module internal Impl =
//-----------------------------------------------------------------
// ATTRIBUTE DECOMPILATION
-
let tryFindCompilationMappingAttribute (attrs:obj[]) =
match attrs with
| null | [| |] -> None
@@ -93,9 +315,9 @@ module internal Impl =
| Some a -> a
#if FX_NO_CUSTOMATTRIBUTEDATA
- let tryFindCompilationMappingAttributeFromType (typ:Type) = tryFindCompilationMappingAttribute ( typ.GetCustomAttributes (typeof,false))
- let tryFindCompilationMappingAttributeFromMemberInfo (info:MemberInfo) = tryFindCompilationMappingAttribute (info.GetCustomAttributes (typeof,false))
- let findCompilationMappingAttributeFromMemberInfo (info:MemberInfo) = findCompilationMappingAttribute (info.GetCustomAttributes (typeof,false))
+ let tryFindCompilationMappingAttributeFromType (typ:Type) = tryFindCompilationMappingAttribute ( typ.GetCustomAttributes(typeof, false))
+ let tryFindCompilationMappingAttributeFromMemberInfo (info:MemberInfo) = tryFindCompilationMappingAttribute (info.GetCustomAttributes(typeof, false))
+ let findCompilationMappingAttributeFromMemberInfo (info:MemberInfo) = findCompilationMappingAttribute (info.GetCustomAttributes(typeof, false))
#else
let cmaName = typeof.FullName
let assemblyName = typeof.Assembly.GetName().Name
@@ -165,8 +387,7 @@ module internal Impl =
| Some (flags,_n,_vn) -> Some flags
//-----------------------------------------------------------------
- // UNION DECOMPILATION
-
+ // UNION DECOMPILATION
// Get the type where the type definitions are stored
let getUnionCasesTyp (typ: Type, _bindingFlags) =
@@ -211,7 +432,20 @@ module internal Impl =
let tagField = tagFields |> Array.pick (fun (i,f) -> if i = tag then Some f else None)
if tagFields.Length = 1 then
typ
- else
+ else
+ // special case: two-cased DU annotated with CompilationRepresentation(UseNullAsTrueValue)
+ // in this case it will be compiled as one class: return self type for non-nullary case and null for nullary
+ let isTwoCasedDU =
+ if tagFields.Length = 2 then
+ match typ.GetCustomAttributes(typeof, false) with
+ | [|:? CompilationRepresentationAttribute as attr|] ->
+ (attr.Flags &&& CompilationRepresentationFlags.UseNullAsTrueValue) = CompilationRepresentationFlags.UseNullAsTrueValue
+ | _ -> false
+ else
+ false
+ if isTwoCasedDU then
+ typ
+ else
let casesTyp = getUnionCasesTyp (typ, bindingFlags)
let caseTyp = casesTyp.GetNestedType(tagField, bindingFlags) // if this is null then the union is nullary
match caseTyp with
@@ -617,12 +851,17 @@ module internal Impl =
let checkTupleType(argName,tupleType) =
checkNonNull argName tupleType;
if not (isTupleType tupleType) then invalidArg argName (SR.GetString1(SR.notATupleType, tupleType.FullName))
+
+#if FX_RESHAPED_REFLECTION
+open ReflectionAdapters
+type BindingFlags = ReflectionAdapters.BindingFlags
+#endif
[]
type UnionCaseInfo(typ: System.Type, tag:int) =
// Cache the tag -> name map
let mutable names = None
- let getMethInfo() = Impl.getUnionCaseConstructorMethod (typ,tag,BindingFlags.Public ||| BindingFlags.NonPublic)
+ let getMethInfo() = Impl.getUnionCaseConstructorMethod (typ, tag, BindingFlags.Public ||| BindingFlags.NonPublic)
member x.Name =
match names with
| None -> (let conv = Impl.getUnionTagConverter (typ,BindingFlags.Public ||| BindingFlags.NonPublic) in names <- Some conv; conv tag)
@@ -660,13 +899,14 @@ type FSharpType =
static member IsRecord(typ:Type,?bindingFlags) =
let bindingFlags = defaultArg bindingFlags BindingFlags.Public
+
Impl.checkNonNull "typ" typ;
Impl.isRecordType (typ,bindingFlags)
static member IsUnion(typ:Type,?bindingFlags) =
+ let bindingFlags = defaultArg bindingFlags BindingFlags.Public
Impl.checkNonNull "typ" typ;
let typ = Impl.getTypeOfReprType (typ ,BindingFlags.Public ||| BindingFlags.NonPublic)
- let bindingFlags = defaultArg bindingFlags BindingFlags.Public
Impl.isUnionType (typ,bindingFlags)
static member IsFunction(typ:Type) =
@@ -701,7 +941,7 @@ type FSharpType =
static member GetRecordFields(recordType:Type,?bindingFlags) =
let bindingFlags = defaultArg bindingFlags BindingFlags.Public
Impl.checkRecordType("recordType",recordType,bindingFlags);
- Impl.fieldPropsOfRecordType(recordType,bindingFlags)
+ Impl.fieldPropsOfRecordType(recordType,bindingFlags)
static member GetUnionCases (unionType:Type,?bindingFlags) =
let bindingFlags = defaultArg bindingFlags BindingFlags.Public
@@ -711,7 +951,7 @@ type FSharpType =
Impl.getUnionTypeTagNameMap(unionType,bindingFlags) |> Array.mapi (fun i _ -> UnionCaseInfo(unionType,i))
static member IsExceptionRepresentation(exceptionType:Type, ?bindingFlags) =
- let bindingFlags = defaultArg bindingFlags BindingFlags.Public
+ let bindingFlags = defaultArg bindingFlags BindingFlags.Public
Impl.checkNonNull "exceptionType" exceptionType;
Impl.isExceptionRepr(exceptionType,bindingFlags)
@@ -742,8 +982,8 @@ type FSharpValue =
info.GetValue(record,null)
static member GetRecordFields(record:obj,?bindingFlags) =
- Impl.checkNonNull "record" record;
let bindingFlags = defaultArg bindingFlags BindingFlags.Public
+ Impl.checkNonNull "record" record;
let typ = record.GetType()
if not (Impl.isRecordType(typ,bindingFlags)) then invalidArg "record" (SR.GetString(SR.objIsNotARecord));
Impl.getRecordReader (typ,bindingFlags) record
@@ -814,21 +1054,22 @@ type FSharpValue =
Impl.getTupleConstructorInfo (tupleType)
static member MakeUnion(unionCase:UnionCaseInfo,args: obj [],?bindingFlags) =
+ let bindingFlags = defaultArg bindingFlags BindingFlags.Public
Impl.checkNonNull "unionCase" unionCase;
- let bindingFlags = defaultArg bindingFlags BindingFlags.Public
Impl.getUnionCaseConstructor (unionCase.DeclaringType,unionCase.Tag,bindingFlags) args
static member PreComputeUnionConstructor (unionCase:UnionCaseInfo,?bindingFlags) =
- Impl.checkNonNull "unionCase" unionCase;
let bindingFlags = defaultArg bindingFlags BindingFlags.Public
+ Impl.checkNonNull "unionCase" unionCase;
Impl.getUnionCaseConstructor (unionCase.DeclaringType,unionCase.Tag,bindingFlags)
static member PreComputeUnionConstructorInfo(unionCase:UnionCaseInfo, ?bindingFlags) =
- Impl.checkNonNull "unionCase" unionCase;
let bindingFlags = defaultArg bindingFlags BindingFlags.Public
- Impl.getUnionCaseConstructorMethod (unionCase.DeclaringType,unionCase.Tag,bindingFlags)
+ Impl.checkNonNull "unionCase" unionCase;
+ Impl.getUnionCaseConstructorMethod (unionCase.DeclaringType,unionCase.Tag,bindingFlags)
static member GetUnionFields(obj:obj,unionType:Type,?bindingFlags) =
+ let bindingFlags = defaultArg bindingFlags BindingFlags.Public
let ensureType (typ:Type,obj:obj) =
match typ with
| null ->
@@ -837,7 +1078,6 @@ type FSharpValue =
| _ -> obj.GetType()
| _ -> typ
//System.Console.WriteLine("typ1 = {0}",box unionType)
- let bindingFlags = defaultArg bindingFlags BindingFlags.Public
let unionType = ensureType(unionType,obj)
//System.Console.WriteLine("typ2 = {0}",box unionType)
Impl.checkNonNull "unionType" unionType;
@@ -847,7 +1087,7 @@ type FSharpValue =
let tag = Impl.getUnionTagReader (unionType,bindingFlags) obj
let flds = Impl.getUnionCaseRecordReader (unionType,tag,bindingFlags) obj
UnionCaseInfo(unionType,tag), flds
-
+
static member PreComputeUnionTagReader(unionType: Type,?bindingFlags) : (obj -> int) =
let bindingFlags = defaultArg bindingFlags BindingFlags.Public
Impl.checkNonNull "unionType" unionType;
@@ -855,6 +1095,7 @@ type FSharpValue =
Impl.checkUnionType(unionType,bindingFlags);
Impl.getUnionTagReader (unionType ,bindingFlags)
+
static member PreComputeUnionTagMemberInfo(unionType: Type,?bindingFlags) =
let bindingFlags = defaultArg bindingFlags BindingFlags.Public
Impl.checkNonNull "unionType" unionType;
@@ -863,17 +1104,96 @@ type FSharpValue =
Impl.getUnionTagMemberInfo(unionType ,bindingFlags)
static member PreComputeUnionReader(unionCase: UnionCaseInfo,?bindingFlags) : (obj -> obj[]) =
- Impl.checkNonNull "unionCase" unionCase;
let bindingFlags = defaultArg bindingFlags BindingFlags.Public
+ Impl.checkNonNull "unionCase" unionCase;
let typ = unionCase.DeclaringType
- Impl.getUnionCaseRecordReader (typ,unionCase.Tag,bindingFlags)
-
+ Impl.getUnionCaseRecordReader (typ,unionCase.Tag,bindingFlags)
static member GetExceptionFields(exn:obj, ?bindingFlags) =
- Impl.checkNonNull "exn" exn;
let bindingFlags = defaultArg bindingFlags BindingFlags.Public
+ Impl.checkNonNull "exn" exn;
let typ = exn.GetType()
Impl.checkExnType(typ,bindingFlags);
Impl.getRecordReader (typ,bindingFlags) exn
+module FSharpReflectionExtensions =
+
+ type FSharpType with
+
+ static member GetExceptionFields(exceptionType:Type, ?allowAccessToPrivateRepresentation) =
+ let bindingFlags = Impl.getBindingFlags allowAccessToPrivateRepresentation
+ FSharpType.GetExceptionFields(exceptionType, bindingFlags)
+
+ static member IsExceptionRepresentation(exceptionType:Type, ?allowAccessToPrivateRepresentation) =
+ let bindingFlags = Impl.getBindingFlags allowAccessToPrivateRepresentation
+ FSharpType.IsExceptionRepresentation(exceptionType, bindingFlags)
+
+ static member GetUnionCases (unionType:Type,?allowAccessToPrivateRepresentation) =
+ let bindingFlags = Impl.getBindingFlags allowAccessToPrivateRepresentation
+ FSharpType.GetUnionCases(unionType, bindingFlags)
+
+ static member GetRecordFields(recordType:Type,?allowAccessToPrivateRepresentation) =
+ let bindingFlags = Impl.getBindingFlags allowAccessToPrivateRepresentation
+ FSharpType.GetRecordFields(recordType, bindingFlags)
+
+ static member IsUnion(typ:Type,?allowAccessToPrivateRepresentation) =
+ let bindingFlags = Impl.getBindingFlags allowAccessToPrivateRepresentation
+ FSharpType.IsUnion(typ, bindingFlags)
+
+ static member IsRecord(typ:Type,?allowAccessToPrivateRepresentation) =
+ let bindingFlags = Impl.getBindingFlags allowAccessToPrivateRepresentation
+ FSharpType.IsRecord(typ, bindingFlags)
+
+ type FSharpValue with
+ static member MakeRecord(recordType:Type,args,?allowAccessToPrivateRepresentation) =
+ let bindingFlags = Impl.getBindingFlags allowAccessToPrivateRepresentation
+ FSharpValue.MakeRecord(recordType, args, bindingFlags)
+
+ static member GetRecordFields(record:obj,?allowAccessToPrivateRepresentation) =
+ let bindingFlags = Impl.getBindingFlags allowAccessToPrivateRepresentation
+ FSharpValue.GetRecordFields(record, bindingFlags)
+
+ static member PreComputeRecordReader(recordType:Type,?allowAccessToPrivateRepresentation) : (obj -> obj[]) =
+ let bindingFlags = Impl.getBindingFlags allowAccessToPrivateRepresentation
+ FSharpValue.PreComputeRecordReader(recordType, bindingFlags)
+
+ static member PreComputeRecordConstructor(recordType:Type,?allowAccessToPrivateRepresentation) =
+ let bindingFlags = Impl.getBindingFlags allowAccessToPrivateRepresentation
+ FSharpValue.PreComputeRecordConstructor(recordType, bindingFlags)
+
+ static member PreComputeRecordConstructorInfo(recordType:Type, ?allowAccessToPrivateRepresentation) =
+ let bindingFlags = Impl.getBindingFlags allowAccessToPrivateRepresentation
+ FSharpValue.PreComputeRecordConstructorInfo(recordType, bindingFlags)
+
+ static member MakeUnion(unionCase:UnionCaseInfo,args: obj [],?allowAccessToPrivateRepresentation) =
+ let bindingFlags = Impl.getBindingFlags allowAccessToPrivateRepresentation
+ FSharpValue.MakeUnion(unionCase, args, bindingFlags)
+
+ static member PreComputeUnionConstructor (unionCase:UnionCaseInfo,?allowAccessToPrivateRepresentation) =
+ let bindingFlags = Impl.getBindingFlags allowAccessToPrivateRepresentation
+ FSharpValue.PreComputeUnionConstructor(unionCase, bindingFlags)
+
+ static member PreComputeUnionConstructorInfo(unionCase:UnionCaseInfo, ?allowAccessToPrivateRepresentation) =
+ let bindingFlags = Impl.getBindingFlags allowAccessToPrivateRepresentation
+ FSharpValue.PreComputeUnionConstructorInfo(unionCase, bindingFlags)
+
+ static member PreComputeUnionTagMemberInfo(unionType: Type,?allowAccessToPrivateRepresentation) =
+ let bindingFlags = Impl.getBindingFlags allowAccessToPrivateRepresentation
+ FSharpValue.PreComputeUnionTagMemberInfo(unionType, bindingFlags)
+
+ static member GetUnionFields(obj:obj,unionType:Type,?allowAccessToPrivateRepresentation) =
+ let bindingFlags = Impl.getBindingFlags allowAccessToPrivateRepresentation
+ FSharpValue.GetUnionFields(obj, unionType, bindingFlags)
+
+ static member PreComputeUnionTagReader(unionType: Type,?allowAccessToPrivateRepresentation) : (obj -> int) =
+ let bindingFlags = Impl.getBindingFlags allowAccessToPrivateRepresentation
+ FSharpValue.PreComputeUnionTagReader(unionType, bindingFlags)
+
+ static member PreComputeUnionReader(unionCase: UnionCaseInfo,?allowAccessToPrivateRepresentation) : (obj -> obj[]) =
+ let bindingFlags = Impl.getBindingFlags allowAccessToPrivateRepresentation
+ FSharpValue.PreComputeUnionReader(unionCase, bindingFlags)
+
+ static member GetExceptionFields(exn:obj, ?allowAccessToPrivateRepresentation) =
+ let bindingFlags = Impl.getBindingFlags allowAccessToPrivateRepresentation
+ FSharpValue.GetExceptionFields(exn, bindingFlags)
diff --git a/src/fsharp/FSharp.Core/reflect.fsi b/src/fsharp/FSharp.Core/reflect.fsi
index 6ce9de9794..db0824d6dd 100755
--- a/src/fsharp/FSharp.Core/reflect.fsi
+++ b/src/fsharp/FSharp.Core/reflect.fsi
@@ -59,16 +59,6 @@ type UnionCaseInfo =
/// such as records, unions and tuples.
type FSharpValue =
- /// Creates an instance of a record type.
- ///
- /// Assumes the given input is a record type.
- /// The type of record to make.
- /// The array of values to initialize the record.
- /// Optional binding flags for the record.
- /// Thrown when the input type is not a record type.
- /// The created record.
- static member MakeRecord: recordType:Type * values:obj [] * ?bindingFlags:BindingFlags -> obj
-
/// Reads a field from a record value.
///
/// Assumes the given input is a record value. If not, ArgumentException is raised.
@@ -77,16 +67,6 @@ type FSharpValue =
/// Thrown when the input type is not a record type.
/// The field from the record.
static member GetRecordField: record:obj * info:PropertyInfo -> obj
-
- /// Reads all the fields from a record value.
- ///
- /// Assumes the given input is a record value. If not, ArgumentException is raised.
- /// The record object.
- /// Optional binding flags for the record.
- /// Thrown when the input type is not a record type.
- /// The array of fields from the record.
- static member GetRecordFields: record:obj * ?bindingFlags:BindingFlags -> obj[]
-
/// Precompute a function for reading a particular field from a record.
/// Assumes the given type is a RecordType with a field of the given name.
@@ -100,6 +80,27 @@ type FSharpValue =
/// A function to read the specified field from the record.
static member PreComputeRecordFieldReader : info:PropertyInfo -> (obj -> obj)
+#if FX_RESHAPED_REFLECTION
+#else
+ /// Creates an instance of a record type.
+ ///
+ /// Assumes the given input is a record type.
+ /// The type of record to make.
+ /// The array of values to initialize the record.
+ /// Optional binding flags for the record.
+ /// Thrown when the input type is not a record type.
+ /// The created record.
+ static member MakeRecord: recordType:Type * values:obj [] * ?bindingFlags:BindingFlags -> obj
+
+ /// Reads all the fields from a record value.
+ ///
+ /// Assumes the given input is a record value. If not, ArgumentException is raised.
+ /// The record object.
+ /// Optional binding flags for the record.
+ /// Thrown when the input type is not a record type.
+ /// The array of fields from the record.
+ static member GetRecordFields: record:obj * ?bindingFlags:BindingFlags -> obj[]
+
/// Precompute a function for reading all the fields from a record. The fields are returned in the
/// same order as the fields reported by a call to Microsoft.FSharp.Reflection.Type.GetInfo for
/// this type.
@@ -115,8 +116,6 @@ type FSharpValue =
/// Thrown when the input type is not a record type.
/// An optimized reader for the given record type.
static member PreComputeRecordReader : recordType:Type * ?bindingFlags:BindingFlags -> (obj -> obj[])
-
-
/// Precompute a function for constructing a record value.
///
/// Assumes the given type is a RecordType.
@@ -191,6 +190,16 @@ type FSharpValue =
/// The description of the constructor of the given union case.
static member PreComputeUnionConstructorInfo: unionCase:UnionCaseInfo * ?bindingFlags:BindingFlags -> MethodInfo
+ /// Reads all the fields from a value built using an instance of an F# exception declaration
+ ///
+ /// Assumes the given input is an F# exception value. If not, ArgumentException is raised.
+ /// The exception instance.
+ /// Optional binding flags.
+ /// Thrown when the input type is not an F# exception.
+ /// The fields from the given exception.
+ static member GetExceptionFields: exn:obj * ?bindingFlags:BindingFlags -> obj[]
+#endif
+
/// Creates an instance of a tuple type
///
/// Assumes at least one element is given. If not, ArgumentException is raised.
@@ -260,20 +269,12 @@ type FSharpValue =
/// A typed function from the given dynamic implementation.
static member MakeFunction : functionType:Type * implementation:(obj -> obj) -> obj
- /// Reads all the fields from a value built using an instance of an F# exception declaration
- ///
- /// Assumes the given input is an F# exception value. If not, ArgumentException is raised.
- /// The exception instance.
- /// Optional binding flags.
- /// Thrown when the input type is not an F# exception.
- /// The fields from the given exception.
- static member GetExceptionFields: exn:obj * ?bindingFlags:BindingFlags -> obj[]
-
-
[]
/// Contains operations associated with constructing and analyzing F# types such as records, unions and tuples
type FSharpType =
+#if FX_RESHAPED_REFLECTION
+#else
/// Reads all the fields from a record value, in declaration order
///
/// Assumes the given input is a record value. If not, ArgumentException is raised.
@@ -291,6 +292,36 @@ type FSharpType =
/// An array of descriptions of the cases of the given union type.
static member GetUnionCases: unionType:Type * ?bindingFlags:BindingFlags -> UnionCaseInfo[]
+
+ /// Return true if the typ is a representation of an F# record type
+ /// The type to check.
+ /// Optional binding flags.
+ /// True if the type check succeeds.
+ static member IsRecord: typ:Type * ?bindingFlags:BindingFlags -> bool
+
+ /// Returns true if the typ is a representation of an F# union type or the runtime type of a value of that type
+ /// The type to check.
+ /// Optional binding flags.
+ /// True if the type check succeeds.
+ static member IsUnion: typ:Type * ?bindingFlags:BindingFlags -> bool
+
+ /// Reads all the fields from an F# exception declaration, in declaration order
+ ///
+ /// Assumes exceptionType is an exception representation type. If not, ArgumentException is raised.
+ /// The exception type to read.
+ /// Optional binding flags.
+ /// Thrown if the given type is not an exception.
+ /// An array containing the PropertyInfo of each field in the exception.
+ static member GetExceptionFields: exceptionType:Type * ?bindingFlags:BindingFlags -> PropertyInfo[]
+
+ /// Returns true if the typ is a representation of an F# exception declaration
+ /// The type to check.
+ /// Optional binding flags.
+ /// True if the type check is an F# exception.
+ static member IsExceptionRepresentation: exceptionType:Type * ?bindingFlags:BindingFlags -> bool
+
+#endif
+
/// Returns a System.Type representing the F# function type with the given domain and range
/// The input type of the function.
/// The output type of the function.
@@ -317,17 +348,6 @@ type FSharpType =
/// True if the type check succeeds.
static member IsModule: typ:Type -> bool
- /// Return true if the typ is a representation of an F# record type
- /// The type to check.
- /// Optional binding flags.
- /// True if the type check succeeds.
- static member IsRecord: typ:Type * ?bindingFlags:BindingFlags -> bool
-
- /// Returns true if the typ is a representation of an F# union type or the runtime type of a value of that type
- /// The type to check.
- /// Optional binding flags.
- /// True if the type check succeeds.
- static member IsUnion: typ:Type * ?bindingFlags:BindingFlags -> bool
/// Gets the tuple elements from the representation of an F# tuple type.
/// The input tuple type.
@@ -339,24 +359,258 @@ type FSharpType =
/// A tuple of the domain and range types of the input function.
static member GetFunctionElements : functionType:Type -> Type * Type
- /// Reads all the fields from an F# exception declaration, in declaration order
- ///
- /// Assumes exceptionType is an exception representation type. If not, ArgumentException is raised.
- /// The exception type to read.
- /// Optional binding flags.
- /// Thrown if the given type is not an exception.
- /// An array containing the PropertyInfo of each field in the exception.
- static member GetExceptionFields: exceptionType:Type * ?bindingFlags:BindingFlags -> PropertyInfo[]
+[]
+module FSharpReflectionExtensions =
+ type FSharpValue with
+ /// Creates an instance of a record type.
+ ///
+ /// Assumes the given input is a record type.
+ /// The type of record to make.
+ /// The array of values to initialize the record.
+ /// Optional flags that denotes accessibility of the private representation.
+ /// Thrown when the input type is not a record type.
+ /// The created record.
+ static member MakeRecord: recordType:Type * values:obj [] * ?allowAccessToPrivateRepresentation : bool -> obj
+ /// Reads all the fields from a record value.
+ ///
+ /// Assumes the given input is a record value. If not, ArgumentException is raised.
+ /// The record object.
+ /// Optional flag that denotes accessibility of the private representation.
+ /// Thrown when the input type is not a record type.
+ /// The array of fields from the record.
+ static member GetRecordFields: record:obj * ?allowAccessToPrivateRepresentation : bool -> obj[]
+
+ /// Precompute a function for reading all the fields from a record. The fields are returned in the
+ /// same order as the fields reported by a call to Microsoft.FSharp.Reflection.Type.GetInfo for
+ /// this type.
+ ///
+ /// Assumes the given type is a RecordType.
+ /// If not, ArgumentException is raised during pre-computation.
+ ///
+ /// Using the computed function will typically be faster than executing a corresponding call to Value.GetInfo
+ /// because the path executed by the computed function is optimized given the knowledge that it will be
+ /// used to read values of the given type.
+ /// The type of record to read.
+ /// Optional flag that denotes accessibility of the private representation.
+ /// Thrown when the input type is not a record type.
+ /// An optimized reader for the given record type.
+ static member PreComputeRecordReader : recordType:Type * ?allowAccessToPrivateRepresentation : bool -> (obj -> obj[])
+ /// Precompute a function for constructing a record value.
+ ///
+ /// Assumes the given type is a RecordType.
+ /// If not, ArgumentException is raised during pre-computation.
+ /// The type of record to construct.
+ /// Optional flag that denotes accessibility of the private representation.
+ /// Thrown when the input type is not a record type.
+ /// A function to construct records of the given type.
+ static member PreComputeRecordConstructor : recordType:Type * ?allowAccessToPrivateRepresentation : bool -> (obj[] -> obj)
+
+ /// Get a ConstructorInfo for a record type
+ /// The record type.
+ /// Optional flag that denotes accessibility of the private representation.
+ /// A ConstructorInfo for the given record type.
+ static member PreComputeRecordConstructorInfo: recordType:Type * ?allowAccessToPrivateRepresentation : bool-> ConstructorInfo
+
+ /// Create a union case value.
+ /// The description of the union case to create.
+ /// The array of arguments to construct the given case.
+ /// Optional flag that denotes accessibility of the private representation.
+ /// The constructed union case.
+ static member MakeUnion: unionCase:UnionCaseInfo * args:obj [] * ?allowAccessToPrivateRepresentation : bool-> obj
+
+ /// Identify the union case and its fields for an object
+ ///
+ /// Assumes the given input is a union case value. If not, ArgumentException is raised.
+ ///
+ /// If the type is not given, then the runtime type of the input object is used to identify the
+ /// relevant union type. The type should always be given if the input object may be null. For example,
+ /// option values may be represented using the 'null'.
+ /// The input union case.
+ /// The union type containing the value.
+ /// Optional flag that denotes accessibility of the private representation.
+ /// Thrown when the input type is not a union case value.
+ /// The description of the union case and its fields.
+ static member GetUnionFields: value:obj * unionType:Type * ?allowAccessToPrivateRepresentation : bool -> UnionCaseInfo * obj []
+
+ /// Assumes the given type is a union type.
+ /// If not, ArgumentException is raised during pre-computation.
+ ///
+ /// Using the computed function is more efficient than calling GetUnionCase
+ /// because the path executed by the computed function is optimized given the knowledge that it will be
+ /// used to read values of the given type.
+ /// The type of union to optimize reading.
+ /// Optional flag that denotes accessibility of the private representation.
+ /// An optimized function to read the tags of the given union type.
+ static member PreComputeUnionTagReader : unionType:Type * ?allowAccessToPrivateRepresentation : bool -> (obj -> int)
+
+ /// Precompute a property or static method for reading an integer representing the case tag of a union type.
+ /// The type of union to read.
+ /// Optional flag that denotes accessibility of the private representation.
+ /// The description of the union case reader.
+ static member PreComputeUnionTagMemberInfo : unionType:Type * ?allowAccessToPrivateRepresentation : bool -> MemberInfo
+
+ /// Precomputes a function for reading all the fields for a particular discriminator case of a union type
+ ///
+ /// Using the computed function will typically be faster than executing a corresponding call to GetFields
+ /// The description of the union case to read.
+ /// Optional flag that denotes accessibility of the private representation.
+ /// A function to for reading the fields of the given union case.
+ static member PreComputeUnionReader : unionCase:UnionCaseInfo * ?allowAccessToPrivateRepresentation : bool -> (obj -> obj[])
+
+ /// Precomputes a function for constructing a discriminated union value for a particular union case.
+ /// The description of the union case.
+ /// Optional flag that denotes accessibility of the private representation.
+ /// A function for constructing values of the given union case.
+ static member PreComputeUnionConstructor : unionCase:UnionCaseInfo * ?allowAccessToPrivateRepresentation : bool -> (obj[] -> obj)
+
+ /// A method that constructs objects of the given case
+ /// The description of the union case.
+ /// Optional flag that denotes accessibility of the private representation.
+ /// The description of the constructor of the given union case.
+ static member PreComputeUnionConstructorInfo: unionCase:UnionCaseInfo * ?allowAccessToPrivateRepresentation : bool -> MethodInfo
+
+ /// Reads all the fields from a value built using an instance of an F# exception declaration
+ ///
+ /// Assumes the given input is an F# exception value. If not, ArgumentException is raised.
+ /// The exception instance.
+ /// Optional flag that denotes accessibility of the private representation.
+ /// Thrown when the input type is not an F# exception.
+ /// The fields from the given exception.
+ static member GetExceptionFields: exn:obj * ?allowAccessToPrivateRepresentation : bool -> obj[]
+
+ type FSharpType with
+ /// Reads all the fields from a record value, in declaration order
+ ///
+ /// Assumes the given input is a record value. If not, ArgumentException is raised.
+ /// The input record type.
+ /// Optional flag that denotes accessibility of the private representation.
+ /// An array of descriptions of the properties of the record type.
+ static member GetRecordFields: recordType:Type * ?allowAccessToPrivateRepresentation : bool -> PropertyInfo[]
+
+ /// Gets the cases of a union type.
+ ///
+ /// Assumes the given type is a union type. If not, ArgumentException is raised during pre-computation.
+ /// The input union type.
+ /// Optional flag that denotes accessibility of the private representation.
+ /// Thrown when the input type is not a union type.
+ /// An array of descriptions of the cases of the given union type.
+ static member GetUnionCases: unionType:Type * ?allowAccessToPrivateRepresentation : bool -> UnionCaseInfo[]
+
+
+ /// Return true if the