Skip to content

Commit 0929055

Browse files
authored
Merge pull request #650 from vasily-kirichenko/add-module-values-to-navigable-items
Add module values to navigable items
2 parents a1548bf + 81f993c commit 0929055

File tree

2 files changed

+94
-40
lines changed

2 files changed

+94
-40
lines changed

src/fsharp/vs/ServiceNavigation.fs

Lines changed: 81 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -24,23 +24,48 @@ type FSharpNavigationDeclarationItemKind =
2424
| FieldDecl
2525
| OtherDecl
2626

27+
[<RequireQualifiedAccess>]
28+
type FSharpEnclosingEntityKind =
29+
| Namespace
30+
| Module
31+
| Class
32+
| Exception
33+
| Interface
34+
| Record
35+
| Enum
36+
| DU
37+
2738
/// Represents an item to be displayed in the navigation bar
2839
[<Sealed>]
29-
type FSharpNavigationDeclarationItem(uniqueName: string, name: string, kind: FSharpNavigationDeclarationItemKind, glyph: int, range: range, bodyRange: range, singleTopLevel:bool) =
40+
type FSharpNavigationDeclarationItem
41+
(
42+
uniqueName: string,
43+
name: string,
44+
kind: FSharpNavigationDeclarationItemKind,
45+
glyph: int,
46+
range: range,
47+
bodyRange: range,
48+
singleTopLevel: bool,
49+
enclosingEntityKind: FSharpEnclosingEntityKind,
50+
isAbstract: bool
51+
) =
3052

3153
member x.bodyRange = bodyRange
32-
3354
member x.UniqueName = uniqueName
3455
member x.Name = name
3556
member x.Glyph = glyph
3657
member x.Kind = kind
3758
member x.Range = range
3859
member x.BodyRange = bodyRange
3960
member x.IsSingleTopLevel = singleTopLevel
61+
member x.EnclosingEntityKind = enclosingEntityKind
62+
member x.IsAbstract = isAbstract
63+
4064
member x.WithUniqueName(uniqueName: string) =
41-
FSharpNavigationDeclarationItem(uniqueName, name, kind, glyph, range, bodyRange, singleTopLevel)
42-
static member Create(name: string, kind, glyph: int, range: range, bodyRange: range, singleTopLevel:bool) =
43-
FSharpNavigationDeclarationItem("", name, kind, glyph, range, bodyRange, singleTopLevel)
65+
FSharpNavigationDeclarationItem (uniqueName, name, kind, glyph, range, bodyRange, singleTopLevel, enclosingEntityKind, isAbstract)
66+
67+
static member Create(name: string, kind, glyph: int, range: range, bodyRange: range, singleTopLevel: bool, enclosingEntityKind, isAbstract) =
68+
FSharpNavigationDeclarationItem("", name, kind, glyph, range, bodyRange, singleTopLevel, enclosingEntityKind, isAbstract)
4469

4570
/// Represents top-level declarations (that should be in the type drop-down)
4671
/// with nested declarations (that can be shown in the member drop-down)
@@ -92,26 +117,29 @@ module NavigationImpl =
92117
sprintf "%s_%d_of_%d" name idx total
93118

94119
// Create declaration (for the left dropdown)
95-
let createDeclLid(baseName, lid, kind, baseGlyph, m, bodym, nested) =
120+
let createDeclLid(baseName, lid, kind, baseGlyph, m, bodym, nested, enclosingEntityKind, isAbstract) =
96121
let name = (if baseName <> "" then baseName + "." else "") + (textOfLid lid)
97122
FSharpNavigationDeclarationItem.Create
98-
(name, kind, baseGlyph * 6, m, bodym, false), (addItemName name), nested
123+
(name, kind, baseGlyph * 6, m, bodym, false, enclosingEntityKind, isAbstract), (addItemName name), nested
99124

100-
let createDecl(baseName, (id:Ident), kind, baseGlyph, m, bodym, nested) =
125+
let createDecl(baseName, (id:Ident), kind, baseGlyph, m, bodym, nested, enclosingEntityKind, isAbstract) =
101126
let name = (if baseName <> "" then baseName + "." else "") + (id.idText)
102127
FSharpNavigationDeclarationItem.Create
103-
(name, kind, baseGlyph * 6, m, bodym, false), (addItemName name), nested
128+
(name, kind, baseGlyph * 6, m, bodym, false, enclosingEntityKind, isAbstract), (addItemName name), nested
104129

105130
// Create member-kind-of-thing for the right dropdown
106-
let createMemberLid(lid, kind, baseGlyph, m) =
107-
FSharpNavigationDeclarationItem.Create(textOfLid lid, kind, baseGlyph * 6, m, m, false), (addItemName(textOfLid lid))
131+
let createMemberLid(lid, kind, baseGlyph, m, enclosingEntityKind, isAbstract) =
132+
FSharpNavigationDeclarationItem.Create(textOfLid lid, kind, baseGlyph * 6, m, m, false, enclosingEntityKind, isAbstract),
133+
(addItemName(textOfLid lid))
108134

109-
let createMember((id:Ident), kind, baseGlyph, m) =
110-
FSharpNavigationDeclarationItem.Create(id.idText, kind, baseGlyph * 6, m, m, false), (addItemName(id.idText))
111-
135+
let createMember((id:Ident), kind, baseGlyph, m, enclosingEntityKind, isAbstract) =
136+
FSharpNavigationDeclarationItem.Create(id.idText, kind, baseGlyph * 6, m, m, false, enclosingEntityKind, isAbstract),
137+
(addItemName(id.idText))
112138

113139
// Process let-binding
114-
let processBinding isMember (Binding(_, _, _, _, _, _, SynValData(memebrOpt, _, _), synPat, _, synExpr, _, _)) =
140+
let processBinding isMember enclosingEntityKind isAbstract
141+
(Binding(_, _, _, _, _, _, SynValData(memebrOpt, _, _), synPat, _, synExpr, _, _)) =
142+
115143
let m = match synExpr with
116144
| SynExpr.Typed(e, _, _) -> e.Range // fix range for properties with type annotations
117145
| _ -> synExpr.Range
@@ -131,89 +159,101 @@ module NavigationImpl =
131159
| _thisVar::nm::_ -> (List.tail lid, nm.idRange)
132160
| hd::_ -> (lid, hd.idRange)
133161
| _ -> (lid, m)
134-
[ createMemberLid(lidShow, kind, icon, unionRanges rangeMerge m) ]
135-
| SynPat.LongIdent(LongIdentWithDots(lid,_), _,_, _, _, _), _ -> [ createMemberLid(lid, FieldDecl, iIconGroupConstant, unionRanges (List.head lid).idRange m) ]
162+
[ createMemberLid(lidShow, kind, icon, unionRanges rangeMerge m, enclosingEntityKind, isAbstract) ]
163+
| SynPat.LongIdent(LongIdentWithDots(lid,_), _,_, _, _, _), _ ->
164+
[ createMemberLid(lid, FieldDecl, iIconGroupConstant, unionRanges (List.head lid).idRange m, enclosingEntityKind, isAbstract) ]
165+
| SynPat.Named (_,ident,_,_,r), _ ->
166+
[ createMemberLid([ident], FieldDecl, iIconGroupConstant, r, enclosingEntityKind, isAbstract)]
136167
| _ -> []
137168

138169
// Process a class declaration or F# type declaration
139170
let rec processExnDefnRepr baseName nested (SynExceptionDefnRepr(_, (UnionCase(_, id, fldspec, _, _, _)), _, _, _, m)) =
140171
// Exception declaration
141-
[ createDecl(baseName, id, ExnDecl, iIconGroupException, m, fldspecRange fldspec, nested) ]
172+
[ createDecl(baseName, id, ExnDecl, iIconGroupException, m, fldspecRange fldspec, nested,
173+
FSharpEnclosingEntityKind.Exception, false) ]
142174

143175
// Process a class declaration or F# type declaration
144176
and processExnDefn baseName (SynExceptionDefn(repr, membDefns, _)) =
145-
let nested = processMembers membDefns |> snd
177+
let nested = processMembers membDefns FSharpEnclosingEntityKind.Exception |> snd
146178
processExnDefnRepr baseName nested repr
147179

148180
and processTycon baseName (TypeDefn(ComponentInfo(_, _, _, lid, _, _, _, _), repr, membDefns, m)) =
149-
let topMembers = processMembers membDefns |> snd
181+
let topMembers = processMembers membDefns FSharpEnclosingEntityKind.Class |> snd
150182
match repr with
151183
| SynTypeDefnRepr.Exception repr -> processExnDefnRepr baseName [] repr
152184
| SynTypeDefnRepr.ObjectModel(_, membDefns, mb) ->
153185
// F# class declaration
154-
let members = processMembers membDefns |> snd
186+
let members = processMembers membDefns FSharpEnclosingEntityKind.Class |> snd
155187
let nested = members@topMembers
156-
([ createDeclLid(baseName, lid, TypeDecl, iIconGroupClass, m, bodyRange mb nested, nested) ]: ((FSharpNavigationDeclarationItem * int * _) list))
188+
([ createDeclLid(baseName, lid, TypeDecl, iIconGroupClass, m, bodyRange mb nested, nested,
189+
FSharpEnclosingEntityKind.Class, false) ]: ((FSharpNavigationDeclarationItem * int * _) list))
157190
| SynTypeDefnRepr.Simple(simple, _) ->
158191
// F# type declaration
159192
match simple with
160193
| SynTypeDefnSimpleRepr.Union(_, cases, mb) ->
161194
let cases =
162195
[ for (UnionCase(_, id, fldspec, _, _, _)) in cases ->
163-
createMember(id, OtherDecl, iIconGroupValueType, unionRanges (fldspecRange fldspec) id.idRange) ]
196+
createMember(id, OtherDecl, iIconGroupValueType, unionRanges (fldspecRange fldspec) id.idRange,
197+
FSharpEnclosingEntityKind.DU, false) ]
164198
let nested = cases@topMembers
165-
[ createDeclLid(baseName, lid, TypeDecl, iIconGroupUnion, m, bodyRange mb nested, nested) ]
199+
[ createDeclLid(baseName, lid, TypeDecl, iIconGroupUnion, m, bodyRange mb nested, nested,
200+
FSharpEnclosingEntityKind.DU, false) ]
166201
| SynTypeDefnSimpleRepr.Enum(cases, mb) ->
167202
let cases =
168203
[ for (EnumCase(_, id, _, _, m)) in cases ->
169-
createMember(id, FieldDecl, iIconGroupEnumMember, m) ]
204+
createMember(id, FieldDecl, iIconGroupEnumMember, m, FSharpEnclosingEntityKind.Enum, false) ]
170205
let nested = cases@topMembers
171-
[ createDeclLid(baseName, lid, TypeDecl, iIconGroupEnum, m, bodyRange mb nested, nested) ]
206+
[ createDeclLid(baseName, lid, TypeDecl, iIconGroupEnum, m, bodyRange mb nested, nested,
207+
FSharpEnclosingEntityKind.Enum, false) ]
172208
| SynTypeDefnSimpleRepr.Record(_, fields, mb) ->
173209
let fields =
174210
[ for (Field(_, _, id, _, _, _, _, m)) in fields do
175211
if (id.IsSome) then
176-
yield createMember(id.Value, FieldDecl, iIconGroupFieldBlue, m) ]
212+
yield createMember(id.Value, FieldDecl, iIconGroupFieldBlue, m, FSharpEnclosingEntityKind.Record, false) ]
177213
let nested = fields@topMembers
178-
[ createDeclLid(baseName, lid, TypeDecl, iIconGroupType, m, bodyRange mb nested, nested) ]
214+
[ createDeclLid(baseName, lid, TypeDecl, iIconGroupType, m, bodyRange mb nested, nested,
215+
FSharpEnclosingEntityKind.Record, false) ]
179216
| SynTypeDefnSimpleRepr.TypeAbbrev(_, _, mb) ->
180-
[ createDeclLid(baseName, lid, TypeDecl, iIconGroupTypedef, m, bodyRange mb topMembers, topMembers) ]
217+
[ createDeclLid(baseName, lid, TypeDecl, iIconGroupTypedef, m, bodyRange mb topMembers, topMembers,
218+
FSharpEnclosingEntityKind.Class, false) ]
181219

182220
//| SynTypeDefnSimpleRepr.General of TyconKind * (SynType * range * ident option) list * (valSpfn * MemberFlags) list * fieldDecls * bool * bool * range
183221
//| SynTypeDefnSimpleRepr.LibraryOnlyILAssembly of ILType * range
184222
//| TyconCore_repr_hidden of range
185223
| _ -> []
186224

187225
// Returns class-members for the right dropdown
188-
and processMembers members: (range * list<FSharpNavigationDeclarationItem * int>) =
226+
and processMembers (members: SynMemberDefns) (enclosingEntityKind: FSharpEnclosingEntityKind)
227+
: (range * list<FSharpNavigationDeclarationItem * int>) =
228+
189229
let members = members |> List.map (fun memb ->
190230
(memb.Range,
191231
match memb with
192-
| SynMemberDefn.LetBindings(binds, _, _, _) -> List.collect (processBinding false) binds
193-
| SynMemberDefn.Member(bind, _) -> processBinding true bind
232+
| SynMemberDefn.LetBindings(binds, _, _, _) -> List.collect (processBinding false enclosingEntityKind false) binds
233+
| SynMemberDefn.Member(bind, _) -> processBinding true enclosingEntityKind false bind
194234
| SynMemberDefn.ValField(Field(_, _, Some(rcid), ty, _, _, _, _), _) ->
195-
[ createMember(rcid, FieldDecl, iIconGroupFieldBlue, ty.Range) ]
235+
[ createMember(rcid, FieldDecl, iIconGroupFieldBlue, ty.Range, enclosingEntityKind, false) ]
196236
| SynMemberDefn.AutoProperty(_attribs,_isStatic,id,_tyOpt,_propKind,_,_xmlDoc,_access,_synExpr, _, _) ->
197-
[ createMember(id, FieldDecl, iIconGroupFieldBlue, id.idRange) ]
237+
[ createMember(id, FieldDecl, iIconGroupFieldBlue, id.idRange, enclosingEntityKind, false) ]
198238
| SynMemberDefn.AbstractSlot(ValSpfn(_, id, _, ty, _, _, _, _, _, _, _), _, _) ->
199-
[ createMember(id, MethodDecl, iIconGroupMethod2, ty.Range) ]
239+
[ createMember(id, MethodDecl, iIconGroupMethod2, ty.Range, enclosingEntityKind, true) ]
200240
| SynMemberDefn.NestedType _ -> failwith "tycon as member????" //processTycon tycon
201241
| SynMemberDefn.Interface(_, Some(membs), _) ->
202-
processMembers membs |> snd
242+
processMembers membs FSharpEnclosingEntityKind.Interface |> snd
203243
| _ -> [] ))
204244
((members |> Seq.map fst |> Seq.fold unionRangesChecked range.Zero),
205245
(members |> List.map snd |> List.concat))
206246

207247
// Process declarations in a module that belong to the right drop-down (let bindings)
208248
let processNestedDeclarations decls = decls |> List.collect (function
209-
| SynModuleDecl.Let(_, binds, _) -> List.collect (processBinding false) binds
249+
| SynModuleDecl.Let(_, binds, _) -> List.collect (processBinding false FSharpEnclosingEntityKind.Module false) binds
210250
| _ -> [] )
211251

212252
// Process declarations nested in a module that should be displayed in the left dropdown
213253
// (such as type declarations, nested modules etc.)
214254
let rec processFSharpNavigationTopLevelDeclarations(baseName, decls) = decls |> List.collect (function
215255
| SynModuleDecl.ModuleAbbrev(id, lid, m) ->
216-
[ createDecl(baseName, id, ModuleDecl, iIconGroupModule, m, rangeOfLid lid, []) ]
256+
[ createDecl(baseName, id, ModuleDecl, iIconGroupModule, m, rangeOfLid lid, [], FSharpEnclosingEntityKind.Namespace, false) ]
217257

218258
| SynModuleDecl.NestedModule(ComponentInfo(_, _, _, lid, _, _, _, _), _isRec, decls, _, m) ->
219259
// Find let bindings (for the right dropdown)
@@ -222,7 +262,8 @@ module NavigationImpl =
222262

223263
// Get nested modules and types (for the left dropdown)
224264
let other = processFSharpNavigationTopLevelDeclarations(newBaseName, decls)
225-
createDeclLid(baseName, lid, ModuleDecl, iIconGroupModule, m, unionRangesChecked (rangeOfDecls nested) (moduleRange (rangeOfLid lid) other), nested)::other
265+
createDeclLid(baseName, lid, ModuleDecl, iIconGroupModule, m, unionRangesChecked (rangeOfDecls nested)
266+
(moduleRange (rangeOfLid lid) other), nested, FSharpEnclosingEntityKind.Module, false)::other
226267

227268
| SynModuleDecl.Types(tydefs, _) -> tydefs |> List.collect (processTycon baseName)
228269
| SynModuleDecl.Exception (defn,_) -> processExnDefn baseName defn
@@ -245,7 +286,7 @@ module NavigationImpl =
245286
(textOfLid id, (if isModule then ModuleFileDecl else NamespaceDecl),
246287
iIconGroupModule * 6, m,
247288
unionRangesChecked (rangeOfDecls nested) (moduleRange (rangeOfLid id) other),
248-
singleTopLevel), (addItemName(textOfLid id)), nested
289+
singleTopLevel, FSharpEnclosingEntityKind.Module, false), (addItemName(textOfLid id)), nested
249290
decl::other )
250291

251292
let items =

src/fsharp/vs/ServiceNavigation.fsi

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,17 @@ type FSharpNavigationDeclarationItemKind =
2121
| FieldDecl
2222
| OtherDecl
2323

24+
[<RequireQualifiedAccess>]
25+
type FSharpEnclosingEntityKind =
26+
| Namespace
27+
| Module
28+
| Class
29+
| Exception
30+
| Interface
31+
| Record
32+
| Enum
33+
| DU
34+
2435
/// Represents an item to be displayed in the navigation bar
2536
[<Sealed>]
2637
type (*internal*) FSharpNavigationDeclarationItem =
@@ -31,6 +42,8 @@ type (*internal*) FSharpNavigationDeclarationItem =
3142
member Range : Range.range
3243
member BodyRange : Range.range
3344
member IsSingleTopLevel : bool
45+
member EnclosingEntityKind: FSharpEnclosingEntityKind
46+
member IsAbstract: bool
3447

3548
/// Represents top-level declarations (that should be in the type drop-down)
3649
/// with nested declarations (that can be shown in the member drop-down)

0 commit comments

Comments
 (0)