From 8e2b13446604bf3a41e527b248be634df6400d50 Mon Sep 17 00:00:00 2001 From: nojaf Date: Mon, 3 Jul 2023 15:39:03 +0200 Subject: [PATCH 1/4] Add inline keyword to get member. --- src/Compiler/Checking/NicePrint.fs | 5 ++++- src/Compiler/Facilities/TextLayoutRender.fs | 1 + src/Compiler/Facilities/TextLayoutRender.fsi | 1 + src/Compiler/Utilities/sformat.fs | 1 + src/Compiler/Utilities/sformat.fsi | 1 + .../TestCasesForGenerationRoundTrip/inline-member.fsx | 6 ++++++ 6 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 tests/FSharp.Compiler.ComponentTests/Signatures/TestCasesForGenerationRoundTrip/inline-member.fsx diff --git a/src/Compiler/Checking/NicePrint.fs b/src/Compiler/Checking/NicePrint.fs index 50a2ca2b44d..6cfc6ee4246 100644 --- a/src/Compiler/Checking/NicePrint.fs +++ b/src/Compiler/Checking/NicePrint.fs @@ -1287,7 +1287,10 @@ module PrintTastMemberOrVals = let prettyLayoutOfMemberShortOption denv typarInst (v: Val) short = let vref = mkLocalValRef v let membInfo = Option.get vref.MemberInfo - let stat = layoutMemberFlags membInfo.MemberFlags + let stat = + match vref.InlineInfo with + | ValInline.Always -> layoutMemberFlags membInfo.MemberFlags ^^ WordL.keywordInline + | _ -> layoutMemberFlags membInfo.MemberFlags let _tps, argInfos, retTy, _ = GetTypeOfMemberInFSharpForm denv.g vref if short then diff --git a/src/Compiler/Facilities/TextLayoutRender.fs b/src/Compiler/Facilities/TextLayoutRender.fs index e9b7cd8637a..0768e699df1 100644 --- a/src/Compiler/Facilities/TextLayoutRender.fs +++ b/src/Compiler/Facilities/TextLayoutRender.fs @@ -59,6 +59,7 @@ module WordL = let keywordAbstract = wordL TaggedText.keywordAbstract let keywordOverride = wordL TaggedText.keywordOverride let keywordEnum = wordL TaggedText.keywordEnum + let keywordInline = wordL TaggedText.keywordInline module LeftL = let leftParen = leftL TaggedText.leftParen diff --git a/src/Compiler/Facilities/TextLayoutRender.fsi b/src/Compiler/Facilities/TextLayoutRender.fsi index 88dc9921e72..48f874a0d3b 100644 --- a/src/Compiler/Facilities/TextLayoutRender.fsi +++ b/src/Compiler/Facilities/TextLayoutRender.fsi @@ -98,6 +98,7 @@ module internal WordL = val keywordAbstract: Layout val keywordOverride: Layout val keywordEnum: Layout + val keywordInline: Layout module internal LeftL = val leftParen: Layout diff --git a/src/Compiler/Utilities/sformat.fs b/src/Compiler/Utilities/sformat.fs index 5d42dae0b45..7281286dfd6 100644 --- a/src/Compiler/Utilities/sformat.fs +++ b/src/Compiler/Utilities/sformat.fs @@ -252,6 +252,7 @@ module TaggedText = let rightBracketAngle = tagPunctuation ">]" let star = tagOperator "*" let keywordNew = tagKeyword "new" + let keywordInline = tagKeyword "inline" #endif [] diff --git a/src/Compiler/Utilities/sformat.fsi b/src/Compiler/Utilities/sformat.fsi index 2707838552e..e4e8412495f 100644 --- a/src/Compiler/Utilities/sformat.fsi +++ b/src/Compiler/Utilities/sformat.fsi @@ -210,6 +210,7 @@ module internal TaggedText = val internal rightBracketAngle: TaggedText val internal star: TaggedText val internal keywordNew: TaggedText + val internal keywordInline: TaggedText type internal IEnvironment = /// Return to the layout-generation diff --git a/tests/FSharp.Compiler.ComponentTests/Signatures/TestCasesForGenerationRoundTrip/inline-member.fsx b/tests/FSharp.Compiler.ComponentTests/Signatures/TestCasesForGenerationRoundTrip/inline-member.fsx new file mode 100644 index 00000000000..7ee18e11fc5 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Signatures/TestCasesForGenerationRoundTrip/inline-member.fsx @@ -0,0 +1,6 @@ +module Meh + +type Foo() = + member inline this.Item + with get (i:int,j: char) : string = "" + and set (i:int,j: char) (x:string) = printfn "%i %c" i j From d76c0b68a8c8b80c2f0844557819b42571efeab0 Mon Sep 17 00:00:00 2001 From: nojaf Date: Mon, 3 Jul 2023 16:14:20 +0200 Subject: [PATCH 2/4] Consider two members when TotalArgCount differ for getter and setter. --- src/Compiler/Checking/NicePrint.fs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/Compiler/Checking/NicePrint.fs b/src/Compiler/Checking/NicePrint.fs index 6cfc6ee4246..d44b7db2791 100644 --- a/src/Compiler/Checking/NicePrint.fs +++ b/src/Compiler/Checking/NicePrint.fs @@ -1820,22 +1820,25 @@ module TastDefinitionPrinting = | Some gRef, Some sRef -> isPublicAccess gRef.Accessibility && isPublicAccess sRef.Accessibility | _ -> false - let (|MixedAccessibilityGetterAndSetter|_|) (pinfo: PropInfo) = + let (|DifferentGetterAndSetter|_|) (pinfo: PropInfo) = if not (pinfo.HasGetter && pinfo.HasSetter) then None else match pinfo.GetterMethod.ArbitraryValRef, pinfo.SetterMethod.ArbitraryValRef with | Some getValRef, Some setValRef -> - if getValRef.Accessibility = setValRef.Accessibility then - None - else + if getValRef.Accessibility <> setValRef.Accessibility then Some (getValRef, setValRef) + else + match getValRef.ValReprInfo, setValRef.ValReprInfo with + | Some getValReprInfo, Some setValReprInfo when getValReprInfo.TotalArgCount <> setValReprInfo.TotalArgCount -> + Some (getValRef, setValRef) + | _ -> None | _ -> None match pinfo.ArbitraryValRef with | Some vref -> match pinfo with - | MixedAccessibilityGetterAndSetter(getValRef, setValRef) -> + | DifferentGetterAndSetter(getValRef, setValRef) -> let getSuffix = if pinfo.IsIndexer then emptyL else wordL (tagKeyword "with") ^^ wordL (tagText "get") [ PrintTastMemberOrVals.prettyLayoutOfValOrMemberNoInst denv infoReader getValRef ^^ getSuffix From cfbfb164f14290378723fd4ac17f679610ea4b97 Mon Sep 17 00:00:00 2001 From: nojaf Date: Mon, 3 Jul 2023 16:54:43 +0200 Subject: [PATCH 3/4] Reuse existing inline helper. --- src/Compiler/Checking/NicePrint.fs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Compiler/Checking/NicePrint.fs b/src/Compiler/Checking/NicePrint.fs index d44b7db2791..c4e42cf7fe6 100644 --- a/src/Compiler/Checking/NicePrint.fs +++ b/src/Compiler/Checking/NicePrint.fs @@ -1255,7 +1255,7 @@ module PrintTastMemberOrVals = let mkInlineL denv (v: Val) nameL = if v.MustInline && not denv.suppressInlineKeyword then - wordL (tagKeyword "inline") ++ nameL + WordL.keywordInline ++ nameL else nameL @@ -1287,10 +1287,7 @@ module PrintTastMemberOrVals = let prettyLayoutOfMemberShortOption denv typarInst (v: Val) short = let vref = mkLocalValRef v let membInfo = Option.get vref.MemberInfo - let stat = - match vref.InlineInfo with - | ValInline.Always -> layoutMemberFlags membInfo.MemberFlags ^^ WordL.keywordInline - | _ -> layoutMemberFlags membInfo.MemberFlags + let stat = layoutMemberFlags membInfo.MemberFlags let _tps, argInfos, retTy, _ = GetTypeOfMemberInFSharpForm denv.g vref if short then @@ -1329,6 +1326,7 @@ module PrintTastMemberOrVals = // use error recovery because intellisense on an incomplete file will show this errorR(Error(FSComp.SR.tastInvalidFormForPropertyGetter(), vref.Id.idRange)) let nameL = layoutMemberName denv vref [] argInfos tagProperty vref.DisplayNameCoreMangled + let nameL = if short then nameL else mkInlineL denv vref.Deref nameL let resL = if short then nameL --- (WordL.keywordWith ^^ WordL.keywordGet) else stat --- nameL --- (WordL.keywordWith ^^ WordL.keywordGet) @@ -1345,6 +1343,7 @@ module PrintTastMemberOrVals = else tauL --- (WordL.keywordWith ^^ WordL.keywordGet) else let nameL = layoutMemberName denv vref niceMethodTypars argInfos tagProperty vref.DisplayNameCoreMangled + let nameL = if short then nameL else mkInlineL denv vref.Deref nameL stat --- ((nameL |> addColonL) ^^ (if isNil argInfos then tauL else tauL --- (WordL.keywordWith ^^ WordL.keywordGet))) prettyTyparInst, resL @@ -1353,6 +1352,7 @@ module PrintTastMemberOrVals = // use error recovery because intellisense on an incomplete file will show this errorR(Error(FSComp.SR.tastInvalidFormForPropertySetter(), vref.Id.idRange)) let nameL = layoutMemberName denv vref [] argInfos tagProperty vref.DisplayNameCoreMangled + let nameL = if short then nameL else mkInlineL denv vref.Deref nameL let resL = stat --- nameL --- (WordL.keywordWith ^^ WordL.keywordSet) emptyTyparInst, resL else @@ -1364,6 +1364,7 @@ module PrintTastMemberOrVals = (tauL --- (WordL.keywordWith ^^ WordL.keywordSet)) else let nameL = layoutMemberName denv vref niceMethodTypars curriedArgInfos tagProperty vref.DisplayNameCoreMangled + let nameL = if short then nameL else mkInlineL denv vref.Deref nameL stat --- ((nameL |> addColonL) ^^ (tauL --- (WordL.keywordWith ^^ WordL.keywordSet))) prettyTyparInst, resL From 8454819589774fc2dda182c0d40f51c13e02f0c3 Mon Sep 17 00:00:00 2001 From: nojaf Date: Mon, 3 Jul 2023 17:20:07 +0200 Subject: [PATCH 4/4] Slightly better detection of indexed getter. --- src/Compiler/Checking/NicePrint.fs | 7 ++-- .../Signatures/TypeTests.fs | 36 +++++++++++++++++++ 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/Compiler/Checking/NicePrint.fs b/src/Compiler/Checking/NicePrint.fs index c4e42cf7fe6..f4e69616c9b 100644 --- a/src/Compiler/Checking/NicePrint.fs +++ b/src/Compiler/Checking/NicePrint.fs @@ -1830,9 +1830,10 @@ module TastDefinitionPrinting = if getValRef.Accessibility <> setValRef.Accessibility then Some (getValRef, setValRef) else - match getValRef.ValReprInfo, setValRef.ValReprInfo with - | Some getValReprInfo, Some setValReprInfo when getValReprInfo.TotalArgCount <> setValReprInfo.TotalArgCount -> - Some (getValRef, setValRef) + match getValRef.ValReprInfo with + | Some getValReprInfo when + // Getter has an index parameter + getValReprInfo.TotalArgCount > 1 -> Some (getValRef, setValRef) | _ -> None | _ -> None diff --git a/tests/FSharp.Compiler.ComponentTests/Signatures/TypeTests.fs b/tests/FSharp.Compiler.ComponentTests/Signatures/TypeTests.fs index cd637449500..daf7e0d89f7 100644 --- a/tests/FSharp.Compiler.ComponentTests/Signatures/TypeTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Signatures/TypeTests.fs @@ -184,3 +184,39 @@ type EConverter () = let valText = mfv.GetValSignatureText(canReadSymbolUse.DisplayContext, canReadSymbolUse.Range).Value Assert.Equal("override CanRead: bool", valText) | _ -> () + +[] +let ``Property with unit getter and regular setter`` () = + FSharp """ +module Lib + +type Foo = + member x.Bar with get () = 5 and set v = ignore v +""" + |> printSignatures + |> should equal + """ +module Lib + +type Foo = + + member Bar: int with get, set""" + +[] +let ``Property with indexed getter and regular setter`` () = + FSharp """ +module Lib + +type Foo = + member x.Bar with get (a:int) = 5 and set (a:int) v = ignore v +""" + |> printSignatures + |> should equal + """ +module Lib + +type Foo = + + member Bar: a: int -> int with get + + member Bar: a: int -> int with set"""