Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
dotNET Platform
fsharp
提交
e8fc5fb1
F
fsharp
项目概览
dotNET Platform
/
fsharp
10 个月 前同步成功
通知
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,发现更多精彩内容 >>
未验证
提交
e8fc5fb1
编写于
5月 20, 2022
作者:
D
Don Syme
提交者:
GitHub
5月 20, 2022
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
remove whitespace prior to formatting (#13172)
上级
cccdfb1d
变更
2
展开全部
隐藏空白更改
内联
并排
Showing
2 changed file
with
1140 addition
and
1137 deletion
+1140
-1137
src/Compiler/Utilities/TaggedCollections.fs
src/Compiler/Utilities/TaggedCollections.fs
+1001
-1001
src/Compiler/Utilities/sr.fs
src/Compiler/Utilities/sr.fs
+139
-136
未找到文件。
src/Compiler/Utilities/TaggedCollections.fs
浏览文件 @
e8fc5fb1
此差异已折叠。
点击以展开。
src/Compiler/Utilities/sr.fs
浏览文件 @
e8fc5fb1
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
namespace
FSharp
.
Compiler
open
Microsoft
.
FSharp
.
Core
open
Microsoft
.
FSharp
.
Collections
open
Microsoft
.
FSharp
.
Reflection
module
internal
SR
=
let
private
resources
=
lazy
(
System
.
Resources
.
ResourceManager
(
"fsstrings"
,
System
.
Reflection
.
Assembly
.
GetExecutingAssembly
()
))
open
Microsoft
.
FSharp
.
Core
open
Microsoft
.
FSharp
.
Collections
open
Microsoft
.
FSharp
.
Reflection
let
GetString
(
name
:
string
)
=
let
s
=
resources
.
Force
()
.
GetString
(
name
,
System
.
Globalization
.
CultureInfo
.
CurrentUICulture
)
module
internal
SR
=
let
private
resources
=
lazy
(
System
.
Resources
.
ResourceManager
(
"fsstrings"
,
System
.
Reflection
.
Assembly
.
GetExecutingAssembly
()
))
let
GetString
(
name
:
string
)
=
let
s
=
resources
.
Force
()
.
GetString
(
name
,
System
.
Globalization
.
CultureInfo
.
CurrentUICulture
)
#
if
DEBUG
if
null
=
s
then
System
.
Diagnostics
.
Debug
.
Assert
(
false
,
sprintf
"**RESOURCE ERROR**: Resource token %s does not exist!"
name
)
if
null
=
s
then
System
.
Diagnostics
.
Debug
.
Assert
(
false
,
sprintf
"**RESOURCE ERROR**: Resource token %s does not exist!"
name
)
#
endif
s
s
module
internal
DiagnosticMessage
=
module
internal
DiagnosticMessage
=
open
Microsoft
.
FSharp
.
Core
.
LanguagePrimitives
.
IntrinsicOperators
open
Microsoft
.
FSharp
.
Core
.
LanguagePrimitives
.
IntrinsicOperators
let
mkFunctionValue
(
tys
:
System
.
Type
[]
)
(
impl
:
obj
->
obj
)
=
FSharpValue
.
MakeFunction
(
FSharpType
.
MakeFunctionType
(
tys
[
0
],
tys
[
1
]),
impl
)
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
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
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
->
failwith
"destFunTy: not a function type"
|
b
->
destFunTy
b
let
rec
destFunTy
(
ty
:
System
.
Type
)
=
if
isFunctionType
ty
then
ty
,
ty
.
GetGenericArguments
()
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
capture1
(
fmt
:
string
)
i
args
ty
(
go
:
obj
list
->
System
.
Type
->
int
->
obj
)
:
obj
=
match
fmt
[
i
]
with
|
'
%
'
->
go
args
ty
(
i
+
1
)
|
'
d'
|
'
f'
|
'
s'
->
buildFunctionForOneArgPat
ty
(
fun
rty
n
->
go
(
n
::
args
)
rty
(
i
+
1
))
|
_
->
failwith
"bad format specifier"
// newlines and tabs get converted to strings when read from a resource file
// this will preserve their original intention
let
postProcessString
(
s
:
string
)
=
s
.
Replace
(
"
\\
n"
,
"
\n
"
).
Replace
(
"
\\
t"
,
"
\t
"
)
let
createMessageString
(
messageString
:
string
)
(
fmt
:
Printf
.
StringFormat
<
'
T
>)
:
'
T
=
let
fmt
=
fmt
.
Value
// here, we use the actual error string, as opposed to the one stored as fmt
let
len
=
fmt
.
Length
/// Function to capture the arguments and then run.
let
rec
capture
args
ty
i
=
if
i
>=
len
||
(
fmt
[
i
]
=
'
%
'
&&
i
+
1
>=
len
)
then
let
b
=
System
.
Text
.
StringBuilder
()
b
.
AppendFormat
(
messageString
,
(
Array
.
ofList
(
List
.
rev
args
)))
|>
ignore
box
(
b
.
ToString
()
)
// REVIEW: For these purposes, this should be a nop, but I'm leaving it
// in case we ever decide to support labels for the error format string
// E.g., "<name>%s<foo>%d"
elif
System
.
Char
.
IsSurrogatePair
(
fmt
,
i
)
then
capture
args
ty
(
i
+
2
)
else
match
ty
.
BaseType
with
|
null
->
failwith
"destFunTy: not a function type"
|
b
->
destFunTy
b
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
capture1
(
fmt
:
string
)
i
args
ty
(
go
:
obj
list
->
System
.
Type
->
int
->
obj
)
:
obj
=
match
fmt
[
i
]
with
|
'
%
'
->
go
args
ty
(
i
+
1
)
|
'
d'
|
'
f'
|
'
s'
->
buildFunctionForOneArgPat
ty
(
fun
rty
n
->
go
(
n
::
args
)
rty
(
i
+
1
))
|
_
->
failwith
"bad format specifier"
// newlines and tabs get converted to strings when read from a resource file
// this will preserve their original intention
let
postProcessString
(
s
:
string
)
=
s
.
Replace
(
"
\\
n"
,
"
\n
"
).
Replace
(
"
\\
t"
,
"
\t
"
)
let
createMessageString
(
messageString
:
string
)
(
fmt
:
Printf
.
StringFormat
<
'
T
>)
:
'
T
=
let
fmt
=
fmt
.
Value
// here, we use the actual error string, as opposed to the one stored as fmt
let
len
=
fmt
.
Length
/// Function to capture the arguments and then run.
let
rec
capture
args
ty
i
=
if
i
>=
len
||
(
fmt
[
i
]
=
'
%
'
&&
i
+
1
>=
len
)
then
let
b
=
System
.
Text
.
StringBuilder
()
b
.
AppendFormat
(
messageString
,
(
Array
.
ofList
(
List
.
rev
args
)))
|>
ignore
box
(
b
.
ToString
()
)
// REVIEW: For these purposes, this should be a nop, but I'm leaving it
// in case we ever decide to support labels for the error format string
// E.g., "<name>%s<foo>%d"
elif
System
.
Char
.
IsSurrogatePair
(
fmt
,
i
)
then
capture
args
ty
(
i
+
2
)
else
match
fmt
[
i
]
with
|
'
%
'
->
let
i
=
i
+
1
capture1
fmt
i
args
ty
capture
|
_
->
capture
args
ty
(
i
+
1
)
(
unbox
(
capture
[]
typeof
<
'
T
>
0
)
:
'
T
)
type
ResourceString
<
'
T
>(
fmtString
:
string
,
fmt
:
Printf
.
StringFormat
<
'
T
>)
=
member
_.
Format
=
createMessageString
fmtString
fmt
let
DeclareResourceString
(
messageID
:
string
,
fmt
:
Printf
.
StringFormat
<
'
T
>)
=
let
mutable
messageString
=
SR
.
GetString
(
messageID
)
match
fmt
[
i
]
with
|
'
%
'
->
let
i
=
i
+
1
capture1
fmt
i
args
ty
capture
|
_
->
capture
args
ty
(
i
+
1
)
(
unbox
(
capture
[]
typeof
<
'
T
>
0
)
:
'
T
)
type
ResourceString
<
'
T
>(
fmtString
:
string
,
fmt
:
Printf
.
StringFormat
<
'
T
>)
=
member
_.
Format
=
createMessageString
fmtString
fmt
let
DeclareResourceString
(
messageID
:
string
,
fmt
:
Printf
.
StringFormat
<
'
T
>)
=
let
mutable
messageString
=
SR
.
GetString
(
messageID
)
#
if
DEBUG
// validate that the message string exists
let
fmtString
=
fmt
.
Value
// validate that the message string exists
let
fmtString
=
fmt
.
Value
if
null
=
messageString
then
System
.
Diagnostics
.
Debug
.
Assert
(
false
,
sprintf
"**DECLARED MESSAGE ERROR** String resource %s does not exist"
messageID
)
messageString
<-
""
// validate the formatting specifiers
let
countFormatHoles
(
s
:
string
)
=
// remove escaped format holes
let
s
=
s
.
Replace
(
"{{"
,
""
).
Replace
(
"}}"
,
""
)
let
len
=
s
.
Length
-
2
let
mutable
pos
=
0
let
mutable
nHoles
=
0
let
mutable
order
=
Set
.
empty
<
int
>
while
pos
<
len
do
if
s
[
pos
]
=
'
{
'
then
let
mutable
pos'
=
pos
+
1
while
System
.
Char
.
IsNumber
(
s
[
pos'
])
do
pos'
<-
pos'
+
1
if
pos'
>
pos
+
1
&&
s
[
pos'
]
=
'
}
'
then
nHoles
<-
nHoles
+
1
let
ordern
=
int
s
[(
pos
+
1
)
..
(
pos'
-
1
)]
order
<-
order
.
Add
(
ordern
)
pos
<-
pos'
pos
<-
pos
+
1
// the sort should be unnecessary, but better safe than sorry
nHoles
,
Set
.
toList
order
|>
List
.
sortDescending
let
countFormatPlaceholders
(
s
:
string
)
=
// strip any escaped % characters - yes, this will fail if given %%%...
let
s
=
s
.
Replace
(
"%%"
,
""
)
if
null
=
messageString
then
System
.
Diagnostics
.
Debug
.
Assert
(
false
,
sprintf
"**DECLARED MESSAGE ERROR** String resource %s does not exist"
messageID
)
messageString
<-
""
// validate the formatting specifiers
let
countFormatHoles
(
s
:
string
)
=
// remove escaped format holes
let
s
=
s
.
Replace
(
"{{"
,
""
).
Replace
(
"}}"
,
""
)
let
len
=
s
.
Length
-
2
if
s
=
""
then
0
else
let
len
=
s
.
Length
-
1
let
mutable
pos
=
0
let
mutable
nHoles
=
0
let
mutable
order
=
Set
.
empty
<
int
>
let
mutable
nFmt
=
0
while
pos
<
len
do
if
s
[
pos
]
=
'
{
'
then
let
mutable
pos'
=
pos
+
1
while
System
.
Char
.
IsNumber
(
s
[
pos'
])
do
pos'
<-
pos'
+
1
if
pos'
>
pos
+
1
&&
s
[
pos'
]
=
'
}
'
then
nHoles
<-
nHoles
+
1
let
ordern
=
int
s
[(
pos
+
1
)
..
(
pos'
-
1
)]
order
<-
order
.
Add
(
ordern
)
pos
<-
pos'
pos
<-
pos
+
1
// the sort should be unnecessary, but better safe than sorry
nHoles
,
Set
.
toList
order
|>
List
.
sortDescending
let
countFormatPlaceholders
(
s
:
string
)
=
// strip any escaped % characters - yes, this will fail if given %%%...
let
s
=
s
.
Replace
(
"%%"
,
""
)
if
s
=
""
then
0
else
let
len
=
s
.
Length
-
1
let
mutable
pos
=
0
let
mutable
nFmt
=
0
if
s
[
pos
]
=
'
%
'
&&
(
s
[
pos
+
1
]
=
'
d'
||
s
[
pos
+
1
]
=
'
s'
||
s
[
pos
+
1
]
=
'
f'
)
then
nFmt
<-
nFmt
+
1
pos
<-
pos
+
2
;
else
pos
<-
pos
+
1
;
nFmt
while
pos
<
len
do
if
s
[
pos
]
=
'
%
'
&&
(
s
[
pos
+
1
]
=
'
d'
||
s
[
pos
+
1
]
=
'
s'
||
s
[
pos
+
1
]
=
'
f'
)
then
nFmt
<-
nFmt
+
1
pos
<-
pos
+
2
;
else
pos
<-
pos
+
1
;
nFmt
let
nHoles
,
holes
=
countFormatHoles
messageString
let
nPlaceholders
=
countFormatPlaceholders
fmtString
let
nHoles
,
holes
=
countFormatHoles
messageString
let
nPlaceholders
=
countFormatPlaceholders
fmtString
// first, verify that the number of holes in the message string does not exceed the
// largest hole reference
if
holes
<>
[]
&&
holes
[
0
]
>
nHoles
-
1
then
System
.
Diagnostics
.
Debug
.
Assert
(
false
,
sprintf
"**DECLARED MESSAGE ERROR** Message string %s contains %d holes, but references hole %d"
messageID
nHoles
holes
[
0
])
// first, verify that the number of holes in the message string does not exceed the
// largest hole reference
if
holes
<>
[]
&&
holes
[
0
]
>
nHoles
-
1
then
System
.
Diagnostics
.
Debug
.
Assert
(
false
,
sprintf
"**DECLARED MESSAGE ERROR** Message string %s contains %d holes, but references hole %d"
messageID
nHoles
holes
[
0
])
// next, verify that the number of format placeholders is the same as the number of holes
if
nHoles
<>
nPlaceholders
then
System
.
Diagnostics
.
Debug
.
Assert
(
false
,
sprintf
"**DECLARED MESSAGE ERROR** Message string %s contains %d holes, but its format specifier contains %d placeholders"
messageID
nHoles
nPlaceholders
)
#
endif
messageString
<-
postProcessString
messageString
new
ResourceString
<
'
T
>(
messageString
,
fmt
)
// next, verify that the number of format placeholders is the same as the number of holes
if
nHoles
<>
nPlaceholders
then
System
.
Diagnostics
.
Debug
.
Assert
(
false
,
sprintf
"**DECLARED MESSAGE ERROR** Message string %s contains %d holes, but its format specifier contains %d placeholders"
messageID
nHoles
nPlaceholders
)
#
endif
messageString
<-
postProcessString
messageString
new
ResourceString
<
'
T
>(
messageString
,
fmt
)
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录