forked from dotnet/fsharp
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathSymbols.fs
More file actions
160 lines (131 loc) · 5.32 KB
/
Copy pathSymbols.fs
File metadata and controls
160 lines (131 loc) · 5.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#if INTERACTIVE
#r "../../artifacts/bin/fcs/net461/FSharp.Compiler.Service.dll" // note, build FSharp.Compiler.Service.Tests.fsproj to generate this, this DLL has a public API so can be used from F# Interactive
#r "../../artifacts/bin/fcs/net461/nunit.framework.dll"
#load "FsUnit.fs"
#load "Common.fs"
#else
module Tests.Service.Symbols
#endif
open FSharp.Compiler.Service.Tests.Common
open FsUnit
open NUnit.Framework
open FSharp.Compiler.SourceCodeServices
module ActivePatterns =
let completePatternInput = """
let (|True|False|) = function
| true -> True
| false -> False
match true with
| True | False -> ()
"""
let partialPatternInput = """
let (|String|_|) = function
| :? String -> Some ()
| _ -> None
match "foo" with
| String
| _ -> ()
"""
let getCaseUsages source line =
let fileName, options = mkTestFileAndOptions source [| |]
let _, checkResults = parseAndCheckFile fileName source options
checkResults.GetAllUsesOfAllSymbolsInFile()
|> Array.filter (fun su -> su.RangeAlternate.StartLine = line && su.Symbol :? FSharpActivePatternCase)
|> Array.map (fun su -> su.Symbol :?> FSharpActivePatternCase)
[<Test>]
let ``Active pattern case indices`` () =
let getIndices = Array.map (fun (case: FSharpActivePatternCase) -> case.Index)
getCaseUsages completePatternInput 7 |> getIndices |> shouldEqual [| 0; 1 |]
getCaseUsages partialPatternInput 7 |> getIndices |> shouldEqual [| 0 |]
[<Test>]
let ``Active pattern group names`` () =
let getGroupName (case: FSharpActivePatternCase) = case.Group.Name.Value
getCaseUsages completePatternInput 7 |> Array.head |> getGroupName |> shouldEqual "|True|False|"
getCaseUsages partialPatternInput 7 |> Array.head |> getGroupName |> shouldEqual "|String|_|"
module XmlDocSig =
[<Test>]
let ``XmlDocSig of modules in namespace`` () =
let source = """
namespace Ns1
module Mod1 =
let val1 = 1
module Mod2 =
let func2 () = ()
"""
let fileName, options = mkTestFileAndOptions source [| |]
let _, checkResults = parseAndCheckFile fileName source options
let mod1 = checkResults.PartialAssemblySignature.FindEntityByPath ["Ns1"; "Mod1"] |> Option.get
let mod2 = checkResults.PartialAssemblySignature.FindEntityByPath ["Ns1"; "Mod1"; "Mod2"] |> Option.get
let mod1val1 = mod1.MembersFunctionsAndValues |> Seq.find (fun m -> m.DisplayName = "val1")
let mod2func2 = mod2.MembersFunctionsAndValues |> Seq.find (fun m -> m.DisplayName = "func2")
mod1.XmlDocSig |> shouldEqual "T:Ns1.Mod1"
mod2.XmlDocSig |> shouldEqual "T:Ns1.Mod1.Mod2"
mod1val1.XmlDocSig |> shouldEqual "P:Ns1.Mod1.val1"
mod2func2.XmlDocSig |> shouldEqual "M:Ns1.Mod1.Mod2.func2"
[<Test>]
let ``XmlDocSig of modules`` () =
let source = """
module Mod1
let val1 = 1
module Mod2 =
let func2 () = ()
"""
let fileName, options = mkTestFileAndOptions source [| |]
let _, checkResults = parseAndCheckFile fileName source options
let mod1 = checkResults.PartialAssemblySignature.FindEntityByPath ["Mod1"] |> Option.get
let mod2 = checkResults.PartialAssemblySignature.FindEntityByPath ["Mod1"; "Mod2"] |> Option.get
let mod1val1 = mod1.MembersFunctionsAndValues |> Seq.find (fun m -> m.DisplayName = "val1")
let mod2func2 = mod2.MembersFunctionsAndValues |> Seq.find (fun m -> m.DisplayName = "func2")
mod1.XmlDocSig |> shouldEqual "T:Mod1"
mod2.XmlDocSig |> shouldEqual "T:Mod1.Mod2"
mod1val1.XmlDocSig |> shouldEqual "P:Mod1.val1"
mod2func2.XmlDocSig |> shouldEqual "M:Mod1.Mod2.func2"
module Attributes =
[<Test>]
let ``Emit conditional attributes`` () =
let source = """
open System
open System.Diagnostics
[<Conditional("Bar")>]
type FooAttribute() =
inherit Attribute()
[<Foo>]
let x = 123
"""
let fileName, options = mkTestFileAndOptions source [| "--noconditionalerasure" |]
let _, checkResults = parseAndCheckFile fileName source options
checkResults.GetAllUsesOfAllSymbolsInFile()
|> Array.tryFind (fun su -> su.Symbol.DisplayName = "x")
|> Option.orElseWith (fun _ -> failwith "Could not get symbol")
|> Option.map (fun su -> su.Symbol :?> FSharpMemberOrFunctionOrValue)
|> Option.iter (fun symbol -> symbol.Attributes.Count |> shouldEqual 1)
module Types =
[<Test>]
let ``FSharpType.Print parent namespace qualifiers`` () =
let _, checkResults = getParseAndCheckResults """
namespace Ns1.Ns2
type T() = class end
type A = T
namespace Ns1.Ns3
type B = Ns1.Ns2.T
namespace Ns1.Ns4
open Ns1.Ns2
type C = Ns1.Ns2.T
namespace Ns1.Ns5
open Ns1
type D = Ns1.Ns2.T
namespace Ns1.Ns2.Ns6
type E = Ns1.Ns2.T
"""
[| "A", "T"
"B", "Ns1.Ns2.T"
"C", "T"
"D", "Ns2.T"
"E", "Ns1.Ns2.T" |]
|> Array.iter (fun (symbolName, expectedPrintedType) ->
let symbolUse = findSymbolUseByName symbolName checkResults
match symbolUse.Symbol with
| :? FSharpEntity as entity ->
entity.AbbreviatedType.Format(symbolUse.DisplayContext)
|> should equal expectedPrintedType
| _ -> failwithf "Couldn't get entity: %s" symbolName)