diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj index 19175fd7f05..99af61de377 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj @@ -101,6 +101,9 @@ SyntaxTree\MemberFlagTests.fs + + SyntaxTree\MemberTests.fs + SyntaxTree\ComputationExpressionTests.fs diff --git a/tests/service/SyntaxTreeTests/MemberTests.fs b/tests/service/SyntaxTreeTests/MemberTests.fs new file mode 100644 index 00000000000..084af4bff85 --- /dev/null +++ b/tests/service/SyntaxTreeTests/MemberTests.fs @@ -0,0 +1,225 @@ +module FSharp.Compiler.Service.Tests.SyntaxTreeTests.MemberTests + +open FSharp.Compiler.Service.Tests.Common +open FSharp.Compiler.Syntax +open FSharp.Compiler.SyntaxTrivia +open NUnit.Framework + +[] +let ``SynTypeDefn with AutoProperty contains the range of the equals sign`` () = + let parseResults = + getParseResults + """ +/// mutable class with auto-properties +type Person(name : string, age : int) = + /// Full name + member val Name = name with get, set +""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.Types( + typeDefns = [ SynTypeDefn(typeRepr = SynTypeDefnRepr.ObjectModel(members = [_ ; SynMemberDefn.AutoProperty(equalsRange = mEquals)])) ] + ) + ]) ])) -> + assertRange (5, 20) (5, 21) mEquals + | _ -> Assert.Fail "Could not get valid AST" + +[] +let ``SynTypeDefn with AutoProperty contains the range of the with keyword`` () = + let parseResults = + getParseResults + """ +type Foo() = + member val AutoProperty = autoProp with get, set + member val AutoProperty2 = autoProp +""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.Types( + typeDefns = [ SynTypeDefn(typeRepr = SynTypeDefnRepr.ObjectModel(members = [_ + SynMemberDefn.AutoProperty(withKeyword=Some mWith) + SynMemberDefn.AutoProperty(withKeyword=None)])) ] + ) + ]) ])) -> + assertRange (3, 39) (3, 43) mWith + | _ -> Assert.Fail "Could not get valid AST" + +[] +let ``SynTypeDefn with AbstractSlot contains the range of the with keyword`` () = + let parseResults = + getParseResults + """ +type Foo() = + abstract member Bar : int with get,set +""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.Types( + typeDefns = [ SynTypeDefn(typeRepr = SynTypeDefnRepr.ObjectModel(members = [_ + SynMemberDefn.AbstractSlot(slotSig=SynValSig(trivia = { WithKeyword = Some mWith }))])) ] + ) + ]) ])) -> + assertRange (3, 30) (3, 34) mWith + | _ -> Assert.Fail "Could not get valid AST" + +[] +let ``read-only property in SynMemberDefn.Member contains the range of the with keyword`` () = + let parseResults = + getParseResults + """ +type Foo() = + // A read-only property. + member this.MyReadProperty with get () = myInternalValue +""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.Types( + typeDefns = [ SynTypeDefn(typeRepr = + SynTypeDefnRepr.ObjectModel(members=[ + _ + SynMemberDefn.GetSetMember(Some(SynBinding _), None, _, { WithKeyword = mWith }) ]) + ) ]) + ]) ])) -> + assertRange (4, 31) (4, 35) mWith + | _ -> Assert.Fail "Could not get valid AST" + +[] +let ``write-only property in SynMemberDefn.Member contains the range of the with keyword`` () = + let parseResults = + getParseResults + """ +type Foo() = + // A write-only property. + member this.MyWriteOnlyProperty with set (value) = myInternalValue <- value +""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.Types( + typeDefns = [ SynTypeDefn(typeRepr = + SynTypeDefnRepr.ObjectModel(members=[ + _ + SynMemberDefn.GetSetMember(None, Some(SynBinding _), _, { WithKeyword = mWith }) ]) + ) ]) + ]) ])) -> + assertRange (4, 36) (4, 40) mWith + | _ -> Assert.Fail "Could not get valid AST" + +[] +let ``read/write property in SynMemberDefn.Member contains the range of the with keyword`` () = + let parseResults = + getParseResults + """ +type Foo() = + // A read-write property. + member this.MyReadWriteProperty + with get () = myInternalValue + and set (value) = myInternalValue <- value +""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.Types( + typeDefns = [ SynTypeDefn(typeRepr = + SynTypeDefnRepr.ObjectModel(members=[ + _ + SynMemberDefn.GetSetMember(Some _, Some _, _, { WithKeyword = mWith; AndKeyword = Some mAnd }) ]) + ) ]) + ]) ])) -> + assertRange (5, 8) (5, 12) mWith + assertRange (6, 8) (6, 11) mAnd + | _ -> Assert.Fail "Could not get valid AST" + +[] +let ``SynTypeDefn with static member with get/set`` () = + let parseResults = + getParseResults + """ +type Foo = + static member ReadWrite2 + with set x = lastUsed <- ("ReadWrite2", x) + and get () = lastUsed <- ("ReadWrite2", 0); 4 +""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.Types( + typeDefns = [ SynTypeDefn(typeRepr = SynTypeDefnRepr.ObjectModel(members = [ + SynMemberDefn.GetSetMember(Some _, Some _, m, { WithKeyword = mWith + GetKeyword = Some mGet + AndKeyword = Some mAnd + SetKeyword = Some mSet }) + ])) ] + ) + ]) ])) -> + assertRange (4, 8) (4, 12) mWith + assertRange (4, 13) (4, 16) mSet + assertRange (5, 8) (5, 11) mAnd + assertRange (5, 13) (5, 16) mGet + assertRange (3, 4) (5, 54) m + | _ -> Assert.Fail "Could not get valid AST" + +[] +let ``SynTypeDefn with member with set/get`` () = + let parseResults = + getParseResults + """ +type A() = + member this.Z with set (_:int):unit = () and get():int = 1 +""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.Types( + typeDefns = [ SynTypeDefn(typeRepr = SynTypeDefnRepr.ObjectModel(members = [ + SynMemberDefn.ImplicitCtor _ + SynMemberDefn.GetSetMember(Some (SynBinding(headPat = SynPat.LongIdent(extraId = Some getIdent))), + Some (SynBinding(headPat = SynPat.LongIdent(extraId = Some setIdent))), + m, + { WithKeyword = mWith + GetKeyword = Some mGet + AndKeyword = Some mAnd + SetKeyword = Some mSet }) + ])) ] + ) + ]) ])) -> + Assert.AreEqual("get", getIdent.idText) + Assert.AreEqual("set", setIdent.idText) + assertRange (3, 18) (3, 22) mWith + assertRange (3, 23) (3, 26) mSet + assertRange (3, 23) (3, 26) setIdent.idRange + assertRange (3, 45) (3, 48) mAnd + assertRange (3, 49) (3, 52) mGet + assertRange (3, 49) (3, 52) getIdent.idRange + assertRange (3, 4) (3, 62) m + | _ -> Assert.Fail "Could not get valid AST" + +[] +let ``SynTypeDefn with member with get has xml comment`` () = + let parseResults = + getParseResults + """ +type A = + /// B + member x.B with get() = 5 +""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.Types( + typeDefns = [ SynTypeDefn(typeRepr = SynTypeDefnRepr.ObjectModel(members = [ + SynMemberDefn.GetSetMember(Some (SynBinding(xmlDoc = preXmlDoc)), + None, + _, + _) + ])) ] + ) + ]) ])) -> + Assert.False preXmlDoc.IsEmpty + let comment = preXmlDoc.ToXmlDoc(false, None).GetXmlText() + Assert.False (System.String.IsNullOrWhiteSpace(comment)) + | _ -> Assert.Fail "Could not get valid AST" diff --git a/tests/service/SyntaxTreeTests/TypeTests.fs b/tests/service/SyntaxTreeTests/TypeTests.fs index 874c1f41dac..c006a7cd529 100644 --- a/tests/service/SyntaxTreeTests/TypeTests.fs +++ b/tests/service/SyntaxTreeTests/TypeTests.fs @@ -169,26 +169,6 @@ type Shape = assertRange (2, 11) (2, 12) mEquals | _ -> Assert.Fail "Could not get valid AST" -[] -let ``SynTypeDefn with AutoProperty contains the range of the equals sign`` () = - let parseResults = - getParseResults - """ -/// mutable class with auto-properties -type Person(name : string, age : int) = - /// Full name - member val Name = name with get, set -""" - - match parseResults with - | ParsedInput.ImplFile (ParsedImplFileInput (contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ - SynModuleDecl.Types( - typeDefns = [ SynTypeDefn(typeRepr = SynTypeDefnRepr.ObjectModel(members = [_ ; SynMemberDefn.AutoProperty(equalsRange = mEquals)])) ] - ) - ]) ])) -> - assertRange (5, 20) (5, 21) mEquals - | _ -> Assert.Fail "Could not get valid AST" - [] let ``SynTypeDefn with Record contains the range of the with keyword`` () = let parseResults = @@ -250,115 +230,6 @@ type Foo() = assertRange (3, 18) (3, 22) mWithKeyword | _ -> Assert.Fail "Could not get valid AST" -[] -let ``SynTypeDefn with AutoProperty contains the range of the with keyword`` () = - let parseResults = - getParseResults - """ -type Foo() = - member val AutoProperty = autoProp with get, set - member val AutoProperty2 = autoProp -""" - - match parseResults with - | ParsedInput.ImplFile (ParsedImplFileInput (contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ - SynModuleDecl.Types( - typeDefns = [ SynTypeDefn(typeRepr = SynTypeDefnRepr.ObjectModel(members = [_ - SynMemberDefn.AutoProperty(withKeyword=Some mWith) - SynMemberDefn.AutoProperty(withKeyword=None)])) ] - ) - ]) ])) -> - assertRange (3, 39) (3, 43) mWith - | _ -> Assert.Fail "Could not get valid AST" - -[] -let ``SynTypeDefn with AbstractSlot contains the range of the with keyword`` () = - let parseResults = - getParseResults - """ -type Foo() = - abstract member Bar : int with get,set -""" - - match parseResults with - | ParsedInput.ImplFile (ParsedImplFileInput (contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ - SynModuleDecl.Types( - typeDefns = [ SynTypeDefn(typeRepr = SynTypeDefnRepr.ObjectModel(members = [_ - SynMemberDefn.AbstractSlot(slotSig=SynValSig(trivia = { WithKeyword = Some mWith }))])) ] - ) - ]) ])) -> - assertRange (3, 30) (3, 34) mWith - | _ -> Assert.Fail "Could not get valid AST" - -[] -let ``read-only property in SynMemberDefn.Member contains the range of the with keyword`` () = - let parseResults = - getParseResults - """ -type Foo() = - // A read-only property. - member this.MyReadProperty with get () = myInternalValue -""" - - match parseResults with - | ParsedInput.ImplFile (ParsedImplFileInput (contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ - SynModuleDecl.Types( - typeDefns = [ SynTypeDefn(typeRepr = - SynTypeDefnRepr.ObjectModel(members=[ - _ - SynMemberDefn.GetSetMember(Some(SynBinding _), None, _, { WithKeyword = mWith }) ]) - ) ]) - ]) ])) -> - assertRange (4, 31) (4, 35) mWith - | _ -> Assert.Fail "Could not get valid AST" - -[] -let ``write-only property in SynMemberDefn.Member contains the range of the with keyword`` () = - let parseResults = - getParseResults - """ -type Foo() = - // A write-only property. - member this.MyWriteOnlyProperty with set (value) = myInternalValue <- value -""" - - match parseResults with - | ParsedInput.ImplFile (ParsedImplFileInput (contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ - SynModuleDecl.Types( - typeDefns = [ SynTypeDefn(typeRepr = - SynTypeDefnRepr.ObjectModel(members=[ - _ - SynMemberDefn.GetSetMember(None, Some(SynBinding _), _, { WithKeyword = mWith }) ]) - ) ]) - ]) ])) -> - assertRange (4, 36) (4, 40) mWith - | _ -> Assert.Fail "Could not get valid AST" - -[] -let ``read/write property in SynMemberDefn.Member contains the range of the with keyword`` () = - let parseResults = - getParseResults - """ -type Foo() = - // A read-write property. - member this.MyReadWriteProperty - with get () = myInternalValue - and set (value) = myInternalValue <- value -""" - - match parseResults with - | ParsedInput.ImplFile (ParsedImplFileInput (contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ - SynModuleDecl.Types( - typeDefns = [ SynTypeDefn(typeRepr = - SynTypeDefnRepr.ObjectModel(members=[ - _ - SynMemberDefn.GetSetMember(Some _, Some _, _, { WithKeyword = mWith; AndKeyword = Some mAnd }) ]) - ) ]) - ]) ])) -> - assertRange (5, 8) (5, 12) mWith - assertRange (6, 8) (6, 11) mAnd - | _ -> Assert.Fail "Could not get valid AST" - [] let ``SynTypeDefn with XmlDoc contains the range of the type keyword`` () = let parseResults = @@ -399,70 +270,6 @@ type A = B assertRange (4, 0) (4, 4) mType | _ -> Assert.Fail "Could not get valid AST" -[] -let ``SynTypeDefn with static member with get/set`` () = - let parseResults = - getParseResults - """ -type Foo = - static member ReadWrite2 - with set x = lastUsed <- ("ReadWrite2", x) - and get () = lastUsed <- ("ReadWrite2", 0); 4 -""" - - match parseResults with - | ParsedInput.ImplFile (ParsedImplFileInput (contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ - SynModuleDecl.Types( - typeDefns = [ SynTypeDefn(typeRepr = SynTypeDefnRepr.ObjectModel(members = [ - SynMemberDefn.GetSetMember(Some _, Some _, m, { WithKeyword = mWith - GetKeyword = Some mGet - AndKeyword = Some mAnd - SetKeyword = Some mSet }) - ])) ] - ) - ]) ])) -> - assertRange (4, 8) (4, 12) mWith - assertRange (4, 13) (4, 16) mSet - assertRange (5, 8) (5, 11) mAnd - assertRange (5, 13) (5, 16) mGet - assertRange (3, 4) (5, 54) m - | _ -> Assert.Fail "Could not get valid AST" - -[] -let ``SynTypeDefn with member with set/get`` () = - let parseResults = - getParseResults - """ -type A() = - member this.Z with set (_:int):unit = () and get():int = 1 -""" - - match parseResults with - | ParsedInput.ImplFile (ParsedImplFileInput (contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ - SynModuleDecl.Types( - typeDefns = [ SynTypeDefn(typeRepr = SynTypeDefnRepr.ObjectModel(members = [ - SynMemberDefn.ImplicitCtor _ - SynMemberDefn.GetSetMember(Some (SynBinding(headPat = SynPat.LongIdent(extraId = Some getIdent))), - Some (SynBinding(headPat = SynPat.LongIdent(extraId = Some setIdent))), - m, - { WithKeyword = mWith - GetKeyword = Some mGet - AndKeyword = Some mAnd - SetKeyword = Some mSet }) - ])) ] - ) - ]) ])) -> - Assert.AreEqual("get", getIdent.idText) - Assert.AreEqual("set", setIdent.idText) - assertRange (3, 18) (3, 22) mWith - assertRange (3, 23) (3, 26) mSet - assertRange (3, 23) (3, 26) setIdent.idRange - assertRange (3, 45) (3, 48) mAnd - assertRange (3, 49) (3, 52) mGet - assertRange (3, 49) (3, 52) getIdent.idRange - assertRange (3, 4) (3, 62) m - | _ -> Assert.Fail "Could not get valid AST" - [] let ``SynType.Fun has range of arrow`` () = let parseResults = @@ -502,7 +309,7 @@ let _: struct (int * int) = () ]) ) -> assertRange (2, 7) (2, 25) mTuple - + | _ -> Assert.Fail $"Could not get valid AST, got {parseResults}" [] @@ -522,7 +329,7 @@ let _: struct (int * int = () ]) ) -> assertRange (2, 7) (2, 24) mTuple - + | _ -> Assert.Fail $"Could not get valid AST, got {parseResults}" [] @@ -593,4 +400,4 @@ type X = ])) -> Assert.AreEqual("a", a.idText) assertRange (3, 23) (3, 41) m - | _ -> Assert.Fail $"Could not get valid AST, got {parseResults}" \ No newline at end of file + | _ -> Assert.Fail $"Could not get valid AST, got {parseResults}"