@@ -11,10 +11,7 @@ module UnusedOpens =
1111
1212/// Represents single open statement.
1313type OpenStatement =
14- { /// Full namespace or module identifier as it's presented in source code.
15- Idents: Set < string >
16- /// Modules.
17- Modules: FSharpEntity list
14+ { Modules: FSharpEntity list
1815/// Range of open statement itself.
1916 Range: range
2017/// Scope on which this open declaration is applied.
@@ -23,8 +20,7 @@ module UnusedOpens =
2320 IsGlobal: bool }
2421
2522member this.AllChildSymbols =
26- let rec getAllChildSymbolsInModule ( modul : FSharpEntity ) =
27- seq {
23+ seq { for modulin this.Modulesdo
2824for entin modul.NestedEntitiesdo
2925yield ent:> FSharpSymbol
3026
@@ -35,36 +31,26 @@ module UnusedOpens =
3531if ent.IsFSharpUnion&& not ( hasAttribute< RequireQualifiedAccessAttribute> ent.Attributes) then
3632for unionCasein ent.UnionCasesdo
3733yield upcast unionCase
38-
39- if ent.IsFSharpModule&& hasAttribute< AutoOpenAttribute> ent.Attributesthen
40- yield ! getAllChildSymbolsInModule ent
41-
34+
4235for fvin modul.MembersFunctionsAndValuesdo
4336yield upcast fv
4437
4538for apCasein modul.ActivePatternCasesdo
46- yield upcast apCase
47- }
48-
49- seq { for modulin this.Modulesdo
50- yield ! getAllChildSymbolsInModule modul
39+ yield upcast apCase
5140} |> Seq.cache
5241
42+ let rec getModuleAndItsAutoOpens ( modul : FSharpEntity ) =
43+ [ yield modul
44+ for entin modul.NestedEntitiesdo
45+ if ent.IsFSharpModule&& hasAttribute< AutoOpenAttribute> ent.Attributesthen
46+ yield ! getModuleAndItsAutoOpens ent]
47+
5348let getOpenStatements ( openDeclarations : FSharpOpenDeclaration list ) : OpenStatement list =
5449 openDeclarations
5550|> List.choose( fun openDecl ->
5651match openDecl.LongId, openDecl.Rangewith
5752| firstId:: _, Some range->
58- Some{ Idents=
59- openDecl.Modules
60- |> List.choose( fun x -> x.TryFullName|> Option.map( fun fullName -> x, fullName))
61- |> List.collect( fun ( modul , fullName ) ->
62- [ yield fullName
63- if modul.HasFSharpModuleSuffixthen
64- yield fullName.[.. fullName.Length- 7 ] // "Module" length plus zero index correction
65- ])
66- |> Set.ofList
67- Modules= openDecl.Modules
53+ Some{ Modules= openDecl.Modules|> List.collect getModuleAndItsAutoOpens
6854 Range= range
6955 AppliedScope= openDecl.AppliedScope
7056 IsGlobal= firstId.idText= MangledGlobalName}
@@ -93,7 +79,6 @@ module UnusedOpens =
9379|> Array.exists( fun symbolUse ->
9480let inScope = rangeContainsRange openStatement.AppliedScope symbolUse.RangeAlternate
9581if not inScopethen false
96- //elif openStatement.Idents |> Set.intersect symbolUse.PossibleNamespaces |> Set.isEmpty then false
9782else
9883let moduleSymbols = openStatement.AllChildSymbols|> Seq.toList
9984 moduleSymbols
@@ -107,7 +92,7 @@ module UnusedOpens =
10792// if such open statement has already been marked as used in this or outer module, we skip it
10893// (that is, do not mark as used so far)
10994 rangeContainsRange seenNs.AppliedScope openStatement.AppliedScope&&
110- not ( openStatement.Idents |> Set.intersect seenNs.Idents |> Set.isEmpty ))
95+ openStatement.Modules |> List.exists ( fun x -> seenNs.Modules |> List.exists ( fun s -> s.IsEffectivelySameAs x ) ))
11196not alreadySeen
11297
11398match openStatementswith