Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit7755f90

Browse files
colinbullKevinRansom
authored andcommitted
Implement ToString on unions (RFC FS-1022) (dotnet#1589)
* Initial implementation of ToString for unions* Added basic tests for union ToString and override* Changed type representation of the PrintFormat function* Adding union definitions to test fsi file* Updated in fsharpqa IL to include new generated ToString method on DUs* Furthur fixing up of IL for qa tests* Yet again fixing up of IL for qa tests* Removed unneeded comments* More IL test fixes* Incorrect class name in Equals09 IL* Tidying up comment removal ILxGen.fs* fix tests and an accessibility bug by using "%+A" instead of "%A"* use member info instead of override info because of a certain test* fix il tests
1 parent0c26a52 commit7755f90

File tree

34 files changed

+589
-3
lines changed

34 files changed

+589
-3
lines changed

‎src/fsharp/IlxGen.fs‎

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6437,7 +6437,47 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon:Tycon) =
64376437
yield{ ilMethodDefwith Access=reprAccess}
64386438
|_->
64396439
()
6440-
6440+
| TUnionRepr_when(not<| tycon.HasMember cenv.g"ToString"[])->
6441+
match(eenv.valsInScope.TryFind cenv.g.sprintf_vref.Deref,
6442+
eenv.valsInScope.TryFind cenv.g.new_format_vref.Deref)with
6443+
| Some(Lazy(Method(_,_,sprintfMethSpec,_,_,_))), Some(Lazy(Method(_,_,newFormatMethSpec,_,_,_)))->
6444+
// The type returned by the 'sprintf' call
6445+
letfuncTy= EraseClosures.mkILFuncTy cenv.g.ilxPubCloEnv ilThisTy cenv.g.ilg.typ_String
6446+
// Give the instantiation of the printf format object, i.e. a Format`5 object compatible with StringFormat<ilThisTy>
6447+
letnewFormatMethSpec= mkILMethSpec(newFormatMethSpec.MethodRef,AsObject,
6448+
[// 'T -> string'
6449+
funcTy
6450+
// rest follow from 'StringFormat<T>'
6451+
GenUnitTy cenv eenv m
6452+
cenv.g.ilg.typ_String
6453+
cenv.g.ilg.typ_String
6454+
ilThisTy],[])
6455+
// Instantiate with our own type
6456+
letsprintfMethSpec= mkILMethSpec(sprintfMethSpec.MethodRef,AsObject,[],[funcTy])
6457+
// Here's the body of the method. Call printf, then invoke the function it returns
6458+
letcallInstrs= EraseClosures.mkCallFunc cenv.g.ilxPubCloEnv(fun _->0us) eenv.tyenv.Count Normalcall(Apps_app(ilThisTy, Apps_done cenv.g.ilg.typ_String))
6459+
letilMethodDef= mkILNonGenericVirtualMethod("ToString",ILMemberAccess.Public,[],
6460+
mkILReturn cenv.g.ilg.typ_String,
6461+
mkMethodBody
6462+
(true,[],2,
6463+
nonBranchingInstrsToCode
6464+
([// load the hardwired format string
6465+
yield I_ldstr"%+A"
6466+
// make the printf format object
6467+
yield mkNormalNewobj newFormatMethSpec
6468+
// call sprintf
6469+
yield mkNormalCall sprintfMethSpec
6470+
// call the function returned by sprintf
6471+
yield mkLdarg0
6472+
if ilThisTy.Boxity= ILBoxity.AsValuethen
6473+
yield mkNormalLdobj ilThisTy]@
6474+
callInstrs),
6475+
None))
6476+
letmdef={ ilMethodDefwith CustomAttrs= mkILCustomAttrs[ cenv.g.CompilerGeneratedAttribute]}
6477+
yield mdef
6478+
| None,_->()
6479+
|_,None->()
6480+
|_->()
64416481
|_->()]
64426482

64436483
letilMethods= methodDefs@ augmentOverrideMethodDefs@ abstractMethodDefs

‎src/fsharp/TastOps.fs‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7686,10 +7686,22 @@ type Entity with
76867686
argInfos.Length=1&&
76877687
List.lengthsEqAndForall2(typeEquiv g)(List.map fst(List.head argInfos)) argtys&&
76887688
membInfo.MemberFlags.IsOverrideOrExplicitImpl)
7689+
7690+
membertycon.HasMember g nm argtys=
7691+
tycon.TypeContents.tcaug_adhoc
7692+
|> NameMultiMap.find nm
7693+
|> List.exists(fun vref->
7694+
match vref.MemberInfowith
7695+
| None->false
7696+
|_->letargInfos= ArgInfosOfMember g vref
7697+
argInfos.Length=1&&
7698+
List.lengthsEqAndForall2(typeEquiv g)(List.map fst(List.head argInfos)) argtys)
7699+
76897700

76907701
typeEntityRefwith
76917702
membertcref.HasInterface g ty= tcref.Deref.HasInterface g ty
76927703
membertcref.HasOverride g nm argtys= tcref.Deref.HasOverride g nm argtys
7704+
membertcref.HasMember g nm argtys= tcref.Deref.HasMember g nm argtys
76937705

76947706
letmkFastForLoop g(spLet,m,idv:Val,start,dir,finish,body)=
76957707
letdir=if dirthen FSharpForLoopUpelse FSharpForLoopDown

‎src/fsharp/TastOps.fsi‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1400,10 +1400,12 @@ val IsGenericValWithGenericContraints: TcGlobals -> Val -> bool
14001400
typeEntitywith
14011401
memberHasInterface:TcGlobals->TType->bool
14021402
memberHasOverride:TcGlobals->string->TType list->bool
1403+
memberHasMember:TcGlobals->string->TType list->bool
14031404

14041405
type EntityRef with
14051406
memberHasInterface:TcGlobals->TType->bool
14061407
memberHasOverride:TcGlobals->string->TType list->bool
1408+
memberHasMember:TcGlobals->string->TType list->bool
14071409

14081410
val(|AttribBitwiseOrExpr|_|):TcGlobals->Expr->(Expr* Expr)option
14091411
val(|EnumExpr|_|):TcGlobals->Expr->Expr option

‎tests/fsharp/core/libtest/test.fsx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5217,8 +5217,8 @@ module Repro_3947 = begin
52175217
do check"Bug3947.Internal%+A"(sprintf"%+A (%+A)" ITA(ITB2))"ITA (ITB 2)"
52185218

52195219
// The follow are not very useful outputs, but adding regression tests to pick up any changes...
5220-
do check"Bug3947.Internal%A.ITA"true(letstr=sprintf"%A" ITAin str.EndsWith("InternalType+_ITA"))
5221-
do check"Bug3947.Internal%A.ITB"true(letstr=sprintf"%A"(ITB2)in str.EndsWith("InternalType+ITB"))
5220+
do check"Bug3947.Internal%A.ITA"(sprintf"%A" ITA)"ITA"
5221+
do check"Bug3947.Internal%A.ITB"(sprintf"%A"(ITB2))"ITB 2"
52225222
end
52235223

52245224

‎tests/fsharp/core/members/basics/test.fs‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1104,6 +1104,28 @@ module OverrideIComparableOnUnionTest = begin
11041104
do testc s4 s2
11051105
end
11061106

1107+
moduleToStringOnUnionTest=begin
1108+
1109+
typeMyUnion= Aofstring| B
1110+
1111+
leta1= A"FOO"
1112+
do test"union-tostring-def"(a1.ToString()="A\"FOO\"")
1113+
do test"union-sprintfO-def"((sprintf"%O" a1)="A\"FOO\"")
1114+
1115+
end
1116+
1117+
moduleToStringOnUnionTestOverride=begin
1118+
1119+
typeMyUnion= Aofstring| B
1120+
with
1121+
overridex.ToString()="MyUnion"
1122+
1123+
leta1= A"FOO"
1124+
do test"union-tostring-with-override"(a1.ToString()="MyUnion")
1125+
do test"union-sprintfO-with-override"((sprintf"%O" a1)="MyUnion")
1126+
1127+
end
1128+
11071129
moduleOverrideIStructuralComparableOnUnionTest=begin
11081130

11091131
[<CustomEquality; CustomComparison>]

‎tests/fsharp/core/members/basics/test.fsi‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,3 +129,13 @@ module UnionTypeTest: begin
129129
end
130130

131131
end
132+
133+
module ToStringOnUnionTest: begin
134+
type MyUnion= Aofstring| B
135+
136+
end
137+
138+
moduleToStringOnUnionTestOverride:begin
139+
typeMyUnion= Aofstring| B
140+
141+
end

‎tests/fsharpqa/Source/CodeGen/EmittedIL/CCtorDUWithMember/CCtorDUWithMember01.il.bsl‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,20 @@
235235
IL_0015: ret
236236
}// end of method C::__DebugDisplay
237237

238+
.method public strict virtual instance string
239+
ToString() cil managed
240+
{
241+
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor()= (01000000 )
242+
// Code size 22 (0x16)
243+
.maxstack8
244+
IL_0000: ldstr"%+A"
245+
IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5<class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<class CCtorDUWithMember01a/C,string>,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,class CCtorDUWithMember01a/C>::.ctor(string)
246+
IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString<class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<class CCtorDUWithMember01a/C,string>>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4<!!0,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string>)
247+
IL_000f: ldarg.0
248+
IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<class CCtorDUWithMember01a/C,string>::Invoke(!0)
249+
IL_0015: ret
250+
}// end of method C::ToString
251+
238252
.method public hidebysig virtual final
239253
instance int32 CompareTo(class CCtorDUWithMember01a/C obj) cil managed
240254
{

‎tests/fsharpqa/Source/CodeGen/EmittedIL/CCtorDUWithMember/cctorduwithmember01.il.netfx4.bsl‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,20 @@
238238
IL_0015: ret
239239
}// end of method C::__DebugDisplay
240240

241+
.method public strict virtual instance string
242+
ToString() cil managed
243+
{
244+
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor()= (01000000 )
245+
// Code size 22 (0x16)
246+
.maxstack8
247+
IL_0000: ldstr"%+A"
248+
IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5<class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<class CCtorDUWithMember01a/C,string>,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,class CCtorDUWithMember01a/C>::.ctor(string)
249+
IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString<class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<class CCtorDUWithMember01a/C,string>>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4<!!0,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string>)
250+
IL_000f: ldarg.0
251+
IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<class CCtorDUWithMember01a/C,string>::Invoke(!0)
252+
IL_0015: ret
253+
}// end of method C::ToString
254+
241255
.method public hidebysig virtual final
242256
instance int32 CompareTo(class CCtorDUWithMember01a/C obj) cil managed
243257
{

‎tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/EqualsOnUnions01.il.bsl‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,20 @@
321321
IL_0015: ret
322322
}// end of method U::__DebugDisplay
323323

324+
.method public strict virtual instance string
325+
ToString() cil managed
326+
{
327+
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor()= (01000000 )
328+
// Code size 22 (0x16)
329+
.maxstack8
330+
IL_0000: ldstr"%+A"
331+
IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5<class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<class EqualsOnUnions01/U,string>,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,string>::.ctor(string)
332+
IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString<class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<class EqualsOnUnions01/U,string>>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4<!!0,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string>)
333+
IL_000f: ldarg.0
334+
IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<class EqualsOnUnions01/U,string>::Invoke(!0)
335+
IL_0015: ret
336+
}// end of method U::ToString
337+
324338
.method public hidebysig virtual final
325339
instance int32 CompareTo(class EqualsOnUnions01/U obj) cil managed
326340
{

‎tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/EqualsOnUnions01.il.netfx4.bsl‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,20 @@
321321
IL_0015: ret
322322
}// end of method U::__DebugDisplay
323323

324+
.method public strict virtual instance string
325+
ToString() cil managed
326+
{
327+
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor()= (01000000 )
328+
// Code size 22 (0x16)
329+
.maxstack8
330+
IL_0000: ldstr"%+A"
331+
IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5<class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<class EqualsOnUnions01/U,string>,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,class EqualsOnUnions01/U>::.ctor(string)
332+
IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString<class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<class EqualsOnUnions01/U,string>>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4<!!0,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string>)
333+
IL_000f: ldarg.0
334+
IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<class EqualsOnUnions01/U,string>::Invoke(!0)
335+
IL_0015: ret
336+
}// end of method U::ToString
337+
324338
.method public hidebysig virtual final
325339
instance int32 CompareTo(class EqualsOnUnions01/U obj) cil managed
326340
{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp