Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
dotNET Platform
fsharp
提交
5b1a3ae5
F
fsharp
项目概览
dotNET Platform
/
fsharp
大约 1 年 前同步成功
通知
0
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
F
fsharp
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
5b1a3ae5
编写于
5月 31, 2022
作者:
D
Don Syme
提交者:
GitHub
5月 31, 2022
1
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
apply formatting (fix build) (#13209)
* preformat * apply formatting
上级
36af364b
变更
16
隐藏空白更改
内联
并排
Showing
16 changed file
with
484 addition
and
162 deletion
+484
-162
src/FSharp.Core/.editorconfig
src/FSharp.Core/.editorconfig
+4
-0
src/FSharp.Core/QueryExtensions.fs
src/FSharp.Core/QueryExtensions.fs
+24
-20
src/FSharp.Core/array.fs
src/FSharp.Core/array.fs
+25
-5
src/FSharp.Core/async.fs
src/FSharp.Core/async.fs
+53
-16
src/FSharp.Core/collections.fs
src/FSharp.Core/collections.fs
+2
-1
src/FSharp.Core/event.fs
src/FSharp.Core/event.fs
+6
-5
src/FSharp.Core/fslib-extra-pervasives.fs
src/FSharp.Core/fslib-extra-pervasives.fs
+12
-3
src/FSharp.Core/list.fs
src/FSharp.Core/list.fs
+25
-5
src/FSharp.Core/mailbox.fs
src/FSharp.Core/mailbox.fs
+6
-3
src/FSharp.Core/map.fs
src/FSharp.Core/map.fs
+36
-7
src/FSharp.Core/quotations.fs
src/FSharp.Core/quotations.fs
+56
-21
src/FSharp.Core/reflect.fs
src/FSharp.Core/reflect.fs
+130
-52
src/FSharp.Core/resumable.fs
src/FSharp.Core/resumable.fs
+49
-12
src/FSharp.Core/seq.fs
src/FSharp.Core/seq.fs
+10
-3
src/FSharp.Core/set.fs
src/FSharp.Core/set.fs
+10
-2
src/FSharp.Core/tasks.fs
src/FSharp.Core/tasks.fs
+36
-7
未找到文件。
src/FSharp.Core/.editorconfig
浏览文件 @
5b1a3ae5
# FSharp.Core uses more "conservative" settings - more lines etc.
[*.fs]
max_line_length=120
fsharp_max_function_binding_width=1
fsharp_max_if_then_else_short_width=40
\ No newline at end of file
src/FSharp.Core/QueryExtensions.fs
浏览文件 @
5b1a3ae5
...
...
@@ -11,31 +11,33 @@ open Microsoft.FSharp.Quotations
open
Microsoft
.
FSharp
.
Quotations
.
DerivedPatterns
open
Microsoft
.
FSharp
.
Reflection
open
Microsoft
.
FSharp
.
Linq
.
RuntimeHelpers
open
System
.
Collections
open
System
.
Collections
.
Concurrent
open
System
.
Collections
.
Generic
open
System
.
Linq
open
System
.
Linq
.
Expressions
open
System
.
Reflection
// ----------------------------------------------------------------------------
/// A type used to reconstruct a grouping after applying a mutable->immutable mapping transformation
/// on a result of a query.
type
Grouping
<
'
K
,
'
T
>(
key
:
'
K
,
values
:
seq
<
'
T
>)
=
interface
System
.
Linq
.
IGrouping
<
'
K
,
'
T
>
with
interface
IGrouping
<
'
K
,
'
T
>
with
member
_.
Key
=
key
interface
System
.
Collections
.
IEnumerable
with
interface
IEnumerable
with
member
_.
GetEnumerator
()
=
values
.
GetEnumerator
()
:>
System
.
Collections
.
IEnumerator
values
.
GetEnumerator
()
:>
IEnumerator
interface
System
.
Collections
.
Generic
.
IEnumerable
<
'
T
>
with
interface
Generic
.
IEnumerable
<
'
T
>
with
member
_.
GetEnumerator
()
=
values
.
GetEnumerator
()
module
internal
Adapters
=
let
memoize
f
=
let
d
=
new
System
.
Collections
.
Concurrent
.
ConcurrentDictionary
<
Type
,
'
b
>(
HashIdentity
.
Structural
)
let
d
=
new
ConcurrentDictionary
<
Type
,
'
b
>(
HashIdentity
.
Structural
)
fun
x
->
d
.
GetOrAdd
(
x
,
(
fun
r
->
f
r
))
...
...
@@ -46,13 +48,13 @@ module internal Adapters =
let
MemberInitializationHelperMeth
=
methodhandleof
(
fun
x
->
LeafExpressionConverter
.
MemberInitializationHelper
x
)
|>
System
.
Reflection
.
MethodInfo
.
GetMethodFromHandle
:?>
System
.
Reflection
.
MethodInfo
|>
MethodInfo
.
GetMethodFromHandle
:?>
MethodInfo
let
NewAnonymousObjectHelperMeth
=
methodhandleof
(
fun
x
->
LeafExpressionConverter
.
NewAnonymousObjectHelper
x
)
|>
System
.
Reflection
.
MethodInfo
.
GetMethodFromHandle
:?>
System
.
Reflection
.
MethodInfo
|>
MethodInfo
.
GetMethodFromHandle
:?>
MethodInfo
// The following patterns are used to recognize object construction
// using the 'new O(Prop1 = <e>, Prop2 = <e>)' syntax
...
...
@@ -73,7 +75,8 @@ module internal Adapters =
let
rec
propSetList
acc
x
=
match
x
with
// detect " v.X <- y"
|
((
Patterns
.
PropertySet
(
Some
(
Patterns
.
Var
var
),
_,
_,
_))
as
p
)
::
xs
when
var
=
varArg
->
propSetList
(
p
::
acc
)
xs
|
((
Patterns
.
PropertySet
(
Some
(
Patterns
.
Var
var
),
_,
_,
_))
as
p
)
::
xs
when
var
=
varArg
->
propSetList
(
p
::
acc
)
xs
// skip unit values
|
(
Patterns
.
Value
(
v
,
_))
::
xs
when
v
=
null
->
propSetList
acc
xs
// detect "v"
...
...
@@ -190,8 +193,7 @@ module internal Adapters =
let
fields
=
Microsoft
.
FSharp
.
Reflection
.
FSharpType
.
GetRecordFields
(
typ
,
System
.
Reflection
.
BindingFlags
.
Public
|||
System
.
Reflection
.
BindingFlags
.
NonPublic
BindingFlags
.
Public
|||
BindingFlags
.
NonPublic
)
match
fields
|>
Array
.
tryFindIndex
(
fun
p
->
p
=
propInfo
)
with
...
...
@@ -223,7 +225,8 @@ module internal Adapters =
match
convs
with
|
x1
::
x2
::
x3
::
x4
::
x5
::
x6
::
x7
::
x8
::
tail
->
RewriteTupleType
ty
(
List
.
map2
ConvImmutableTypeToMutableType
[
x1
;
x2
;
x3
;
x4
;
x5
;
x6
;
x7
;
TupleConv
(
x8
::
tail
)
])
let
els
=
[
x1
;
x2
;
x3
;
x4
;
x5
;
x6
;
x7
;
TupleConv
(
x8
::
tail
)
]
RewriteTupleType
ty
(
List
.
map2
ConvImmutableTypeToMutableType
els
)
|
_
->
RewriteTupleType
ty
(
List
.
map2
ConvImmutableTypeToMutableType
convs
)
|
RecordConv
(_,
convs
)
->
assert
(
isPartiallyImmutableRecord
ty
)
...
...
@@ -231,10 +234,10 @@ module internal Adapters =
ConvImmutableTypeToMutableType
(
TupleConv
convs
)
(
FSharpType
.
MakeTupleType
types
)
|
GroupingConv
(_
keyTy
,
_
elemTy
,
conv
)
->
assert
ty
.
IsGenericType
assert
(
ty
.
GetGenericTypeDefinition
()
=
typedefof
<
System
.
Linq
.
IGrouping
<_,
_>>)
assert
(
ty
.
GetGenericTypeDefinition
()
=
typedefof
<
IGrouping
<_,
_>>)
let
keyt1
=
ty
.
GetGenericArguments
()
.[
0
]
let
valt1
=
ty
.
GetGenericArguments
()
.[
1
]
typedefof
<
System
.
Linq
.
IGrouping
<_,
_>>.
MakeGenericType
[|
keyt1
;
ConvImmutableTypeToMutableType
conv
valt1
|]
typedefof
<
IGrouping
<_,
_>>.
MakeGenericType
[|
keyt1
;
ConvImmutableTypeToMutableType
conv
valt1
|]
|
SeqConv
conv
->
assert
ty
.
IsGenericType
let
isIQ
=
ty
.
GetGenericTypeDefinition
()
=
typedefof
<
IQueryable
<_>>
...
...
@@ -256,14 +259,14 @@ module internal Adapters =
let
mhandle
=
(
methodhandleof
(
fun
x
->
LeafExpressionConverter
.
NewAnonymousObjectHelper
x
))
let
minfo
=
(
System
.
Reflection
.
MethodInfo
.
GetMethodFromHandle
mhandle
)
:?>
System
.
Reflection
.
MethodInfo
let
minfo
=
(
MethodInfo
.
GetMethodFromHandle
mhandle
)
:?>
MethodInfo
let
gmd
=
minfo
.
GetGenericMethodDefinition
()
(
fun
tm
->
match
tm
with
|
Patterns
.
Call
(_
obj
,
minfo2
,
_
args
)
->
minfo2
.
IsGenericMethod
&&
(
gmd
=
minfo2
.
GetGenericMethodDefinition
()
)
|
Patterns
.
Call
(_
obj
,
minfo2
,
_
args
)
->
minfo2
.
IsGenericMethod
&&
(
gmd
=
minfo2
.
GetGenericMethodDefinition
()
)
|
_
->
false
)
/// Cleanup the use of property-set object constructions in leaf expressions that form parts of F# queries.
...
...
@@ -305,7 +308,8 @@ module internal Adapters =
// rewrite bottom-up
let
e
=
match
e
with
|
ExprShape
.
ShapeCombination
(
comb
,
args
)
->
ExprShape
.
RebuildShapeCombination
(
comb
,
List
.
map
SimplifyConsumingExpr
args
)
|
ExprShape
.
ShapeCombination
(
comb
,
args
)
->
ExprShape
.
RebuildShapeCombination
(
comb
,
List
.
map
SimplifyConsumingExpr
args
)
|
ExprShape
.
ShapeLambda
(
v
,
body
)
->
Expr
.
Lambda
(
v
,
SimplifyConsumingExpr
body
)
|
ExprShape
.
ShapeVar
_
->
e
...
...
src/FSharp.Core/array.fs
浏览文件 @
5b1a3ae5
...
...
@@ -244,7 +244,11 @@ module Array =
// Wrap a StructBox around all keys in case the key type is itself a type using null as a representation
let
countByRefType
(
projection
:
'
T
->
'
Key
)
(
array
:
'
T
[]
)
=
countByImpl
RuntimeHelpers
.
StructBox
<
'
Key
>.
Comparer
(
fun
t
->
RuntimeHelpers
.
StructBox
(
projection
t
))
(
fun
sb
->
sb
.
Value
)
array
countByImpl
RuntimeHelpers
.
StructBox
<
'
Key
>.
Comparer
(
fun
t
->
RuntimeHelpers
.
StructBox
(
projection
t
))
(
fun
sb
->
sb
.
Value
)
array
[<
CompiledName
(
"CountBy"
)>]
let
countBy
(
projection
:
'
T
->
'
Key
)
(
array
:
'
T
[]
)
=
...
...
@@ -570,7 +574,11 @@ module Array =
// Wrap a StructBox around all keys in case the key type is itself a type using null as a representation
let
groupByRefType
(
keyf
:
'
T
->
'
Key
)
(
array
:
'
T
[]
)
=
groupByImpl
RuntimeHelpers
.
StructBox
<
'
Key
>.
Comparer
(
fun
t
->
RuntimeHelpers
.
StructBox
(
keyf
t
))
(
fun
sb
->
sb
.
Value
)
array
groupByImpl
RuntimeHelpers
.
StructBox
<
'
Key
>.
Comparer
(
fun
t
->
RuntimeHelpers
.
StructBox
(
keyf
t
))
(
fun
sb
->
sb
.
Value
)
array
[<
CompiledName
(
"GroupBy"
)>]
let
groupBy
(
projection
:
'
T
->
'
Key
)
(
array
:
'
T
[]
)
=
...
...
@@ -822,7 +830,12 @@ module Array =
count
let
private
createMask
<
'
a
>
(
f
:
'
a
->
bool
)
(
src
:
array
<
'
a
>)
(
maskArrayOut
:
byref
<
array
<
uint32
>>)
(
leftoverMaskOut
:
byref
<
uint32
>)
=
let
private
createMask
<
'
a
>
(
f
:
'
a
->
bool
)
(
src
:
array
<
'
a
>)
(
maskArrayOut
:
byref
<
array
<
uint32
>>)
(
leftoverMaskOut
:
byref
<
uint32
>)
=
let
maskArrayLength
=
src
.
Length
/
0x20
// null when there are less than 32 items in src array.
...
...
@@ -1208,7 +1221,10 @@ module Array =
if
len
%
chunkSize
<>
0
then
res
.[
chunkCount
-
1
]
<-
Microsoft
.
FSharp
.
Primitives
.
Basics
.
Array
.
subUnchecked
((
chunkCount
-
1
)
*
chunkSize
)
(
len
%
chunkSize
)
array
Microsoft
.
FSharp
.
Primitives
.
Basics
.
Array
.
subUnchecked
((
chunkCount
-
1
)
*
chunkSize
)
(
len
%
chunkSize
)
array
res
...
...
@@ -1776,7 +1792,11 @@ module Array =
for
j
in
1
..
len
-
1
do
if
lenInner
<>
array
.[
j
].
Length
then
invalidArgDifferentArrayLength
"array.[0]"
lenInner
(
String
.
Format
(
"array.[{0}]"
,
j
))
array
.[
j
].
Length
invalidArgDifferentArrayLength
"array.[0]"
lenInner
(
String
.
Format
(
"array.[{0}]"
,
j
))
array
.[
j
].
Length
let
result
:
'
T
[][]
=
Microsoft
.
FSharp
.
Primitives
.
Basics
.
Array
.
zeroCreateUnchecked
lenInner
...
...
src/FSharp.Core/async.fs
浏览文件 @
5b1a3ae5
...
...
@@ -870,13 +870,15 @@ module AsyncPrimitives =
/// - Create Thread and call Start() with exception protection. We don't expect this
/// to fail but protect nevertheless.
let
CreateSwitchToNewThreadAsync
()
=
MakeAsyncWithCancelCheck
(
fun
ctxt
->
ctxt
.
ProtectCode
(
fun
()
->
ctxt
.
trampolineHolder
.
StartThreadWithTrampoline
ctxt
.
cont
))
MakeAsyncWithCancelCheck
(
fun
ctxt
->
ctxt
.
ProtectCode
(
fun
()
->
ctxt
.
trampolineHolder
.
StartThreadWithTrampoline
ctxt
.
cont
))
/// - Initial cancellation check
/// - Call ThreadPool.QueueUserWorkItem with exception protection. We don't expect this
/// to fail but protect nevertheless.
let
CreateSwitchToThreadPoolAsync
()
=
MakeAsyncWithCancelCheck
(
fun
ctxt
->
ctxt
.
ProtectCode
(
fun
()
->
ctxt
.
trampolineHolder
.
QueueWorkItemWithTrampoline
ctxt
.
cont
))
MakeAsyncWithCancelCheck
(
fun
ctxt
->
ctxt
.
ProtectCode
(
fun
()
->
ctxt
.
trampolineHolder
.
QueueWorkItemWithTrampoline
ctxt
.
cont
))
/// Post back to the sync context regardless of which continuation is taken
/// - Call syncCtxt.Post with exception protection
...
...
@@ -917,7 +919,8 @@ module AsyncPrimitives =
// This logic was added in F# 2.0 though is incorrect from the perspective of
// how SynchronizationContext is meant to work. However the logic works for
// mainline scenarios (WinForms/WPF) and for compatibility reasons we won't change it.
|
_
when
Object
.
Equals
(
syncCtxt
,
currentSyncCtxt
)
&&
thread
.
Equals
Thread
.
CurrentThread
->
executeImmediately
()
|
_
when
Object
.
Equals
(
syncCtxt
,
currentSyncCtxt
)
&&
thread
.
Equals
Thread
.
CurrentThread
->
executeImmediately
()
|
_
->
trampolineHolder
.
PostOrQueueWithTrampoline
syncCtxt
action
member
_.
PostOrQueueWithTrampoline
res
=
...
...
@@ -1074,7 +1077,7 @@ module AsyncPrimitives =
(
typeof
<
FuncDelegate
<
'
T
>>)
.
GetMethod
(
"Invoke"
,
BindingFlags
.
Public
|||
BindingFlags
.
NonPublic
|||
BindingFlags
.
Instance
)
System
.
Delegate
.
CreateDelegate
(
typeof
<
'
Delegate
>,
obj
,
invokeMeth
)
:?>
'
Delegate
Delegate
.
CreateDelegate
(
typeof
<
'
Delegate
>,
obj
,
invokeMeth
)
:?>
'
Delegate
[<
DebuggerHidden
>]
let
QueueAsync
cancellationToken
cont
econt
ccont
computation
=
...
...
@@ -1429,7 +1432,9 @@ type Async =
static
member
CancelCheck
()
=
unitAsync
static
member
FromContinuations
(
callback
:
(
'
T
->
unit
)
*
(
exn
->
unit
)
*
(
OperationCanceledException
->
unit
)
->
unit
)
:
Async
<
'
T
>
=
static
member
FromContinuations
(
callback
:
(
'
T
->
unit
)
*
(
exn
->
unit
)
*
(
OperationCanceledException
->
unit
)
->
unit
)
:
Async
<
'
T
>
=
MakeAsyncWithCancelCheck
(
fun
ctxt
->
let
mutable
underCurrentThreadStack
=
true
let
mutable
contToTailCall
=
None
...
...
@@ -1451,7 +1456,11 @@ type Async =
ctxt
.
trampolineHolder
.
ExecuteWithTrampoline
(
fun
()
->
cont
x
)
|>
unfake
try
callback
(
once
ctxt
.
cont
,
(
fun
exn
->
once
ctxt
.
econt
(
ExceptionDispatchInfo
.
RestoreOrCapture
exn
)),
once
ctxt
.
ccont
)
callback
(
once
ctxt
.
cont
,
(
fun
exn
->
once
ctxt
.
econt
(
ExceptionDispatchInfo
.
RestoreOrCapture
exn
)),
once
ctxt
.
ccont
)
with
exn
->
if
not
(
latch
.
Enter
()
)
then
invalidOp
(
SR
.
GetString
(
SR
.
controlContinuationInvokedMultipleTimes
))
...
...
@@ -1518,7 +1527,12 @@ type Async =
static
member
Parallel
(
computations
:
seq
<
Async
<
'
T
>>,
?
maxDegreeOfParallelism
:
int
)
=
match
maxDegreeOfParallelism
with
|
Some
x
when
x
<
1
->
raise
(
System
.
ArgumentException
(
String
.
Format
(
SR
.
GetString
(
SR
.
maxDegreeOfParallelismNotPositive
),
x
),
"maxDegreeOfParallelism"
))
raise
(
System
.
ArgumentException
(
String
.
Format
(
SR
.
GetString
(
SR
.
maxDegreeOfParallelismNotPositive
),
x
),
"maxDegreeOfParallelism"
)
)
|
_
->
()
MakeAsyncWithCancelCheck
(
fun
ctxt
->
...
...
@@ -1547,8 +1561,10 @@ type Async =
match
firstExn
with
|
None
->
ctxt
.
trampolineHolder
.
ExecuteWithTrampoline
(
fun
()
->
ctxt
.
cont
results
)
|
Some
(
Choice1Of2
exn
)
->
ctxt
.
trampolineHolder
.
ExecuteWithTrampoline
(
fun
()
->
ctxt
.
econt
exn
)
|
Some
(
Choice2Of2
cexn
)
->
ctxt
.
trampolineHolder
.
ExecuteWithTrampoline
(
fun
()
->
ctxt
.
ccont
cexn
)
|
Some
(
Choice1Of2
exn
)
->
ctxt
.
trampolineHolder
.
ExecuteWithTrampoline
(
fun
()
->
ctxt
.
econt
exn
)
|
Some
(
Choice2Of2
cexn
)
->
ctxt
.
trampolineHolder
.
ExecuteWithTrampoline
(
fun
()
->
ctxt
.
ccont
cexn
)
else
fake
()
...
...
@@ -1724,7 +1740,12 @@ type Async =
let
cancellationToken
=
defaultArg
cancellationToken
defaultCancellationTokenSource
.
Token
AsyncPrimitives
.
StartWithContinuations
cancellationToken
computation
continuation
exceptionContinuation
cancellationContinuation
AsyncPrimitives
.
StartWithContinuations
cancellationToken
computation
continuation
exceptionContinuation
cancellationContinuation
static
member
StartWithContinuations
(
...
...
@@ -1781,7 +1802,8 @@ type Async =
DisposeCancellationRegistration
&
registration
DisposeTimer
&
timer
ctxt
.
trampolineHolder
.
ExecuteWithTrampoline
(
fun
()
->
ctxt
.
ccont
(
OperationCanceledException
(
ctxt
.
token
)))
ctxt
.
trampolineHolder
.
ExecuteWithTrampoline
(
fun
()
->
ctxt
.
ccont
(
OperationCanceledException
(
ctxt
.
token
)))
|>
unfake
)
)
|>
Some
...
...
@@ -1847,7 +1869,8 @@ type Async =
UnregisterWaitHandle
&
rwh
// Call the cancellation continuation
ctxt
.
trampolineHolder
.
ExecuteWithTrampoline
(
fun
()
->
ctxt
.
ccont
(
OperationCanceledException
(
ctxt
.
token
)))
ctxt
.
trampolineHolder
.
ExecuteWithTrampoline
(
fun
()
->
ctxt
.
ccont
(
OperationCanceledException
(
ctxt
.
token
)))
|>
unfake
)
)
|>
Some
...
...
@@ -1929,7 +1952,11 @@ type Async =
let
res
=
resultCell
.
GrabResult
()
return
res
.
Commit
()
else
let
!
ok
=
Async
.
AwaitWaitHandle
(
resultCell
.
GetWaitHandle
()
,
?
millisecondsTimeout
=
millisecondsTimeout
)
let
!
ok
=
Async
.
AwaitWaitHandle
(
resultCell
.
GetWaitHandle
()
,
?
millisecondsTimeout
=
millisecondsTimeout
)
if
ok
then
let
res
=
resultCell
.
GrabResult
()
...
...
@@ -2009,10 +2036,18 @@ type Async =
Async
.
FromBeginEnd
((
fun
(
iar
,
state
)
->
beginAction
(
arg
,
iar
,
state
)),
endAction
,
?
cancelAction
=
cancelAction
)
static
member
FromBeginEnd
(
arg1
,
arg2
,
beginAction
,
endAction
,
?
cancelAction
)
:
Async
<
'
T
>
=
Async
.
FromBeginEnd
((
fun
(
iar
,
state
)
->
beginAction
(
arg1
,
arg2
,
iar
,
state
)),
endAction
,
?
cancelAction
=
cancelAction
)
Async
.
FromBeginEnd
(
(
fun
(
iar
,
state
)
->
beginAction
(
arg1
,
arg2
,
iar
,
state
)),
endAction
,
?
cancelAction
=
cancelAction
)
static
member
FromBeginEnd
(
arg1
,
arg2
,
arg3
,
beginAction
,
endAction
,
?
cancelAction
)
:
Async
<
'
T
>
=
Async
.
FromBeginEnd
((
fun
(
iar
,
state
)
->
beginAction
(
arg1
,
arg2
,
arg3
,
iar
,
state
)),
endAction
,
?
cancelAction
=
cancelAction
)
Async
.
FromBeginEnd
(
(
fun
(
iar
,
state
)
->
beginAction
(
arg1
,
arg2
,
arg3
,
iar
,
state
)),
endAction
,
?
cancelAction
=
cancelAction
)
static
member
AsBeginEnd
<
'
Arg
,
'
T
>
(
computation
:
(
'
Arg
->
Async
<
'
T
>))
...
...
@@ -2267,7 +2302,9 @@ module WebExtensions =
)
|>
CreateTryWithFilterAsync
(
fun
exn
->
match
exn
with
|
:?
System
.
Net
.
WebException
as
webExn
when
webExn
.
Status
=
System
.
Net
.
WebExceptionStatus
.
RequestCanceled
&&
canceled
->
|
:?
System
.
Net
.
WebException
as
webExn
when
webExn
.
Status
=
System
.
Net
.
WebExceptionStatus
.
RequestCanceled
&&
canceled
->
Some
(
CreateAsyncResultAsync
(
AsyncResult
.
Canceled
(
OperationCanceledException
webExn
.
Message
)))
|
_
->
None
)
...
...
src/FSharp.Core/collections.fs
浏览文件 @
5b1a3ae5
...
...
@@ -50,7 +50,8 @@ module ComparisonIdentity =
let
inline
Structural
<
'
T
when
'
T
:
comparison
>
:
IComparer
<
'
T
>
=
LanguagePrimitives
.
FastGenericComparer
<
'
T
>
let
inline
NonStructural
<
'
T
when
'
T
:
(
static
member
(<):
'
T
*
'
T
->
bool
)
and
'
T
:
(
static
member
(>):
'
T
*
'
T
->
bool
)>
:
IComparer
<
'
T
>
=
let
inline
NonStructural
<
'
T
when
'
T
:
(
static
member
(<):
'
T
*
'
T
->
bool
)
and
'
T
:
(
static
member
(>):
'
T
*
'
T
->
bool
)>
:
IComparer
<
'
T
>
=
{
new
IComparer
<
'
T
>
with
member
_.
Compare
(
x
,
y
)
=
NonStructuralComparison
.
compare
x
y
...
...
src/FSharp.Core/event.fs
浏览文件 @
5b1a3ae5
...
...
@@ -8,8 +8,9 @@ open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators
open
Microsoft
.
FSharp
.
Core
.
Operators
open
Microsoft
.
FSharp
.
Collections
open
Microsoft
.
FSharp
.
Control
open
System
.
Reflection
open
System
open
System
.
Diagnostics
open
System
.
Reflection
module
private
Atomic
=
open
System
.
Threading
...
...
@@ -79,7 +80,8 @@ type EventDelegee<'Args>(observer: System.IObserver<'Args>) =
type
EventWrapper
<
'
Delegate
,
'
Args
>
=
delegate
of
'
Delegate
*
obj
*
'
Args
->
unit
[<
CompiledName
(
"FSharpEvent`2"
)>]
type
Event
<
'
Delegate
,
'
Args
when
'
Delegate
:
delegate
<
'
Args
,
unit
>
and
'
Delegate
:>
System
.
Delegate
and
'
Delegate
:
not
struct
>()
=
type
Event
<
'
Delegate
,
'
Args
when
'
Delegate
:
delegate
<
'
Args
,
unit
>
and
'
Delegate
:>
System
.
Delegate
and
'
Delegate
:
not
struct
>()
=
let
mutable
multicast
:
'
Delegate
=
Unchecked
.
defaultof
<_>
...
...
@@ -98,7 +100,7 @@ type Event<'Delegate, 'Args when 'Delegate: delegate<'Args, unit> and 'Delegate
// CreateDelegate creates a delegate that is fast to invoke.
static
let
invoker
=
if
argTypes
.
Length
=
1
then
(
System
.
Delegate
.
CreateDelegate
(
typeof
<
EventWrapper
<
'
Delegate
,
'
Args
>>,
mi
)
:?>
EventWrapper
<
'
Delegate
,
'
Args
>)
(
Delegate
.
CreateDelegate
(
typeof
<
EventWrapper
<
'
Delegate
,
'
Args
>>,
mi
)
:?>
EventWrapper
<
'
Delegate
,
'
Args
>)
else
null
...
...
@@ -152,8 +154,7 @@ type Event<'Delegate, 'Args when 'Delegate: delegate<'Args, unit> and 'Delegate
member
e
.
Subscribe
(
observer
)
=
let
obj
=
new
EventDelegee
<
'
Args
>(
observer
)
let
h
=
System
.
Delegate
.
CreateDelegate
(
typeof
<
'
Delegate
>,
obj
,
invokeInfo
)
:?>
'
Delegate
let
h
=
Delegate
.
CreateDelegate
(
typeof
<
'
Delegate
>,
obj
,
invokeInfo
)
:?>
'
Delegate
(
e
:?>
IDelegateEvent
<
'
Delegate
>).
AddHandler
(
h
)
...
...
src/FSharp.Core/fslib-extra-pervasives.fs
浏览文件 @
5b1a3ae5
...
...
@@ -37,12 +37,20 @@ module ExtraTopLevelOperators =
dummyArray
.
Length
|>
ignore
// pretty stupid way to avoid tail call, would be better if attribute existed, but this should be inlineable by the JIT
result
let
inline
ICollection_Contains
<
'
collection
,
'
item
when
'
collection
:>
ICollection
<
'
item
>>
(
collection
:
'
collection
)
(
item
:
'
item
)
=
let
inline
ICollection_Contains
<
'
collection
,
'
item
when
'
collection
:>
ICollection
<
'
item
>>
(
collection
:
'
collection
)
(
item
:
'
item
)
=
collection
.
Contains
item
[<
DebuggerDisplay
(
"Count = {Count}"
)>]
[<
DebuggerTypeProxy
(
typedefof
<
DictDebugView
<_,
_,
_>>)>]
type
DictImpl
<
'
SafeKey
,
'
Key
,
'
T
>(
t
:
Dictionary
<
'
SafeKey
,
'
T
>,
makeSafeKey
:
'
Key
->
'
SafeKey
,
getKey
:
'
SafeKey
->
'
Key
)
=
type
DictImpl
<
'
SafeKey
,
'
Key
,
'
T
>
(
t
:
Dictionary
<
'
SafeKey
,
'
T
>,
makeSafeKey
:
'
Key
->
'
SafeKey
,
getKey
:
'
SafeKey
->
'
Key
)
=
#
if
NETSTANDARD
static
let
emptyEnumerator
=
(
Array
.
empty
<
KeyValuePair
<
'
Key
,
'
T
>>
:>
seq
<_>).
GetEnumerator
()
...
...
@@ -512,7 +520,8 @@ type ITypeProvider =
abstract
GetStaticParameters
:
typeWithoutArguments
:
Type
->
ParameterInfo
[]
abstract
ApplyStaticArguments
:
typeWithoutArguments
:
Type
*
typePathWithArguments
:
string
[]
*
staticArguments
:
obj
[]
->
Type
abstract
ApplyStaticArguments
:
typeWithoutArguments
:
Type
*
typePathWithArguments
:
string
[]
*
staticArguments
:
obj
[]
->
Type
abstract
GetInvokerExpression
:
syntheticMethodBase
:
MethodBase
*
parameters
:
Expr
[]
->
Expr
...
...
src/FSharp.Core/list.fs
浏览文件 @
5b1a3ae5
...
...
@@ -75,7 +75,11 @@ module List =
// Wrap a StructBox around all keys in case the key type is itself a type using null as a representation
let
countByRefType
(
projection
:
'
T
->
'
Key
)
(
list
:
'
T
list
)
=
countByImpl
RuntimeHelpers
.
StructBox
<
'
Key
>.
Comparer
(
fun
t
->
RuntimeHelpers
.
StructBox
(
projection
t
))
(
fun
sb
->
sb
.
Value
)
list
countByImpl
RuntimeHelpers
.
StructBox
<
'
Key
>.
Comparer
(
fun
t
->
RuntimeHelpers
.
StructBox
(
projection
t
))
(
fun
sb
->
sb
.
Value
)
list
[<
CompiledName
(
"CountBy"
)>]
let
countBy
(
projection
:
'
T
->
'
Key
)
(
list
:
'
T
list
)
=
...
...
@@ -358,7 +362,13 @@ module List =
let
arrn
=
arr
.
Length
foldArraySubRight
f
arr
0
(
arrn
-
2
)
arr
.[
arrn
-
1
]
let
scanArraySubRight
<
'
T
,
'
State
>
(
f
:
OptimizedClosures
.
FSharpFunc
<
'
T
,
'
State
,
'
State
>)
(
arr
:
_[])
start
fin
initState
=
let
scanArraySubRight
<
'
T
,
'
State
>
(
f
:
OptimizedClosures
.
FSharpFunc
<
'
T
,
'
State
,
'
State
>)
(
arr
:
_[])
start
fin
initState
=
let
mutable
state
=
initState
let
mutable
res
=
[
state
]
...
...
@@ -411,7 +421,8 @@ module List =
|
[]
,
[]
->
f
.
Invoke
(
h1
,
k1
,
state
)
|
[
h2
],
[
k2
]
->
f
.
Invoke
(
h1
,
k1
,
f
.
Invoke
(
h2
,
k2
,
state
))
|
[
h2
;
h3
],
[
k2
;
k3
]
->
f
.
Invoke
(
h1
,
k1
,
f
.
Invoke
(
h2
,
k2
,
f
.
Invoke
(
h3
,
k3
,
state
)))
|
[
h2
;
h3
;
h4
],
[
k2
;
k3
;
k4
]
->
f
.
Invoke
(
h1
,
k1
,
f
.
Invoke
(
h2
,
k2
,
f
.
Invoke
(
h3
,
k3
,
f
.
Invoke
(
h4
,
k4
,
state
))))
|
[
h2
;
h3
;
h4
],
[
k2
;
k3
;
k4
]
->
f
.
Invoke
(
h1
,
k1
,
f
.
Invoke
(
h2
,
k2
,
f
.
Invoke
(
h3
,
k3
,
f
.
Invoke
(
h4
,
k4
,
state
))))
|
_
->
foldBack2UsingArrays
f
list1
list2
state
|
[]
,
xs2
->
invalidArgDifferentListLength
"list1"
"list2"
xs2
.
Length
|
xs1
,
[]
->
invalidArgDifferentListLength
"list2"
"list1"
xs1
.
Length
...
...
@@ -528,7 +539,12 @@ module List =
let
where
predicate
list
=
Microsoft
.
FSharp
.
Primitives
.
Basics
.
List
.
filter
predicate
list
let
inline
groupByImpl
(
comparer
:
IEqualityComparer
<
'
SafeKey
>)
(
keyf
:
'
T
->
'
SafeKey
)
(
getKey
:
'
SafeKey
->
'
Key
)
(
list
:
'
T
list
)
=
let
inline
groupByImpl
(
comparer
:
IEqualityComparer
<
'
SafeKey
>)
(
keyf
:
'
T
->
'
SafeKey
)
(
getKey
:
'
SafeKey
->
'
Key
)
(
list
:
'
T
list
)
=
Microsoft
.
FSharp
.
Primitives
.
Basics
.
List
.
groupBy
comparer
keyf
getKey
list
// We avoid wrapping a StructBox, because under 64 JIT we get some "hard" tailcalls which affect performance
...
...
@@ -537,7 +553,11 @@ module List =
// Wrap a StructBox around all keys in case the key type is itself a type using null as a representation
let
groupByRefType
(
keyf
:
'
T
->
'
Key
)
(
list
:
'
T
list
)
=
groupByImpl
RuntimeHelpers
.
StructBox
<
'
Key
>.
Comparer
(
fun
t
->
RuntimeHelpers
.
StructBox
(
keyf
t
))
(
fun
sb
->
sb
.
Value
)
list
groupByImpl
RuntimeHelpers
.
StructBox
<
'
Key
>.
Comparer
(
fun
t
->
RuntimeHelpers
.
StructBox
(
keyf
t
))
(
fun
sb
->
sb
.
Value
)
list
[<
CompiledName
(
"GroupBy"
)>]
let
groupBy
(
projection
:
'
T
->
'
Key
)
(
list
:
'
T
list
)
=
...
...
src/FSharp.Core/mailbox.fs
浏览文件 @
5b1a3ae5
...
...
@@ -203,7 +203,8 @@ type Mailbox<'Msg>(cancellationSupported: bool) =
match
ok
with
|
Choice1Of2
true
->
return
!
scan
timeoutAsync
timeoutCts
|
Choice1Of2
false
->
return
failwith
"should not happen - waitOneNoTimeoutOrCancellation always returns true"
|
Choice1Of2
false
->
return
failwith
"should not happen - waitOneNoTimeoutOrCancellation always returns true"
|
Choice2Of2
()
->
lock
syncRoot
(
fun
()
->
// Cancel the outstanding wait for messages installed by waitOneWithCancellation
...
...
@@ -454,8 +455,10 @@ type MailboxProcessor<'Msg>(body, ?cancellationToken) =
// Nothing to dispose, no wait handles used
let
resultCell
=
new
ResultCell
<_>()
let
msg
=
buildMessage
(
new
AsyncReplyChannel
<_>(
fun
reply
->
resultCell
.
RegisterResult
(
reply
,
reuseThread
=
false
)
|>
ignore
))
let
channel
=
AsyncReplyChannel
<_>(
fun
reply
->
resultCell
.
RegisterResult
(
reply
,
reuseThread
=
false
)
|>
ignore
)
let
msg
=
buildMessage
channel
mailbox
.
Post
msg
resultCell
.
AwaitResult_NoDirectCancelOrTimeout
...
...
src/FSharp.Core/map.fs
浏览文件 @
5b1a3ae5
...
...
@@ -22,7 +22,14 @@ type internal MapTree<'Key, 'Value>(k: 'Key, v: 'Value, h: int) =
[<
NoEquality
;
NoComparison
>]
[<
Sealed
>]
[<
AllowNullLiteral
>]
type
internal
MapTreeNode
<
'
Key
,
'
Value
>(
k
:
'
Key
,
v
:
'
Value
,
left
:
MapTree
<
'
Key
,
'
Value
>,
right
:
MapTree
<
'
Key
,
'
Value
>,
h
:
int
)
=
type
internal
MapTreeNode
<
'
Key
,
'
Value
>
(
k
:
'
Key
,
v
:
'
Value
,
left
:
MapTree
<
'
Key
,
'
Value
>,
right
:
MapTree
<
'
Key
,
'
Value
>,
h
:
int
)
=
inherit
MapTree
<
'
Key
,
'
Value
>(
k
,
v
,
h
)
member
_.
Left
=
left
member
_.
Right
=
right
...
...
@@ -68,7 +75,7 @@ module MapTree =
traceCount
<-
traceCount
+
1
if
traceCount
%
1000000
=
0
then
System
.
Console
.
WriteLine
(
Console
.
WriteLine
(
"#MapOne = {0}, #MapNode = {1}, #Add = {2}, #Remove = {3}, #Unions = {4}, #Lookups = {5}, avMapTreeSizeOnNodeCreation = {6}, avMapSizeOnCreation = {7}, avMapSizeOnLookup = {8}"
,
numOnes
,
numNodes
,
...
...
@@ -81,7 +88,7 @@ module MapTree =
(
totalSizeOnMapLookup
/
float
numLookups
)
)
System
.
Console
.
WriteLine
(
"#largestMapSize = {0}, largestMapStackTrace = {1}"
,
largestMapSize
,
largestMapStackTrace
)
Console
.
WriteLine
(
"#largestMapSize = {0}, largestMapStackTrace = {1}"
,
largestMapSize
,
largestMapStackTrace
)
let
MapTree
(
k
,
v
)
=
report
()
...
...
@@ -202,7 +209,12 @@ module MapTree =
else
(
acc1
,
add
comparer
k
v
acc2
)
let
rec
partitionAux
(
comparer
:
IComparer
<
'
Key
>)
(
f
:
OptimizedClosures
.
FSharpFunc
<_,
_,
_>)
(
m
:
MapTree
<
'
Key
,
'
Value
>)
acc
=
let
rec
partitionAux
(
comparer
:
IComparer
<
'
Key
>)
(
f
:
OptimizedClosures
.
FSharpFunc
<_,
_,
_>)
(
m
:
MapTree
<
'
Key
,
'
Value
>)
acc
=
if
isEmpty
m
then
acc
else
if
m
.
Height
=
1
then
...
...
@@ -222,7 +234,12 @@ module MapTree =
else
acc
let
rec
filterAux
(
comparer
:
IComparer
<
'
Key
>)
(
f
:
OptimizedClosures
.
FSharpFunc
<_,
_,
_>)
(
m
:
MapTree
<
'
Key
,
'
Value
>)
acc
=
let
rec
filterAux
(
comparer
:
IComparer
<
'
Key
>)
(
f
:
OptimizedClosures
.
FSharpFunc
<_,
_,
_>)
(
m
:
MapTree
<
'
Key
,
'
Value
>)
acc
=
if
isEmpty
m
then
acc
else
if
m
.
Height
=
1
then
...
...
@@ -273,7 +290,12 @@ module MapTree =
else
rebalance
mn
.
Left
mn
.
Key
mn
.
Value
(
remove
comparer
k
mn
.
Right
)
let
rec
change
(
comparer
:
IComparer
<
'
Key
>)
k
(
u
:
'
Value
option
->
'
Value
option
)
(
m
:
MapTree
<
'
Key
,
'
Value
>)
:
MapTree
<
'
Key
,
'
Value
>
=
let
rec
change
(
comparer
:
IComparer
<
'
Key
>)
k
(
u
:
'
Value
option
->
'
Value
option
)
(
m
:
MapTree
<
'
Key
,
'
Value
>)
:
MapTree
<
'
Key
,
'
Value
>
=
if
isEmpty
m
then
match
u
None
with
|
None
->
m
...
...
@@ -440,7 +462,14 @@ module MapTree =
let
fold
f
x
m
=
foldOpt
(
OptimizedClosures
.
FSharpFunc
<_,
_,
_,
_>.
Adapt
f
)
x
m
let
foldSectionOpt
(
comparer
:
IComparer
<
'
Key
>)
lo
hi
(
f
:
OptimizedClosures
.
FSharpFunc
<_,
_,
_,
_>)
(
m
:
MapTree
<
'
Key
,
'
Value
>)
x
=
let
foldSectionOpt
(
comparer
:
IComparer
<
'
Key
>)
lo
hi
(
f
:
OptimizedClosures
.
FSharpFunc
<_,
_,
_,
_>)
(
m
:
MapTree
<
'
Key
,
'
Value
>)
x
=
let
rec
foldFromTo
(
f
:
OptimizedClosures
.
FSharpFunc
<_,
_,
_,
_>)
(
m
:
MapTree
<
'
Key
,
'
Value
>)
x
=
if
isEmpty
m
then
x
...
...
src/FSharp.Core/quotations.fs
浏览文件 @
5b1a3ae5
...
...
@@ -256,12 +256,16 @@ and [<CompiledName("FSharpExpr"); StructuredFormatDisplay("{DebugText}")>] Expr(
eq
t1
(
CombTerm
(
InstanceMethodCallOp
(
minfo2
),
obj2
::
args2WithoutWitnesses
))
// We strip off StaticMethodCallWOp to ensure that CallWithWitness = Call
|
CombTerm
(
StaticMethodCallWOp
(
minfo1
,
_
minfoW1
,
nWitnesses1
),
args1
),
_
when
nWitnesses1
<=
args1
.
Length
->
|
CombTerm
(
StaticMethodCallWOp
(
minfo1
,
_
minfoW1
,
nWitnesses1
),
args1
),
_
when
nWitnesses1
<=
args1
.
Length
->
let
argsWithoutWitnesses1
=
List
.
skip
nWitnesses1
args1
eq
(
CombTerm
(
StaticMethodCallOp
(
minfo1
),
argsWithoutWitnesses1
))
t2
// We strip off StaticMethodCallWOp to ensure that CallWithWitness = Call
|
_,
CombTerm
(
StaticMethodCallWOp
(
minfo2
,
_
minfoW2
,
nWitnesses2
),
args2
)
when
nWitnesses2
<=
args2
.
Length
->
|
_,
CombTerm
(
StaticMethodCallWOp
(
minfo2
,
_
minfoW2
,
nWitnesses2
),
args2
)
when
nWitnesses2
<=
args2
.
Length
->
let
argsWithoutWitnesses2
=
List
.
skip
nWitnesses2
args2
eq
t1
(
CombTerm
(
StaticMethodCallOp
(
minfo2
),
argsWithoutWitnesses2
))
...
...
@@ -383,11 +387,14 @@ and [<CompiledName("FSharpExpr"); StructuredFormatDisplay("{DebugText}")>] Expr(
|
CombTerm
(
ValueOp
(
v
,
_,
None
),
[]
)
->
combL
"Value"
[
objL
v
]
|
CombTerm
(
WithValueOp
(
v
,
_),
[
defn
])
->
combL
"WithValue"
[
objL
v
;
expr
defn
]
|
CombTerm
(
InstanceMethodCallOp
(
minfo
),
obj
::
args
)
->
combL
"Call"
[
someL
obj
;
minfoL
minfo
;
listL
(
exprs
args
)
]
|
CombTerm
(
InstanceMethodCallOp
(
minfo
),
obj
::
args
)
->
combL
"Call"
[
someL
obj
;
minfoL
minfo
;
listL
(
exprs
args
)
]
|
CombTerm
(
StaticMethodCallOp
(
minfo
),
args
)
->
combL
"Call"
[
noneL
;
minfoL
minfo
;
listL
(
exprs
args
)
]
|
CombTerm
(
InstanceMethodCallWOp
(
minfo
,
_
minfoW
,
nWitnesses
),
obj
::
argsWithoutObj
)
when
nWitnesses
<=
argsWithoutObj
.
Length
->
|
CombTerm
(
InstanceMethodCallWOp
(
minfo
,
_
minfoW
,
nWitnesses
),
obj
::
argsWithoutObj
)
when
nWitnesses
<=
argsWithoutObj
.
Length
->
let
argsWithoutWitnesses
=
List
.
skip
nWitnesses
argsWithoutObj
combL
"Call"
[
someL
obj
;
minfoL
minfo
;
listL
(
exprs
argsWithoutWitnesses
)
]
...
...
@@ -395,9 +402,11 @@ and [<CompiledName("FSharpExpr"); StructuredFormatDisplay("{DebugText}")>] Expr(
let
argsWithoutWitnesses
=
List
.
skip
nWitnesses
args
combL
"Call"
[
noneL
;
minfoL
minfo
;
listL
(
exprs
argsWithoutWitnesses
)
]
|
CombTerm
(
InstancePropGetOp
(
pinfo
),
(
obj
::
args
))
->
combL
"PropertyGet"
[
someL
obj
;
pinfoL
pinfo
;
listL
(
exprs
args
)
]
|
CombTerm
(
InstancePropGetOp
(
pinfo
),
(
obj
::
args
))
->
combL
"PropertyGet"
[
someL
obj
;
pinfoL
pinfo
;
listL
(
exprs
args
)
]
|
CombTerm
(
StaticPropGetOp
(
pinfo
),
args
)
->
combL
"PropertyGet"
[
noneL
;
pinfoL
pinfo
;
listL
(
exprs
args
)
]
|
CombTerm
(
InstancePropSetOp
(
pinfo
),
(
obj
::
args
))
->
combL
"PropertySet"
[
someL
obj
;
pinfoL
pinfo
;
listL
(
exprs
args
)
]
|
CombTerm
(
InstancePropSetOp
(
pinfo
),
(
obj
::
args
))
->
combL
"PropertySet"
[
someL
obj
;
pinfoL
pinfo
;
listL
(
exprs
args
)
]
|
CombTerm
(
StaticPropSetOp
(
pinfo
),
args
)
->
combL
"PropertySet"
[
noneL
;
pinfoL
pinfo
;
listL
(
exprs
args
)
]
|
CombTerm
(
InstanceFieldGetOp
(
finfo
),
[
obj
])
->
combL
"FieldGet"
[
someL
obj
;
finfoL
finfo
]
|
CombTerm
(
StaticFieldGetOp
(
finfo
),
[]
)
->
combL
"FieldGet"
[
noneL
;
finfoL
finfo
]
...
...
@@ -415,7 +424,8 @@ and [<CompiledName("FSharpExpr"); StructuredFormatDisplay("{DebugText}")>] Expr(
combL
"ForIntegerRangeLoop"
[
varL
v
;
expr
e1
;
expr
e2
;
expr
e3
]
|
CombTerm
(
WhileLoopOp
,
args
)
->
combL
"WhileLoop"
(
exprs
args
)
|
CombTerm
(
TryFinallyOp
,
args
)
->
combL
"TryFinally"
(
exprs
args
)
|
CombTerm
(
TryWithOp
,
[
e1
;
Lambda
(
v1
,
e2
);
Lambda
(
v2
,
e3
)
])
->
combL
"TryWith"
[
expr
e1
;
varL
v1
;
expr
e2
;
varL
v2
;
expr
e3
]
|
CombTerm
(
TryWithOp
,
[
e1
;
Lambda
(
v1
,
e2
);
Lambda
(
v2
,
e3
)
])
->
combL
"TryWith"
[
expr
e1
;
varL
v1
;
expr
e2
;
varL
v2
;
expr
e3
]
|
CombTerm
(
SequentialOp
,
args
)
->
combL
"Sequential"
(
exprs
args
)
|
CombTerm
(
NewDelegateOp
ty
,
[
e
])
->
...
...
@@ -764,7 +774,9 @@ module Patterns =
Some
(
None
,
minfo
,
List
.
skip
nWitnesses
args
)
// A InstanceMethodCallWOp matches as if it were a InstanceMethodCallOp
|
E
(
CombTerm
(
InstanceMethodCallWOp
(
minfo
,
_
minfoW
,
nWitnesses
),
obj
::
argsWithoutObj
))
when
nWitnesses
<=
argsWithoutObj
.
Length
->
|
E
(
CombTerm
(
InstanceMethodCallWOp
(
minfo
,
_
minfoW
,
nWitnesses
),
obj
::
argsWithoutObj
))
when
nWitnesses
<=
argsWithoutObj
.
Length
->
let
argsWithoutWitnesses
=
List
.
skip
nWitnesses
argsWithoutObj
Some
(
Some
obj
,
minfo
,
argsWithoutWitnesses
)
...
...
@@ -854,7 +866,8 @@ module Patterns =
match
cases
|>
Array
.
tryFind
(
fun
ucase
->
ucase
.
Name
=
unionCaseName
)
with
|
Some
case
->
case
|
_
->
invalidArg
"unionCaseName"
(
String
.
Format
(
SR
.
GetString
(
SR
.
QmissingUnionCase
),
ty
.
FullName
,
unionCaseName
))
|
_
->
invalidArg
"unionCaseName"
(
String
.
Format
(
SR
.
GetString
(
SR
.
QmissingUnionCase
),
ty
.
FullName
,
unionCaseName
))
let
getUnionCaseInfoField
(
unionCase
:
UnionCaseInfo
,
index
)
=
let
fields
=
unionCase
.
GetFields
()
...
...
@@ -981,7 +994,8 @@ module Patterns =
invalidArg
"args"
(
SR
.
GetString
(
SR
.
QincorrectNumArgs
))
List
.
iter2
(
fun
(
p
:
ParameterInfo
)
a
->
checkTypesWeakSR
p
.
ParameterType
(
typeOf
a
)
"args"
(
SR
.
GetString
(
SR
.
QtmmInvalidParam
)))
(
fun
(
p
:
ParameterInfo
)
a
->
checkTypesWeakSR
p
.
ParameterType
(
typeOf
a
)
"args"
(
SR
.
GetString
(
SR
.
QtmmInvalidParam
)))
(
paramInfos
|>
Array
.
toList
)
args
// todo: shouldn't this be "strong" type check? sometimes?
...
...
@@ -1140,7 +1154,8 @@ module Patterns =
invalidArg
"args"
(
SR
.
GetString
(
SR
.
QincompatibleRecordLength
))
List
.
iter2
(
fun
(
minfo
:
PropertyInfo
)
a
->
checkTypesSR
minfo
.
PropertyType
(
typeOf
a
)
"recd"
(
SR
.
GetString
(
SR
.
QtmmIncorrectArgForRecord
)))
(
fun
(
minfo
:
PropertyInfo
)
a
->
checkTypesSR
minfo
.
PropertyType
(
typeOf
a
)
"recd"
(
SR
.
GetString
(
SR
.
QtmmIncorrectArgForRecord
)))
(
Array
.
toList
mems
)
args
...
...
@@ -1157,7 +1172,8 @@ module Patterns =
invalidArg
"args"
(
SR
.
GetString
(
SR
.
QunionNeedsDiffNumArgs
))
List
.
iter2
(
fun
(
minfo
:
PropertyInfo
)
a
->
checkTypesSR
minfo
.
PropertyType
(
typeOf
a
)
"sum"
(
SR
.
GetString
(
SR
.
QtmmIncorrectArgForUnion
)))
(
fun
(
minfo
:
PropertyInfo
)
a
->
checkTypesSR
minfo
.
PropertyType
(
typeOf
a
)
"sum"
(
SR
.
GetString
(
SR
.
QtmmIncorrectArgForUnion
)))
(
Array
.
toList
sargs
)
args
...
...
@@ -1894,7 +1910,10 @@ module Patterns =
// For some reason we can get 'null' returned here even when a type with the right name exists... Hence search the slow way...
match
(
assembly
.
GetTypes
()
|>
Array
.
tryFind
(
fun
a
->
a
.
FullName
=
tcName
))
with
|
Some
ty
->
ty
|
None
->
invalidArg
"tcName"
(
String
.
Format
(
SR
.
GetString
(
SR
.
QfailedToBindTypeInAssembly
),
tcName
,
assembly
.
FullName
))
|
None
->
invalidArg
"tcName"
(
String
.
Format
(
SR
.
GetString
(
SR
.
QfailedToBindTypeInAssembly
),
tcName
,
assembly
.
FullName
))
|
ty
->
ty
let
decodeNamedTy
genericType
tsR
=
...
...
@@ -2151,7 +2170,8 @@ module Patterns =
and
instModuleDefnOp
r
tyargs
_
=
match
r
with
|
StaticMethodCallOp
(
minfo
)
->
StaticMethodCallOp
(
instMeth
(
minfo
,
tyargs
))
|
StaticMethodCallWOp
(
minfo
,
minfoW
,
n
)
->
StaticMethodCallWOp
(
instMeth
(
minfo
,
tyargs
),
instMeth
(
minfoW
,
tyargs
),
n
)
|
StaticMethodCallWOp
(
minfo
,
minfoW
,
n
)
->
StaticMethodCallWOp
(
instMeth
(
minfo
,
tyargs
),
instMeth
(
minfoW
,
tyargs
),
n
)
// OK to throw away the tyargs here since this only non-generic values in modules get represented by static properties
|
x
->
x
...
...
@@ -2313,7 +2333,8 @@ module Patterns =
let
h
=
l
.[
idx
]
match
typeOf
h
with
|
expected
when
expected
<>
ty
->
invalidArg
"receivedType"
(
String
.
Format
(
SR
.
GetString
(
SR
.
QtmmRaw
),
expected
,
ty
))
|
expected
when
expected
<>
ty
->
invalidArg
"receivedType"
(
String
.
Format
(
SR
.
GetString
(
SR
.
QtmmRaw
),
expected
,
ty
))
|
_
->
h
let
rec
freeInExprAcc
bvs
acc
(
E
t
)
=
...
...
@@ -2373,7 +2394,8 @@ module Patterns =
if
v
=
bv
then
let
v2
=
new
Var
(
v
.
Name
,
v
.
Type
)
let
v2exp
=
E
(
VarTerm
v2
)
EA
(
LambdaTerm
(
v2
,
substituteInExpr
bvs
(
fun
v
->
if
v
=
bv
then
Some
v2exp
else
tmsubst
v
)
b
),
e
.
CustomAttributes
)
let
b2
=
substituteInExpr
bvs
(
fun
v
->
if
v
=
bv
then
Some
v2exp
else
tmsubst
v
)
b
EA
(
LambdaTerm
(
v2
,
b2
),
e
.
CustomAttributes
)
else
reraise
()
|
HoleTerm
_
->
e
...
...
@@ -2417,6 +2439,9 @@ module Patterns =
decodedTopResources
.
Add
((
assem
,
resourceName
),
0
)
let
isReflectedDefinitionResourceName
(
resourceName
:
string
)
=
resourceName
.
StartsWith
(
ReflectedDefinitionsResourceNameBase
,
StringComparison
.
Ordinal
)
/// Get the reflected definition at the given (always generic) instantiation
let
tryGetReflectedDefinition
(
methodBase
:
MethodBase
,
tyargs
:
Type
[]
)
=
checkNonNull
"methodBase"
methodBase
...
...
@@ -2448,7 +2473,7 @@ module Patterns =
[
for
resourceName
in
resources
do
if
resourceName
.
StartsWith
(
ReflectedDefinitionsResourceNameBase
,
StringComparison
.
Ordinal
)
isReflectedDefinitionResourceName
resourceName
&&
not
(
decodedTopResources
.
ContainsKey
((
assem
,
resourceName
)))
then
...
...
@@ -2459,7 +2484,8 @@ module Patterns =
|
x
->
x
)
|>
Array
.
tryPick
(
fun
ca
->
match
ca
with
|
:?
CompilationMappingAttribute
as
cma
when
cma
.
ResourceName
=
resourceName
->
Some
cma
|
:?
CompilationMappingAttribute
as
cma
when
cma
.
ResourceName
=
resourceName
->
Some
cma
|
_
->
None
)
let
resourceBytes
=
readToEnd
(
assem
.
GetManifestResourceStream
resourceName
)
...
...
@@ -2481,7 +2507,8 @@ module Patterns =
|>
List
.
iter
(
fun
(
resourceName
,
defns
)
->
defns
|>
List
.
iter
(
fun
(
methodBase
,
exprBuilder
)
->
reflectedDefinitionTable
.[
ReflectedDefinitionTableKey
.
GetKey
methodBase
]
<-
Entry
exprBuilder
)
reflectedDefinitionTable
.[
ReflectedDefinitionTableKey
.
GetKey
methodBase
]
<-
Entry
exprBuilder
)
decodedTopResources
.[(
assem
,
resourceName
)]
<-
0
)
// we know it's in the table now, if it's ever going to be there
...
...
@@ -2581,7 +2608,14 @@ type Expr with
checkNonNull
"methodInfoWithWitnesses"
methodInfoWithWitnesses
mkStaticMethodCallW
(
methodInfo
,
methodInfoWithWitnesses
,
List
.
length
witnesses
,
witnesses
@
arguments
)
static
member
CallWithWitnesses
(
obj
:
Expr
,
methodInfo
:
MethodInfo
,
methodInfoWithWitnesses
:
MethodInfo
,
witnesses
,
arguments
)
=
static
member
CallWithWitnesses
(
obj
:
Expr
,
methodInfo
:
MethodInfo
,
methodInfoWithWitnesses
:
MethodInfo
,
witnesses
,
arguments
)
=
checkNonNull
"methodInfo"
methodInfo
checkNonNull
"methodInfoWithWitnesses"
methodInfoWithWitnesses
mkInstanceMethodCallW
(
obj
,
methodInfo
,
methodInfoWithWitnesses
,
List
.
length
witnesses
,
witnesses
@
arguments
)
...
...
@@ -2988,7 +3022,8 @@ module ExprShape =
|
StaticMethodCallOp
minfo
,
_
->
mkStaticMethodCall
(
minfo
,
arguments
)
|
InstanceMethodCallOp
minfo
,
obj
::
args
->
mkInstanceMethodCall
(
obj
,
minfo
,
args
)
|
StaticMethodCallWOp
(
minfo
,
minfoW
,
n
),
_
->
mkStaticMethodCallW
(
minfo
,
minfoW
,
n
,
arguments
)
|
InstanceMethodCallWOp
(
minfo
,
minfoW
,
n
),
obj
::
args
->
mkInstanceMethodCallW
(
obj
,
minfo
,
minfoW
,
n
,
args
)
|
InstanceMethodCallWOp
(
minfo
,
minfoW
,
n
),
obj
::
args
->
mkInstanceMethodCallW
(
obj
,
minfo
,
minfoW
,
n
,
args
)
|
CoerceOp
ty
,
[
arg
]
->
mkCoerce
(
ty
,
arg
)
|
NewArrayOp
ty
,
_
->
mkNewArray
(
ty
,
arguments
)
|
NewDelegateOp
ty
,
[
arg
]
->
mkNewDelegate
(
ty
,
arg
)
...
...
src/FSharp.Core/reflect.fs
浏览文件 @
5b1a3ae5
...
...
@@ -83,11 +83,11 @@ module internal Impl =
let
compilePropGetterFunc
(
prop
:
PropertyInfo
)
=
let
param
=
Expression
.
Parameter
(
typeof
<
obj
>,
"param"
)
let
propExpr
=
Expression
.
Property
(
Expression
.
Convert
(
param
,
prop
.
DeclaringType
),
prop
)
let
expr
=
Expression
.
Lambda
<
Func
<
obj
,
obj
>>(
Expression
.
Convert
(
Expression
.
Property
(
Expression
.
Convert
(
param
,
prop
.
DeclaringType
),
prop
),
typeof
<
obj
>),
param
)
Expression
.
Lambda
<
Func
<
obj
,
obj
>>(
Expression
.
Convert
(
propExpr
,
typeof
<
obj
>),
param
)
expr
.
Compile
()
...
...
@@ -103,7 +103,8 @@ module internal Impl =
Expression
.
NewArrayInit
(
typeof
<
obj
>,
[
for
prop
in
props
->
Expression
.
Convert
(
Expression
.
Property
(
typedParam
,
prop
),
typeof
<
obj
>)
:>
Expression
for
prop
in
props
->
Expression
.
Convert
(
Expression
.
Property
(
typedParam
,
prop
),
typeof
<
obj
>)
:>
Expression
]
)
),
...
...
@@ -125,8 +126,8 @@ module internal Impl =
for
paramIndex
in
0
..
ctorParams
.
Length
-
1
do
let
p
=
ctorParams
.[
paramIndex
]
Expression
.
Convert
(
Expression
.
ArrayAccess
(
paramArray
,
Expression
.
Constant
paramIndex
),
p
.
ParameterType
)
:>
Expression
let
accessExpr
=
Expression
.
ArrayAccess
(
paramArray
,
Expression
.
Constant
paramIndex
)
Expression
.
Convert
(
accessExpr
,
p
.
ParameterType
)
:>
Expression
]
),
typeof
<
obj
>
...
...
@@ -149,8 +150,8 @@ module internal Impl =
for
paramIndex
in
0
..
methodParams
.
Length
-
1
do
let
p
=
methodParams
.[
paramIndex
]
Expression
.
Convert
(
Expression
.
ArrayAccess
(
paramArray
,
Expression
.
Constant
paramIndex
),
p
.
ParameterType
)
:>
Expression
let
accessExpr
=
Expression
.
ArrayAccess
(
paramArray
,
Expression
.
Constant
paramIndex
)
Expression
.
Convert
(
accessExpr
,
p
.
ParameterType
)
:>
Expression
]
),
typeof
<
obj
>
...
...
@@ -184,14 +185,20 @@ module internal Impl =
if
paramIndex
=
tupleEncField
then
constituentTuple
genericArg
elements
(
startIndex
+
paramIndex
)
:>
Expression
else
Expression
.
Convert
(
Expression
.
ArrayAccess
(
elements
,
Expression
.
Constant
(
startIndex
+
paramIndex
)),
genericArg
)
Expression
.
Convert
(
Expression
.
ArrayAccess
(
elements
,
Expression
.
Constant
(
startIndex
+
paramIndex
)),
genericArg
)
]
)
let
elements
=
Expression
.
Parameter
(
typeof
<
obj
[]
>,
"elements"
)
let
expr
=
Expression
.
Lambda
<
Func
<
obj
[]
,
obj
>>(
Expression
.
Convert
(
constituentTuple
typ
elements
0
,
typeof
<
obj
>),
elements
)
Expression
.
Lambda
<
Func
<
obj
[]
,
obj
>>(
Expression
.
Convert
(
constituentTuple
typ
elements
0
,
typeof
<
obj
>),
elements
)
expr
.
Compile
()
...
...
@@ -201,9 +208,11 @@ module internal Impl =
let
elements
=
match
getTupleElementAccessors
typ
with
// typ is a struct tuple and its elements are accessed via fields
|
Choice1Of2
(
fi
:
FieldInfo
[]
)
->
fi
|>
Array
.
map
(
fun
fi
->
Expression
.
Field
(
tuple
,
fi
),
fi
.
FieldType
)
|
Choice1Of2
(
fi
:
FieldInfo
[]
)
->
fi
|>
Array
.
map
(
fun
fi
->
Expression
.
Field
(
tuple
,
fi
),
fi
.
FieldType
)
// typ is a class tuple and its elements are accessed via properties
|
Choice2Of2
(
pi
:
PropertyInfo
[]
)
->
pi
|>
Array
.
map
(
fun
pi
->
Expression
.
Property
(
tuple
,
pi
),
pi
.
PropertyType
)
|
Choice2Of2
(
pi
:
PropertyInfo
[]
)
->
pi
|>
Array
.
map
(
fun
pi
->
Expression
.
Property
(
tuple
,
pi
),
pi
.
PropertyType
)
for
index
,
(
element
,
elementType
)
in
elements
|>
Array
.
indexed
do
if
index
=
tupleEncField
then
...
...
@@ -241,14 +250,12 @@ module internal Impl =
Expression
.
Block
(
[
outputArray
],
[
yield
Expression
.
Assign
(
outputArray
,
Expression
.
NewArrayBounds
(
typeof
<
obj
>,
Expression
.
Constant
(
outputLength
tupleEncField
typ
))
)
:>
Expression
let
arrayBounds
=
Expression
.
NewArrayBounds
(
typeof
<
obj
>,
Expression
.
Constant
(
outputLength
tupleEncField
typ
))
Expression
.
Assign
(
outputArray
,
arrayBounds
)
:>
Expression
yield
!
writeTupleIntoArray
typ
(
Expression
.
Convert
(
param
,
typ
))
outputArray
0
yield
outputArray
:>
Expression
outputArray
:>
Expression
]
),
param
...
...
@@ -263,7 +270,9 @@ module internal Impl =
match
attrs
with
|
null
|
[||]
->
None
|
[|
res
|]
->
let
a
=
(
res
:?>
CompilationMappingAttribute
)
in
Some
(
a
.
SourceConstructFlags
,
a
.
SequenceNumber
,
a
.
VariantNumber
)
|
[|
res
|]
->
let
a
=
(
res
:?>
CompilationMappingAttribute
)
Some
(
a
.
SourceConstructFlags
,
a
.
SequenceNumber
,
a
.
VariantNumber
)
|
_
->
invalidOp
(
SR
.
GetString
(
SR
.
multipleCompilationMappings
))
let
findCompilationMappingAttribute
(
attrs
:
obj
[]
)
=
...
...
@@ -287,12 +296,24 @@ module internal Impl =
let
flags
=
match
args
.
Count
with
|
1
->
((
let
x
=
args
.[
0
]
in
x
.
Value
:?>
SourceConstructFlags
),
0
,
0
)
|
2
->
((
let
x
=
args
.[
0
]
in
x
.
Value
:?>
SourceConstructFlags
),
(
let
x
=
args
.[
1
]
in
x
.
Value
:?>
int
),
0
)
|
1
->
let
arg0
=
args
.[
0
]
let
v0
=
arg0
.
Value
:?>
SourceConstructFlags
(
v0
,
0
,
0
)
|
2
->
let
arg0
=
args
.[
0
]
let
v0
=
arg0
.
Value
:?>
SourceConstructFlags
let
arg1
=
args
.[
1
]
let
v1
=
arg1
.
Value
:?>
int
(
v0
,
v1
,
0
)
|
3
->
((
let
x
=
args
.[
0
]
in
x
.
Value
:?>
SourceConstructFlags
),
(
let
x
=
args
.[
1
]
in
x
.
Value
:?>
int
),
(
let
x
=
args
.[
2
]
in
x
.
Value
:?>
int
))
let
arg0
=
args
.[
0
]
let
v0
=
arg0
.
Value
:?>
SourceConstructFlags
let
arg1
=
args
.[
1
]
let
v1
=
arg1
.
Value
:?>
int
let
arg2
=
args
.[
2
]
let
v2
=
arg2
.
Value
:?>
int
(
v0
,
v1
,
v2
)
|
_
->
(
enum
0
,
0
,
0
)
res
<-
Some
flags
...
...
@@ -579,12 +600,16 @@ module internal Impl =
"New"
+
constrname
match
typ
.
GetMethod
(
methname
,
BindingFlags
.
Static
|||
bindingFlags
)
with
|
null
->
invalidOp
(
String
.
Format
(
SR
.
GetString
(
SR
.
constructorForUnionCaseNotFound
),
methname
))
|
null
->
let
msg
=
String
.
Format
(
SR
.
GetString
(
SR
.
constructorForUnionCaseNotFound
),
methname
)
invalidOp
msg
|
meth
->
meth
let
getUnionCaseConstructor
(
typ
:
Type
,
tag
:
int
,
bindingFlags
)
=
let
meth
=
getUnionCaseConstructorMethod
(
typ
,
tag
,
bindingFlags
)
(
fun
args
->
meth
.
Invoke
(
null
,
BindingFlags
.
Static
|||
BindingFlags
.
InvokeMethod
|||
bindingFlags
,
null
,
args
,
null
))
(
fun
args
->
meth
.
Invoke
(
null
,
BindingFlags
.
Static
|||
BindingFlags
.
InvokeMethod
|||
bindingFlags
,
null
,
args
,
null
))
let
getUnionCaseConstructorCompiled
(
typ
:
Type
,
tag
:
int
,
bindingFlags
)
=
let
meth
=
getUnionCaseConstructorMethod
(
typ
,
tag
,
bindingFlags
)
...
...
@@ -595,9 +620,11 @@ module internal Impl =
if
not
(
isUnionType
(
unionType
,
bindingFlags
))
then
if
isUnionType
(
unionType
,
bindingFlags
|||
BindingFlags
.
NonPublic
)
then
invalidArg
"unionType"
(
String
.
Format
(
SR
.
GetString
(
SR
.
privateUnionType
),
unionType
.
FullName
))
let
msg
=
String
.
Format
(
SR
.
GetString
(
SR
.
privateUnionType
),
unionType
.
FullName
)
invalidArg
"unionType"
msg
else
invalidArg
"unionType"
(
String
.
Format
(
SR
.
GetString
(
SR
.
notAUnionType
),
unionType
.
FullName
))
let
msg
=
String
.
Format
(
SR
.
GetString
(
SR
.
notAUnionType
),
unionType
.
FullName
)
invalidArg
"unionType"
msg
//-----------------------------------------------------------------
// TUPLE DECOMPILATION
...
...
@@ -718,7 +745,8 @@ module internal Impl =
let
rec
getTupleTypeInfo
(
typ
:
Type
)
=
if
not
(
isTupleType
typ
)
then
invalidArg
"typ"
(
String
.
Format
(
SR
.
GetString
(
SR
.
notATupleType
),
typ
.
FullName
))
let
msg
=
String
.
Format
(
SR
.
GetString
(
SR
.
notATupleType
),
typ
.
FullName
)
invalidArg
"typ"
msg
let
tyargs
=
typ
.
GetGenericArguments
()
...
...
@@ -801,20 +829,35 @@ module internal Impl =
let
fields
=
typ
.
GetFields
(
instanceFieldFlags
|||
BindingFlags
.
Public
)
|>
orderTupleFields
typ
.
GetConstructor
(
BindingFlags
.
Public
|||
BindingFlags
.
Instance
,
null
,
fields
|>
Array
.
map
(
fun
fi
->
fi
.
FieldType
),
null
)
typ
.
GetConstructor
(
BindingFlags
.
Public
|||
BindingFlags
.
Instance
,
null
,
fields
|>
Array
.
map
(
fun
fi
->
fi
.
FieldType
),
null
)
else
let
props
=
typ
.
GetProperties
()
|>
orderTupleProperties
typ
.
GetConstructor
(
BindingFlags
.
Public
|||
BindingFlags
.
Instance
,
null
,
props
|>
Array
.
map
(
fun
p
->
p
.
PropertyType
),
null
)
typ
.
GetConstructor
(
BindingFlags
.
Public
|||
BindingFlags
.
Instance
,
null
,
props
|>
Array
.
map
(
fun
p
->
p
.
PropertyType
),
null
)
match
ctor
with
|
null
->
raise
(
ArgumentException
(
String
.
Format
(
SR
.
GetString
(
SR
.
invalidTupleTypeConstructorNotDefined
),
typ
.
FullName
)))
|
null
->
let
msg
=
String
.
Format
(
SR
.
GetString
(
SR
.
invalidTupleTypeConstructorNotDefined
))
raise
(
ArgumentException
(
msg
,
typ
.
FullName
))
|
_
->
()
ctor
let
getTupleCtor
(
typ
:
Type
)
=
let
ctor
=
getTupleConstructorMethod
typ
(
fun
(
args
:
obj
[]
)
->
ctor
.
Invoke
(
BindingFlags
.
InvokeMethod
|||
BindingFlags
.
Instance
|||
BindingFlags
.
Public
,
null
,
args
,
null
))
(
fun
(
args
:
obj
[]
)
->
ctor
.
Invoke
(
BindingFlags
.
InvokeMethod
|||
BindingFlags
.
Instance
|||
BindingFlags
.
Public
,
null
,
args
,
null
))
let
getTupleElementAccessors
(
typ
:
Type
)
=
if
typ
.
IsValueType
then
...
...
@@ -869,7 +912,10 @@ module internal Impl =
let
getTupleReaderInfo
(
typ
:
Type
,
index
:
int
)
=
if
index
<
0
then
invalidArg
"index"
(
String
.
Format
(
SR
.
GetString
(
SR
.
tupleIndexOutOfRange
),
typ
.
FullName
,
index
.
ToString
()
))
let
msg
=
String
.
Format
(
SR
.
GetString
(
SR
.
tupleIndexOutOfRange
),
typ
.
FullName
,
index
.
ToString
()
)
invalidArg
"index"
msg
let
get
index
=
if
typ
.
IsValueType
then
...
...
@@ -878,7 +924,10 @@ module internal Impl =
|>
orderTupleProperties
if
index
>=
props
.
Length
then
invalidArg
"index"
(
String
.
Format
(
SR
.
GetString
(
SR
.
tupleIndexOutOfRange
),
typ
.
FullName
,
index
.
ToString
()
))
let
msg
=
String
.
Format
(
SR
.
GetString
(
SR
.
tupleIndexOutOfRange
),
typ
.
FullName
,
index
.
ToString
()
)
invalidArg
"index"
msg
props
.[
index
]
else
...
...
@@ -887,7 +936,10 @@ module internal Impl =
|>
orderTupleProperties
if
index
>=
props
.
Length
then
invalidArg
"index"
(
String
.
Format
(
SR
.
GetString
(
SR
.
tupleIndexOutOfRange
),
typ
.
FullName
,
index
.
ToString
()
))
let
msg
=
String
.
Format
(
SR
.
GetString
(
SR
.
tupleIndexOutOfRange
),
typ
.
FullName
,
index
.
ToString
()
)
invalidArg
"index"
msg
props
.[
index
]
...
...
@@ -944,19 +996,28 @@ module internal Impl =
let
props
=
fieldPropsOfRecordType
(
typ
,
bindingFlags
)
let
ctor
=
typ
.
GetConstructor
(
BindingFlags
.
Instance
|||
bindingFlags
,
null
,
props
|>
Array
.
map
(
fun
p
->
p
.
PropertyType
),
null
)
typ
.
GetConstructor
(
BindingFlags
.
Instance
|||
bindingFlags
,
null
,
props
|>
Array
.
map
(
fun
p
->
p
.
PropertyType
),
null
)
match
ctor
with
|
null
->
raise
<|
ArgumentException
(
String
.
Format
(
SR
.
GetString
(
SR
.
invalidRecordTypeConstructorNotDefined
),
typ
.
FullName
))
let
msg
=
String
.
Format
(
SR
.
GetString
(
SR
.
invalidRecordTypeConstructorNotDefined
),
typ
.
FullName
)
raise
(
ArgumentException
(
msg
))
|
_
->
()
ctor
let
getRecordConstructor
(
typ
:
Type
,
bindingFlags
)
=
let
ctor
=
getRecordConstructorMethod
(
typ
,
bindingFlags
)
(
fun
(
args
:
obj
[]
)
->
ctor
.
Invoke
(
BindingFlags
.
InvokeMethod
|||
BindingFlags
.
Instance
|||
bindingFlags
,
null
,
args
,
null
))
(
fun
(
args
:
obj
[]
)
->
ctor
.
Invoke
(
BindingFlags
.
InvokeMethod
|||
BindingFlags
.
Instance
|||
bindingFlags
,
null
,
args
,
null
))
let
getRecordConstructorCompiled
(
typ
:
Type
,
bindingFlags
)
=
let
ctor
=
getRecordConstructorMethod
(
typ
,
bindingFlags
)
...
...
@@ -1001,24 +1062,31 @@ module internal Impl =
let
checkExnType
(
exceptionType
,
bindingFlags
)
=
if
not
(
isExceptionRepr
(
exceptionType
,
bindingFlags
))
then
if
isExceptionRepr
(
exceptionType
,
bindingFlags
|||
BindingFlags
.
NonPublic
)
then
invalidArg
"exceptionType"
(
String
.
Format
(
SR
.
GetString
(
SR
.
privateExceptionType
),
exceptionType
.
FullName
))
let
msg
=
String
.
Format
(
SR
.
GetString
(
SR
.
privateExceptionType
),
exceptionType
.
FullName
)
invalidArg
"exceptionType"
msg
else
invalidArg
"exceptionType"
(
String
.
Format
(
SR
.
GetString
(
SR
.
notAnExceptionType
),
exceptionType
.
FullName
))
let
msg
=
String
.
Format
(
SR
.
GetString
(
SR
.
notAnExceptionType
),
exceptionType
.
FullName
)
invalidArg
"exceptionType"
msg
let
checkRecordType
(
argName
,
recordType
,
bindingFlags
)
=
checkNonNull
argName
recordType
if
not
(
isRecordType
(
recordType
,
bindingFlags
))
then
if
isRecordType
(
recordType
,
bindingFlags
|||
BindingFlags
.
NonPublic
)
then
invalidArg
argName
(
String
.
Format
(
SR
.
GetString
(
SR
.
privateRecordType
),
recordType
.
FullName
))
let
msg
=
String
.
Format
(
SR
.
GetString
(
SR
.
privateRecordType
),
recordType
.
FullName
)
invalidArg
argName
msg
else
invalidArg
argName
(
String
.
Format
(
SR
.
GetString
(
SR
.
notARecordType
),
recordType
.
FullName
))
let
msg
=
String
.
Format
(
SR
.
GetString
(
SR
.
notARecordType
),
recordType
.
FullName
)
invalidArg
argName
msg
let
checkTupleType
(
argName
,
(
tupleType
:
Type
))
=
checkNonNull
argName
tupleType
if
not
(
isTupleType
tupleType
)
then
invalidArg
argName
(
String
.
Format
(
SR
.
GetString
(
SR
.
notATupleType
),
tupleType
.
FullName
))
let
msg
=
String
.
Format
(
SR
.
GetString
(
SR
.
notATupleType
),
tupleType
.
FullName
)
invalidArg
argName
msg
[<
Sealed
>]
type
UnionCaseInfo
(
typ
:
System
.
Type
,
tag
:
int
)
=
...
...
@@ -1228,7 +1296,8 @@ type FSharpValue =
checkNonNull
"functionType"
functionType
if
not
(
isFunctionType
functionType
)
then
invalidArg
"functionType"
(
String
.
Format
(
SR
.
GetString
(
SR
.
notAFunctionType
),
functionType
.
FullName
))
let
msg
=
String
.
Format
(
SR
.
GetString
(
SR
.
notAFunctionType
),
functionType
.
FullName
)
invalidArg
"functionType"
msg
checkNonNull
"implementation"
implementation
let
domain
,
range
=
getFunctionTypeInfo
functionType
...
...
@@ -1248,7 +1317,8 @@ type FSharpValue =
let
typ
=
tuple
.
GetType
()
if
not
(
isTupleType
typ
)
then
invalidArg
"tuple"
(
String
.
Format
(
SR
.
GetString
(
SR
.
notATupleType
),
tuple
.
GetType
()
.
FullName
))
let
msg
=
String
.
Format
(
SR
.
GetString
(
SR
.
notATupleType
),
tuple
.
GetType
()
.
FullName
)
invalidArg
"tuple"
msg
getTupleReader
typ
tuple
...
...
@@ -1257,12 +1327,16 @@ type FSharpValue =
let
typ
=
tuple
.
GetType
()
if
not
(
isTupleType
typ
)
then
invalidArg
"tuple"
(
String
.
Format
(
SR
.
GetString
(
SR
.
notATupleType
),
tuple
.
GetType
()
.
FullName
))
let
msg
=
String
.
Format
(
SR
.
GetString
(
SR
.
notATupleType
),
tuple
.
GetType
()
.
FullName
)
invalidArg
"tuple"
msg
let
fields
=
getTupleReader
typ
tuple
if
index
<
0
||
index
>=
fields
.
Length
then
invalidArg
"index"
(
String
.
Format
(
SR
.
GetString
(
SR
.
tupleIndexOutOfRange
),
tuple
.
GetType
()
.
FullName
,
index
.
ToString
()
))
let
msg
=
String
.
Format
(
SR
.
GetString
(
SR
.
tupleIndexOutOfRange
),
tuple
.
GetType
()
.
FullName
,
index
.
ToString
()
)
invalidArg
"index"
msg
fields
.[
index
]
...
...
@@ -1421,7 +1495,11 @@ module FSharpReflectionExtensions =
let
bindingFlags
=
getBindingFlags
allowAccessToPrivateRepresentation
FSharpValue
.
PreComputeUnionTagReader
(
unionType
,
bindingFlags
)
static
member
PreComputeUnionReader
(
unionCase
:
UnionCaseInfo
,
?
allowAccessToPrivateRepresentation
)
:
(
obj
->
obj
[]
)
=
static
member
PreComputeUnionReader
(
unionCase
:
UnionCaseInfo
,
?
allowAccessToPrivateRepresentation
)
:
(
obj
->
obj
[]
)
=
let
bindingFlags
=
getBindingFlags
allowAccessToPrivateRepresentation
FSharpValue
.
PreComputeUnionReader
(
unionCase
,
bindingFlags
)
...
...
src/FSharp.Core/resumable.fs
浏览文件 @
5b1a3ae5
...
...
@@ -92,12 +92,15 @@ module StateMachineHelpers =
[<
MethodImpl
(
MethodImplOptions
.
NoInlining
)>]
let
__
resumableEntry
()
:
int
option
=
failwith
"__resumableEntry should always be guarded by __useResumableCode and only used in valid state machine implementations"
failwith
"__resumableEntry should always be guarded by __useResumableCode and only used in valid state machine implementations"
[<
MethodImpl
(
MethodImplOptions
.
NoInlining
)>]
let
__
resumeAt
<
'
T
>
(
programLabel
:
int
)
:
'
T
=
ignore
programLabel
failwith
"__resumeAt should always be guarded by __useResumableCode and only used in valid state machine implementations"
failwith
"__resumeAt should always be guarded by __useResumableCode and only used in valid state machine implementations"
[<
MethodImpl
(
MethodImplOptions
.
NoInlining
)>]
let
__
stateMachine
<
'
Data
,
'
Result
>
...
...
@@ -108,7 +111,9 @@ module StateMachineHelpers =
ignore
moveNextMethod
ignore
setStateMachineMethod
ignore
afterCode
failwith
"__stateMachine should always be guarded by __useResumableCode and only used in valid state machine implementations"
failwith
"__stateMachine should always be guarded by __useResumableCode and only used in valid state machine implementations"
module
ResumableCode
=
...
...
@@ -167,13 +172,21 @@ module ResumableCode =
else
CombineDynamic
(&
sm
,
code1
,
code2
))
let
rec
WhileDynamic
(
sm
:
byref
<
ResumableStateMachine
<
'
Data
>>,
condition
:
unit
->
bool
,
body
:
ResumableCode
<
'
Data
,
unit
>)
:
bool
=
let
rec
WhileDynamic
(
sm
:
byref
<
ResumableStateMachine
<
'
Data
>>,
condition
:
unit
->
bool
,
body
:
ResumableCode
<
'
Data
,
unit
>
)
:
bool
=
if
condition
()
then
if
body
.
Invoke
(&
sm
)
then
WhileDynamic
(&
sm
,
condition
,
body
)
else
let
rf
=
GetResumptionFunc
&
sm
sm
.
ResumptionDynamicInfo
.
ResumptionFunc
<-
(
ResumptionFunc
<
'
Data
>(
fun
sm
->
WhileBodyDynamicAux
(&
sm
,
condition
,
body
,
rf
)))
sm
.
ResumptionDynamicInfo
.
ResumptionFunc
<-
(
ResumptionFunc
<
'
Data
>(
fun
sm
->
WhileBodyDynamicAux
(&
sm
,
condition
,
body
,
rf
)))
false
else
true
...
...
@@ -189,11 +202,18 @@ module ResumableCode =
WhileDynamic
(&
sm
,
condition
,
body
)
else
let
rf
=
GetResumptionFunc
&
sm
sm
.
ResumptionDynamicInfo
.
ResumptionFunc
<-
(
ResumptionFunc
<
'
Data
>(
fun
sm
->
WhileBodyDynamicAux
(&
sm
,
condition
,
body
,
rf
)))
sm
.
ResumptionDynamicInfo
.
ResumptionFunc
<-
(
ResumptionFunc
<
'
Data
>(
fun
sm
->
WhileBodyDynamicAux
(&
sm
,
condition
,
body
,
rf
)))
false
/// Builds a step that executes the body while the condition predicate is true.
let
inline
While
([<
InlineIfLambda
>]
condition
:
unit
->
bool
,
body
:
ResumableCode
<
'
Data
,
unit
>)
:
ResumableCode
<
'
Data
,
unit
>
=
let
inline
While
(
[<
InlineIfLambda
>]
condition
:
unit
->
bool
,
body
:
ResumableCode
<
'
Data
,
unit
>
)
:
ResumableCode
<
'
Data
,
unit
>
=
ResumableCode
<
'
Data
,
unit
>(
fun
sm
->
if
__
useResumableCode
then
//-- RESUMABLE CODE START
...
...
@@ -225,7 +245,8 @@ module ResumableCode =
let
rf
=
GetResumptionFunc
&
sm
sm
.
ResumptionDynamicInfo
.
ResumptionFunc
<-
(
ResumptionFunc
<
'
Data
>(
fun
sm
->
TryWithDynamic
(&
sm
,
ResumableCode
<
'
Data
,
'
T
>(
fun
sm
->
rf
.
Invoke
(&
sm
)),
handler
)))
(
ResumptionFunc
<
'
Data
>(
fun
sm
->
TryWithDynamic
(&
sm
,
ResumableCode
<
'
Data
,
'
T
>(
fun
sm
->
rf
.
Invoke
(&
sm
)),
handler
)))
false
with
exn
->
...
...
@@ -233,7 +254,11 @@ module ResumableCode =
/// Wraps a step in a try/with. This catches exceptions both in the evaluation of the function
/// to retrieve the step, and in the continuation of the step (if any).
let
inline
TryWith
(
body
:
ResumableCode
<
'
Data
,
'
T
>,
catch
:
exn
->
ResumableCode
<
'
Data
,
'
T
>)
:
ResumableCode
<
'
Data
,
'
T
>
=
let
inline
TryWith
(
body
:
ResumableCode
<
'
Data
,
'
T
>,
catch
:
exn
->
ResumableCode
<
'
Data
,
'
T
>
)
:
ResumableCode
<
'
Data
,
'
T
>
=
ResumableCode
<
'
Data
,
'
T
>(
fun
sm
->
if
__
useResumableCode
then
//-- RESUMABLE CODE START
...
...
@@ -260,7 +285,12 @@ module ResumableCode =
else
TryWithDynamic
(&
sm
,
body
,
catch
))
let
rec
TryFinallyCompensateDynamic
(
sm
:
byref
<
ResumableStateMachine
<
'
Data
>>,
mf
:
ResumptionFunc
<
'
Data
>,
savedExn
:
exn
option
)
:
bool
=
let
rec
TryFinallyCompensateDynamic
(
sm
:
byref
<
ResumableStateMachine
<
'
Data
>>,
mf
:
ResumptionFunc
<
'
Data
>,
savedExn
:
exn
option
)
:
bool
=
let
mutable
fin
=
false
fin
<-
mf
.
Invoke
(&
sm
)
...
...
@@ -271,7 +301,10 @@ module ResumableCode =
|
Some
exn
->
raise
exn
else
let
rf
=
GetResumptionFunc
&
sm
sm
.
ResumptionDynamicInfo
.
ResumptionFunc
<-
(
ResumptionFunc
<
'
Data
>(
fun
sm
->
TryFinallyCompensateDynamic
(&
sm
,
rf
,
savedExn
)))
sm
.
ResumptionDynamicInfo
.
ResumptionFunc
<-
(
ResumptionFunc
<
'
Data
>(
fun
sm
->
TryFinallyCompensateDynamic
(&
sm
,
rf
,
savedExn
)))
false
let
rec
TryFinallyAsyncDynamic
...
...
@@ -328,7 +361,11 @@ module ResumableCode =
/// Wraps a step in a try/finally. This catches exceptions both in the evaluation of the function
/// to retrieve the step, and in the continuation of the step (if any).
let
inline
TryFinallyAsync
(
body
:
ResumableCode
<
'
Data
,
'
T
>,
compensation
:
ResumableCode
<
'
Data
,
unit
>)
:
ResumableCode
<
'
Data
,
'
T
>
=
let
inline
TryFinallyAsync
(
body
:
ResumableCode
<
'
Data
,
'
T
>,
compensation
:
ResumableCode
<
'
Data
,
unit
>
)
:
ResumableCode
<
'
Data
,
'
T
>
=
ResumableCode
<
'
Data
,
'
T
>(
fun
sm
->
if
__
useResumableCode
then
//-- RESUMABLE CODE START
...
...
src/FSharp.Core/seq.fs
浏览文件 @
5b1a3ae5
...
...
@@ -443,7 +443,8 @@ module Internal =
static
member
Bind
(
g
:
Generator
<
'
T
>,
cont
)
=
match
g
with
|
:?
GenerateThen
<
'
T
>
as
g
->
GenerateThen
<_>.
Bind
(
g
.
Generator
,
(
fun
()
->
GenerateThen
<_>.
Bind
(
g
.
Cont
()
,
cont
)))
|
:?
GenerateThen
<
'
T
>
as
g
->
GenerateThen
<_>.
Bind
(
g
.
Generator
,
(
fun
()
->
GenerateThen
<_>.
Bind
(
g
.
Cont
()
,
cont
)))
|
g
->
(
new
GenerateThen
<
'
T
>(
g
,
cont
)
:>
Generator
<
'
T
>)
let
bindG
g
cont
=
...
...
@@ -1290,7 +1291,10 @@ module Seq =
// Wrap a StructBox around all keys in case the key type is itself a type using null as a representation
let
groupByRefType
(
keyf
:
'
T
->
'
Key
)
(
seq
:
seq
<
'
T
>)
=
seq
|>
groupByImpl
RuntimeHelpers
.
StructBox
<
'
Key
>.
Comparer
(
fun
t
->
RuntimeHelpers
.
StructBox
(
keyf
t
))
(
fun
sb
->
sb
.
Value
)
|>
groupByImpl
RuntimeHelpers
.
StructBox
<
'
Key
>.
Comparer
(
fun
t
->
RuntimeHelpers
.
StructBox
(
keyf
t
))
(
fun
sb
->
sb
.
Value
)
[<
CompiledName
(
"GroupBy"
)>]
let
groupBy
(
projection
:
'
T
->
'
Key
)
(
source
:
seq
<
'
T
>)
=
...
...
@@ -1402,7 +1406,10 @@ module Seq =
// Wrap a StructBox around all keys in case the key type is itself a type using null as a representation
let
countByRefType
(
keyf
:
'
T
->
'
Key
)
(
seq
:
seq
<
'
T
>)
=
seq
|>
countByImpl
RuntimeHelpers
.
StructBox
<
'
Key
>.
Comparer
(
fun
t
->
RuntimeHelpers
.
StructBox
(
keyf
t
))
(
fun
sb
->
sb
.
Value
)
|>
countByImpl
RuntimeHelpers
.
StructBox
<
'
Key
>.
Comparer
(
fun
t
->
RuntimeHelpers
.
StructBox
(
keyf
t
))
(
fun
sb
->
sb
.
Value
)
[<
CompiledName
(
"CountBy"
)>]
let
countBy
(
projection
:
'
T
->
'
Key
)
(
source
:
seq
<
'
T
>)
=
...
...
src/FSharp.Core/set.fs
浏览文件 @
5b1a3ae5
...
...
@@ -571,13 +571,21 @@ module internal SetTree =
compareStacks
comparer
(
empty
::
SetTree
x1
.
Key
::
t1
)
l2
else
let
x1n
=
asNode
x1
compareStacks
comparer
(
x1n
.
Left
::
(
SetTreeNode
(
x1n
.
Key
,
empty
,
x1n
.
Right
,
0
)
:>
SetTree
<
'
T
>)
::
t1
)
l2
compareStacks
comparer
(
x1n
.
Left
::
(
SetTreeNode
(
x1n
.
Key
,
empty
,
x1n
.
Right
,
0
)
:>
SetTree
<
'
T
>)
::
t1
)
l2
|
_,
(
x2
::
t2
)
when
not
(
isEmpty
x2
)
->
if
x2
.
Height
=
1
then
compareStacks
comparer
l1
(
empty
::
SetTree
x2
.
Key
::
t2
)
else
let
x2n
=
asNode
x2
compareStacks
comparer
l1
(
x2n
.
Left
::
(
SetTreeNode
(
x2n
.
Key
,
empty
,
x2n
.
Right
,
0
)
:>
SetTree
<
'
T
>)
::
t2
)
compareStacks
comparer
l1
(
x2n
.
Left
::
(
SetTreeNode
(
x2n
.
Key
,
empty
,
x2n
.
Right
,
0
)
:>
SetTree
<
'
T
>)
::
t2
)
|
_
->
unexpectedstateInSetTreeCompareStacks
()
match
l1
,
l2
with
...
...
src/FSharp.Core/tasks.fs
浏览文件 @
5b1a3ae5
...
...
@@ -58,21 +58,37 @@ type TaskBuilderBase() =
/// Chains together a step with its following step.
/// Note that this requires that the first step has no result.
/// This prevents constructs like `task { return 1; return 2; }`.
member
inline
_.
Combine
(
task1
:
TaskCode
<
'
TOverall
,
unit
>,
task2
:
TaskCode
<
'
TOverall
,
'
T
>)
:
TaskCode
<
'
TOverall
,
'
T
>
=
member
inline
_.
Combine
(
task1
:
TaskCode
<
'
TOverall
,
unit
>,
task2
:
TaskCode
<
'
TOverall
,
'
T
>
)
:
TaskCode
<
'
TOverall
,
'
T
>
=
ResumableCode
.
Combine
(
task1
,
task2
)
/// Builds a step that executes the body while the condition predicate is true.
member
inline
_.
While
([<
InlineIfLambda
>]
condition
:
unit
->
bool
,
body
:
TaskCode
<
'
TOverall
,
unit
>)
:
TaskCode
<
'
TOverall
,
unit
>
=
member
inline
_.
While
(
[<
InlineIfLambda
>]
condition
:
unit
->
bool
,
body
:
TaskCode
<
'
TOverall
,
unit
>
)
:
TaskCode
<
'
TOverall
,
unit
>
=
ResumableCode
.
While
(
condition
,
body
)
/// Wraps a step in a try/with. This catches exceptions both in the evaluation of the function
/// to retrieve the step, and in the continuation of the step (if any).
member
inline
_.
TryWith
(
body
:
TaskCode
<
'
TOverall
,
'
T
>,
catch
:
exn
->
TaskCode
<
'
TOverall
,
'
T
>)
:
TaskCode
<
'
TOverall
,
'
T
>
=
member
inline
_.
TryWith
(
body
:
TaskCode
<
'
TOverall
,
'
T
>,
catch
:
exn
->
TaskCode
<
'
TOverall
,
'
T
>
)
:
TaskCode
<
'
TOverall
,
'
T
>
=
ResumableCode
.
TryWith
(
body
,
catch
)
/// Wraps a step in a try/finally. This catches exceptions both in the evaluation of the function
/// to retrieve the step, and in the continuation of the step (if any).
member
inline
_.
TryFinally
(
body
:
TaskCode
<
'
TOverall
,
'
T
>,
[<
InlineIfLambda
>]
compensation
:
unit
->
unit
)
:
TaskCode
<
'
TOverall
,
'
T
>
=
member
inline
_.
TryFinally
(
body
:
TaskCode
<
'
TOverall
,
'
T
>,
[<
InlineIfLambda
>]
compensation
:
unit
->
unit
)
:
TaskCode
<
'
TOverall
,
'
T
>
=
ResumableCode
.
TryFinally
(
body
,
ResumableCode
<_,
_>(
fun
_
sm
->
...
...
@@ -84,7 +100,11 @@ type TaskBuilderBase() =
ResumableCode
.
For
(
sequence
,
body
)
#
if
NETSTANDARD2_1
member
inline
internal
this
.
TryFinallyAsync
(
body
:
TaskCode
<
'
TOverall
,
'
T
>,
compensation
:
unit
->
ValueTask
)
:
TaskCode
<
'
TOverall
,
'
T
>
=
member
inline
internal
this
.
TryFinallyAsync
(
body
:
TaskCode
<
'
TOverall
,
'
T
>,
compensation
:
unit
->
ValueTask
)
:
TaskCode
<
'
TOverall
,
'
T
>
=
ResumableCode
.
TryFinallyAsync
(
body
,
ResumableCode
<_,
_>(
fun
sm
->
...
...
@@ -344,7 +364,11 @@ module LowPriority =
sm
.
Data
.
MethodBuilder
.
AwaitUnsafeOnCompleted
(&
awaiter
,
&
sm
)
false
else
TaskBuilderBase
.
BindDynamic
<
^
TaskLike
,
'
TResult1
,
'
TResult2
,
^
Awaiter
,
'
TOverall
>(&
sm
,
task
,
continuation
)
TaskBuilderBase
.
BindDynamic
<
^
TaskLike
,
'
TResult1
,
'
TResult2
,
^
Awaiter
,
'
TOverall
>(
&
sm
,
task
,
continuation
)
//-- RESUMABLE CODE END
)
...
...
@@ -370,7 +394,12 @@ module HighPriority =
// High priority extensions
type
TaskBuilderBase
with
static
member
BindDynamic
(
sm
:
byref
<_>,
task
:
Task
<
'
TResult1
>,
continuation
:
(
'
TResult1
->
TaskCode
<
'
TOverall
,
'
TResult2
>))
:
bool
=
static
member
BindDynamic
(
sm
:
byref
<_>,
task
:
Task
<
'
TResult1
>,
continuation
:
(
'
TResult1
->
TaskCode
<
'
TOverall
,
'
TResult2
>)
)
:
bool
=
let
mutable
awaiter
=
task
.
GetAwaiter
()
let
cont
=
...
...
麦壳饼
@mysticboy
mentioned in commit
9f8b28f4
·
7月 25, 2022
mentioned in commit
9f8b28f4
mentioned in commit 9f8b28f40a5647d80d445c01b1e6564bc7b46217
开关提交列表
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录