提交 3cb5b831 编写于 作者: E Eugene Auduchinok 提交者: Phillip Carter

Fix OpenDeclaration.AppliedScope inside recursive modules (#7868)

* Fix OpenDeclaration.AppliedScope inside recursive modules

* Add tests for open declarations applied scope

* Cherry-pick tests change
上级 3511ca3f
......@@ -4232,7 +4232,7 @@ type ValSpecResult = ValSpecResult of ParentRef * ValMemberInfoTransient option
type RecDefnBindingInfo = RecDefnBindingInfo of ContainerInfo * NewSlotsOK * DeclKind * SynBinding
type MutRecDataForOpen = MutRecDataForOpen of LongIdent * range
type MutRecDataForOpen = MutRecDataForOpen of LongIdent * range * appliedScope: range
type MutRecDataForModuleAbbrev = MutRecDataForModuleAbbrev of Ident * LongIdent * range
type MutRecSigsInitialData = MutRecShape<SynTypeDefnSig, SynValSig, SynComponentInfo, MutRecDataForModuleAbbrev, MutRecDataForOpen > list
......@@ -14030,7 +14030,7 @@ module MutRecBindingChecking =
let tycons = decls |> List.choose (function MutRecShape.Tycon d -> getTyconOpt d | _ -> None)
let mspecs = decls |> List.choose (function MutRecShape.Module (MutRecDefnsPhase2DataForModule (_, mspec), _) -> Some mspec | _ -> None)
let moduleAbbrevs = decls |> List.choose (function MutRecShape.ModuleAbbrev (MutRecDataForModuleAbbrev (id, mp, m)) -> Some (id, mp, m) | _ -> None)
let opens = decls |> List.choose (function MutRecShape.Open (MutRecDataForOpen (mp, m)) -> Some (mp, m) | _ -> None)
let opens = decls |> List.choose (function MutRecShape.Open (MutRecDataForOpen (mp, m, moduleRange)) -> Some (mp, m, moduleRange) | _ -> None)
let lets = decls |> List.collect (function MutRecShape.Lets binds -> getVals binds | _ -> [])
let exns = tycons |> List.filter (fun (tycon: Tycon) -> tycon.IsExceptionDecl)
......@@ -14056,7 +14056,7 @@ module MutRecBindingChecking =
// Add the modules being defined
let envForDecls = (envForDecls, mspecs) ||> List.fold ((if report then AddLocalSubModuleAndReport cenv.tcSink scopem else AddLocalSubModule) cenv.g cenv.amap m)
// Process the 'open' declarations
let envForDecls = (envForDecls, opens) ||> List.fold (fun env (mp, m) -> TcOpenDecl cenv.tcSink cenv.g cenv.amap m scopem env mp)
let envForDecls = (envForDecls, opens) ||> List.fold (fun env (mp, m, moduleRange) -> TcOpenDecl cenv.tcSink cenv.g cenv.amap m moduleRange env mp)
// Add the type definitions being defined
let envForDecls = (if report then AddLocalTyconsAndReport cenv.tcSink scopem else AddLocalTycons) cenv.g cenv.amap m tycons envForDecls
// Add the exception definitions being defined
......@@ -16931,13 +16931,13 @@ and TcSignatureElementsNonMutRec cenv parent typeNames endm env defs =
return! Eventually.fold (TcSignatureElementNonMutRec cenv parent typeNames endm) env defs
}
and TcSignatureElementsMutRec cenv parent typeNames endm mutRecNSInfo envInitial (defs: SynModuleSigDecl list) =
and TcSignatureElementsMutRec cenv parent typeNames m mutRecNSInfo envInitial (defs: SynModuleSigDecl list) =
eventually {
let m = match defs with [] -> endm | _ -> defs |> List.map (fun d -> d.Range) |> List.reduce unionRanges
let scopem = (defs, endm) ||> List.foldBack (fun h m -> unionRanges h.Range m)
let m = match defs with [] -> m | _ -> defs |> List.map (fun d -> d.Range) |> List.reduce unionRanges
let scopem = (defs, m) ||> List.foldBack (fun h m -> unionRanges h.Range m)
let mutRecDefns =
let rec loop isNamespace defs: MutRecSigsInitialData =
let rec loop isNamespace moduleRange defs: MutRecSigsInitialData =
((true, true), defs) ||> List.collectFold (fun (openOk, moduleAbbrevOk) def ->
match def with
| SynModuleSigDecl.Types (typeSpecs, _) ->
......@@ -16946,7 +16946,7 @@ and TcSignatureElementsMutRec cenv parent typeNames endm mutRecNSInfo envInitial
| SynModuleSigDecl.Open (lid, m) ->
if not openOk then errorR(Error(FSComp.SR.tcOpenFirstInMutRec(), m))
let decls = [ MutRecShape.Open (MutRecDataForOpen(lid, m)) ]
let decls = [ MutRecShape.Open (MutRecDataForOpen(lid, m, moduleRange)) ]
decls, (openOk, moduleAbbrevOk)
| SynModuleSigDecl.Exception (SynExceptionSig(exnRepr, members, _), _) ->
......@@ -16960,9 +16960,9 @@ and TcSignatureElementsMutRec cenv parent typeNames endm mutRecNSInfo envInitial
let decls = [ MutRecShape.Lets vspec ]
decls, (false, false)
| SynModuleSigDecl.NestedModule(compInfo, isRec, synDefs, _) ->
| SynModuleSigDecl.NestedModule(compInfo, isRec, synDefs, moduleRange) ->
if isRec then warning(Error(FSComp.SR.tcRecImplied(), compInfo.Range))
let mutRecDefs = loop false synDefs
let mutRecDefs = loop false moduleRange synDefs
let decls = [MutRecShape.Module (compInfo, mutRecDefs)]
decls, (false, false)
......@@ -16978,7 +16978,7 @@ and TcSignatureElementsMutRec cenv parent typeNames endm mutRecNSInfo envInitial
error(Error(FSComp.SR.tcUnsupportedMutRecDecl(), def.Range)))
|> fst
loop (match parent with ParentNone -> true | Parent _ -> false) defs
loop (match parent with ParentNone -> true | Parent _ -> false) m defs
return TcDeclarations.TcMutRecSignatureDecls cenv envInitial parent typeNames emptyUnscopedTyparEnv m scopem mutRecNSInfo mutRecDefns
}
......@@ -17244,14 +17244,14 @@ and TcModuleOrNamespaceElementsNonMutRec cenv parent typeNames endm (defsSoFar,
}
/// The mutually recursive case for a sequence of declarations (and nested modules)
and TcModuleOrNamespaceElementsMutRec cenv parent typeNames endm envInitial mutRecNSInfo (defs: SynModuleDecl list) =
and TcModuleOrNamespaceElementsMutRec cenv parent typeNames m envInitial mutRecNSInfo (defs: SynModuleDecl list) =
eventually {
let m = match defs with [] -> endm | _ -> defs |> List.map (fun d -> d.Range) |> List.reduce unionRanges
let scopem = (defs, endm) ||> List.foldBack (fun h m -> unionRanges h.Range m)
let m = match defs with [] -> m | _ -> defs |> List.map (fun d -> d.Range) |> List.reduce unionRanges
let scopem = (defs, m) ||> List.foldBack (fun h m -> unionRanges h.Range m)
let (mutRecDefns, (_, _, Attributes synAttrs)) =
let rec loop isNamespace attrs defs: (MutRecDefnsInitialData * _) =
let rec loop isNamespace moduleRange attrs defs: (MutRecDefnsInitialData * _) =
((true, true, attrs), defs) ||> List.collectFold (fun (openOk, moduleAbbrevOk, attrs) def ->
match ElimModuleDoBinding def with
......@@ -17268,15 +17268,15 @@ and TcModuleOrNamespaceElementsMutRec cenv parent typeNames endm envInitial mutR
else List.map (List.singleton >> MutRecShape.Lets) binds
binds, (false, false, attrs)
| SynModuleDecl.NestedModule(compInfo, isRec, synDefs, _isContinuingModule, _) ->
| SynModuleDecl.NestedModule(compInfo, isRec, synDefs, _isContinuingModule, moduleRange) ->
if isRec then warning(Error(FSComp.SR.tcRecImplied(), compInfo.Range))
let mutRecDefs, (_, _, attrs) = loop false attrs synDefs
let mutRecDefs, (_, _, attrs) = loop false moduleRange attrs synDefs
let decls = [MutRecShape.Module (compInfo, mutRecDefs)]
decls, (false, false, attrs)
| SynModuleDecl.Open (LongIdentWithDots(lid, _), m) ->
if not openOk then errorR(Error(FSComp.SR.tcOpenFirstInMutRec(), m))
let decls = [ MutRecShape.Open (MutRecDataForOpen(lid, m)) ]
let decls = [ MutRecShape.Open (MutRecDataForOpen(lid, m, moduleRange)) ]
decls, (openOk, moduleAbbrevOk, attrs)
| SynModuleDecl.Exception (SynExceptionDefn(repr, members, _), _m) ->
......@@ -17300,7 +17300,7 @@ and TcModuleOrNamespaceElementsMutRec cenv parent typeNames endm envInitial mutR
| (SynModuleDecl.NamespaceFragment _ as d) -> error(Error(FSComp.SR.tcUnsupportedMutRecDecl(), d.Range)))
loop (match parent with ParentNone -> true | Parent _ -> false) [] defs
loop (match parent with ParentNone -> true | Parent _ -> false) m [] defs
let tpenv = emptyUnscopedTyparEnv
let mutRecDefnsChecked, envAfter = TcDeclarations.TcMutRecDefinitions cenv envInitial parent typeNames tpenv m scopem mutRecNSInfo mutRecDefns
......
......@@ -304,6 +304,9 @@ let rec allSymbolsInEntities compGen (entities: IList<FSharpEntity>) =
yield! allSymbolsInEntities compGen e.NestedEntities ]
let getParseAndCheckResults (source: string) =
parseAndCheckScript("/home/user/Test.fsx", source)
let getSymbolUses (source: string) =
let _, typeCheckResults = parseAndCheckScript("/home/user/Test.fsx", source)
typeCheckResults.GetAllUsesOfAllSymbolsInFile() |> Async.RunSynchronously
......
......@@ -5529,3 +5529,55 @@ module M2 =
(((25, 5), (25, 21)), "open SomeUnusedModule")]
unusedOpensData |> shouldEqual expected
[<Test>]
let ``Opens in nested recursive modules`` () =
let _, checkResults = getParseAndCheckResults """
module rec Module
open System
module Nested =
open System
"""
checkResults.OpenDeclarations
|> Seq.filter (fun openDeclaration ->
match openDeclaration.Range with
| Some range -> range <> Range.rangeStartup
| _ -> false)
|> List.ofSeq
|> List.map(fun openDeclaration -> tups openDeclaration.AppliedScope)
|> shouldEqual
[ (2, 0), (7, 15)
(6, 0), (7, 15) ]
[<Test>]
let ``Opens in nested recursive modules - namespaces`` () =
let _, checkResults = getParseAndCheckResults """
namespace rec Ns1
open System
module Nested =
open System
namespace rec Ns2
open System
module Nested =
open System
"""
checkResults.OpenDeclarations
|> Seq.filter (fun openDeclaration ->
match openDeclaration.Range with
| Some range -> range <> Range.rangeStartup
| _ -> false)
|> List.ofSeq
|> List.map(fun openDeclaration -> tups openDeclaration.AppliedScope)
|> shouldEqual
[ (4, 5), (7, 15)
(6, 0), (7, 15)
(11, 5), (14, 15)
(13, 0), (14, 15) ]
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册