Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
185 changes: 54 additions & 131 deletions src/Compiler/Checking/NameResolution.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4297,20 +4297,6 @@ let InfosForTyconConstructors (ncenv: NameResolver) m ad (tcref: TyconRef) =
let inline notFakeContainerModule (tyconNames: HashSet<_>) nm =
not (tyconNames.Contains nm)

let getFakeContainerModulesFromTycons (tycons:#seq<Tycon>) =
let hashSet = HashSet()
for tycon in tycons do
if tycon.IsILTycon then
hashSet.Add tycon.DisplayName |> ignore
hashSet

let getFakeContainerModulesFromTyconRefs (tyconRefs:#seq<TyconRef>) =
let hashSet = HashSet()
for tyconRef in tyconRefs do
if tyconRef.IsILTycon then
hashSet.Add tyconRef.DisplayName |> ignore
hashSet

/// Check is a namespace or module contains something accessible
let rec private EntityRefContainsSomethingAccessible (ncenv: NameResolver) m ad (modref: ModuleOrNamespaceRef) =
let g = ncenv.g
Expand Down Expand Up @@ -4346,6 +4332,54 @@ let rec private EntityRefContainsSomethingAccessible (ncenv: NameResolver) m ad
let submodref = modref.NestedTyconRef submod
EntityRefContainsSomethingAccessible ncenv m ad submodref))

let GetVisibleNamespacesAndModulesAtPoint (ncenv: NameResolver) (nenv: NameResolutionEnv) fullyQualified m ad =
protectAssemblyExploration [] (fun () ->
let items =
nenv.ModulesAndNamespaces fullyQualified
|> NameMultiMap.range

if isNil items then
[]
else
let ilTyconNames =
let hashSet = HashSet()
for tyconRef in nenv.TyconsByAccessNames(fullyQualified).Values do
if tyconRef.IsILTycon then
hashSet.Add tyconRef.DisplayName |> ignore
hashSet

items
|> List.filter (fun x ->
let demangledName = x.DemangledModuleOrNamespaceName
IsInterestingModuleName demangledName && notFakeContainerModule ilTyconNames demangledName
&& EntityRefContainsSomethingAccessible ncenv m ad x
&& not (IsTyconUnseen ad ncenv.g ncenv.amap m x)))

let GetAccessibleSubModules g (ncenv: NameResolver) (modref: ModuleOrNamespaceRef) m ad =
let moduleOrNamespaces =
modref.ModuleOrNamespaceType.ModulesAndNamespacesByDemangledName
|> NameMap.range

if isNil moduleOrNamespaces then
[]
else
let ilTyconNames =
let hashSet = HashSet()
for tycon in modref.ModuleOrNamespaceType.TypesByAccessNames.Values do
if tycon.IsILTycon then
hashSet.Add tycon.DisplayName |> ignore
hashSet

moduleOrNamespaces
|> List.filter (fun x ->
let demangledName = x.DemangledModuleOrNamespaceName
notFakeContainerModule ilTyconNames demangledName && IsInterestingModuleName demangledName)
|> List.map modref.NestedTyconRef
|> List.filter (fun tyref ->
not (IsTyconUnseen ad g ncenv.amap m tyref) &&
EntityRefContainsSomethingAccessible ncenv m ad tyref)
|> List.map ItemForModuleOrNamespaceRef

let rec ResolvePartialLongIdentInModuleOrNamespace (ncenv: NameResolver) nenv isApplicableMeth m ad (modref: ModuleOrNamespaceRef) plid allowObsolete =
let g = ncenv.g
let mty = modref.ModuleOrNamespaceType
Expand All @@ -4357,25 +4391,6 @@ let rec ResolvePartialLongIdentInModuleOrNamespace (ncenv: NameResolver) nenv is
not (tcref.LogicalName.Contains ",") &&
not (IsTyconUnseen ad g ncenv.amap m (modref.NestedTyconRef tcref)))

let accessibleSubModules =
let moduleOrNamespaces =
mty.ModulesAndNamespacesByDemangledName
|> NameMap.range

if isNil moduleOrNamespaces then [] else

let ilTyconNames = getFakeContainerModulesFromTycons mty.TypesByAccessNames.Values

moduleOrNamespaces
|> List.filter (fun x ->
let demangledName = x.DemangledModuleOrNamespaceName
notFakeContainerModule ilTyconNames demangledName && IsInterestingModuleName demangledName)
|> List.map modref.NestedTyconRef
|> List.filter (fun tyref ->
not (IsTyconUnseen ad g ncenv.amap m tyref) &&
EntityRefContainsSomethingAccessible ncenv m ad tyref)
|> List.map ItemForModuleOrNamespaceRef

// Collect up the accessible values in the module, excluding the members
(mty.AllValsAndMembers
|> Seq.toList
Expand All @@ -4402,7 +4417,7 @@ let rec ResolvePartialLongIdentInModuleOrNamespace (ncenv: NameResolver) nenv is
|> List.filter (IsTyconUnseen ad g ncenv.amap m >> not)
|> List.map Item.ExnCase)

@ accessibleSubModules
@ GetAccessibleSubModules g ncenv modref m ad

// Get all the types and .NET constructor groups accessible from here
@ (tycons
Expand Down Expand Up @@ -4496,20 +4511,7 @@ let rec ResolvePartialLongIdentPrim (ncenv: NameResolver) (nenv: NameResolutionE
|> List.filter (function Item.ActivePatternCase _v -> true | _ -> false)

let moduleAndNamespaceItems =
let moduleOrNamespaceRefs =
nenv.ModulesAndNamespaces fullyQualified
|> NameMultiMap.range

if isNil moduleOrNamespaceRefs then [] else
let ilTyconNames = getFakeContainerModulesFromTyconRefs (nenv.TyconsByAccessNames(fullyQualified).Values)

moduleOrNamespaceRefs
|> List.filter (fun modref ->
let demangledName = modref.DemangledModuleOrNamespaceName
IsInterestingModuleName demangledName && notFakeContainerModule ilTyconNames demangledName &&
EntityRefContainsSomethingAccessible ncenv m ad modref &&
not (IsTyconUnseen ad g ncenv.amap m modref))
|> List.map ItemForModuleOrNamespaceRef
GetVisibleNamespacesAndModulesAtPoint ncenv nenv fullyQualified m ad |> List.map ItemForModuleOrNamespaceRef

let tycons =
nenv.TyconsByDemangledNameAndArity(fullyQualified).Values
Expand Down Expand Up @@ -4599,26 +4601,7 @@ let rec ResolvePartialLongIdentInModuleOrNamespaceForRecordFields (ncenv: NameRe
not (IsTyconUnseen ad g ncenv.amap m (modref.NestedTyconRef tcref)))


let accessibleSubModules =
let moduleOrNamespaces =
mty.ModulesAndNamespacesByDemangledName
|> NameMap.range

if isNil moduleOrNamespaces then [] else

let ilTyconNames = getFakeContainerModulesFromTycons mty.TypesByAccessNames.Values

moduleOrNamespaces
|> List.filter (fun x ->
let demangledName = x.DemangledModuleOrNamespaceName
notFakeContainerModule ilTyconNames demangledName && IsInterestingModuleName demangledName)
|> List.map modref.NestedTyconRef
|> List.filter (fun tcref ->
not (IsTyconUnseen ad g ncenv.amap m tcref) &&
EntityRefContainsSomethingAccessible ncenv m ad tcref)
|> List.map ItemForModuleOrNamespaceRef

accessibleSubModules
GetAccessibleSubModules g ncenv modref m ad

// Collect all accessible record types
@ (tycons |> List.map (modref.NestedTyconRef >> ItemOfTyconRef ncenv m) )
Expand Down Expand Up @@ -4682,21 +4665,7 @@ and ResolvePartialLongIdentToClassOrRecdFieldsImpl (ncenv: NameResolver) (nenv:
if fieldsOnly then getRecordFieldsInScope nenv else

let mods =
let moduleOrNamespaceRefs =
nenv.ModulesAndNamespaces fullyQualified
|> NameMultiMap.range

if isNil moduleOrNamespaceRefs then [] else

let ilTyconNames = getFakeContainerModulesFromTyconRefs (nenv.TyconsByAccessNames(fullyQualified).Values)

moduleOrNamespaceRefs
|> List.filter (fun modref ->
let demangledName = modref.DemangledModuleOrNamespaceName
IsInterestingModuleName demangledName && notFakeContainerModule ilTyconNames demangledName &&
EntityRefContainsSomethingAccessible ncenv m ad modref &&
not (IsTyconUnseen ad g ncenv.amap m modref))
|> List.map ItemForModuleOrNamespaceRef
GetVisibleNamespacesAndModulesAtPoint ncenv nenv fullyQualified m ad |> List.map ItemForModuleOrNamespaceRef

let recdTyCons =
nenv.TyconsByDemangledNameAndArity(fullyQualified).Values
Expand Down Expand Up @@ -5023,23 +4992,7 @@ let rec ResolvePartialLongIdentInModuleOrNamespaceForItem (ncenv: NameResolver)
// Collect up the accessible sub-modules. We must yield them even though `item` is not a module or namespace,
// otherwise we would not resolve long idents which have modules and namespaces in the middle (i.e. all long idents)

let moduleOrNamespaces =
mty.ModulesAndNamespacesByDemangledName
|> NameMap.range

if not (isNil moduleOrNamespaces) then
let ilTyconNames = getFakeContainerModulesFromTycons mty.TypesByAccessNames.Values

yield!
moduleOrNamespaces
|> List.filter (fun x ->
let demangledName = x.DemangledModuleOrNamespaceName
notFakeContainerModule ilTyconNames demangledName && IsInterestingModuleName demangledName)
|> List.map modref.NestedTyconRef
|> List.filter (fun tcref ->
not (IsTyconUnseen ad g ncenv.amap m tcref) &&
EntityRefContainsSomethingAccessible ncenv m ad tcref)
|> List.map ItemForModuleOrNamespaceRef
yield! GetAccessibleSubModules g ncenv modref m ad

let tycons =
mty.TypeDefinitions
Expand Down Expand Up @@ -5117,19 +5070,7 @@ let rec GetCompletionForItem (ncenv: NameResolver) (nenv: NameResolutionEnv) m a

match item with
| Item.ModuleOrNamespaces _ ->
let moduleOrNamespaceRefs =
nenv.ModulesAndNamespaces OpenQualified
|> NameMultiMap.range

if not (isNil moduleOrNamespaceRefs) then
let ilTyconNames = getFakeContainerModulesFromTyconRefs (nenv.TyconsByAccessNames(OpenQualified).Values)

for ns in moduleOrNamespaceRefs do
let demangledName = ns.DemangledModuleOrNamespaceName
if IsInterestingModuleName demangledName && notFakeContainerModule ilTyconNames demangledName
&& EntityRefContainsSomethingAccessible ncenv m ad ns
&& not (IsTyconUnseen ad g ncenv.amap m ns)
then yield ItemForModuleOrNamespaceRef ns
yield! GetVisibleNamespacesAndModulesAtPoint ncenv nenv OpenQualified m ad |> List.map ItemForModuleOrNamespaceRef

| Item.Types _ ->
for tcref in nenv.TyconsByDemangledNameAndArity(OpenQualified).Values do
Expand Down Expand Up @@ -5183,21 +5124,3 @@ let IsItemResolvable (ncenv: NameResolver) (nenv: NameResolutionEnv) m ad plid (
GetCompletionForItem ncenv nenv m ad plid item
|> Seq.exists (ItemsAreEffectivelyEqual ncenv.g item)
)

let GetVisibleNamespacesAndModulesAtPoint (ncenv: NameResolver) (nenv: NameResolutionEnv) m ad =
protectAssemblyExploration [] (fun () ->
let items =
nenv.ModulesAndNamespaces FullyQualifiedFlag.OpenQualified
|> NameMultiMap.range

if isNil items then [] else

let ilTyconNames = getFakeContainerModulesFromTyconRefs (nenv.TyconsByAccessNames(FullyQualifiedFlag.OpenQualified).Values)

items
|> List.filter (fun x ->
let demangledName = x.DemangledModuleOrNamespaceName
IsInterestingModuleName demangledName && notFakeContainerModule ilTyconNames demangledName
&& EntityRefContainsSomethingAccessible ncenv m ad x
&& not (IsTyconUnseen ad ncenv.g ncenv.amap m x))
)
2 changes: 1 addition & 1 deletion src/Compiler/Checking/NameResolution.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -822,7 +822,7 @@ val ResolveCompletionsInType:
Item list

val GetVisibleNamespacesAndModulesAtPoint:
NameResolver -> NameResolutionEnv -> range -> AccessorDomain -> ModuleOrNamespaceRef list
NameResolver -> NameResolutionEnv -> FullyQualifiedFlag -> range -> AccessorDomain -> ModuleOrNamespaceRef list

val IsItemResolvable: NameResolver -> NameResolutionEnv -> range -> AccessorDomain -> string list -> Item -> bool

Expand Down
2 changes: 1 addition & 1 deletion src/Compiler/Service/FSharpCheckerResults.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1435,7 +1435,7 @@ type internal TypeCheckInfo

member _.GetVisibleNamespacesAndModulesAtPosition(cursorPos: pos) : ModuleOrNamespaceRef list =
let (nenv, ad), m = GetBestEnvForPos cursorPos
GetVisibleNamespacesAndModulesAtPoint ncenv nenv m ad
GetVisibleNamespacesAndModulesAtPoint ncenv nenv OpenQualified m ad

/// Determines if a long ident is resolvable at a specific point.
member _.IsRelativeNameResolvable(cursorPos: pos, plid: string list, item: Item) : bool =
Expand Down