diff --git a/src/Compiler/Driver/GraphChecking/FileContentMapping.fs b/src/Compiler/Driver/GraphChecking/FileContentMapping.fs index 5c0ec529bda..234d200f4e3 100644 --- a/src/Compiler/Driver/GraphChecking/FileContentMapping.fs +++ b/src/Compiler/Driver/GraphChecking/FileContentMapping.fs @@ -307,9 +307,27 @@ let visitSynTypeConstraint (tc: SynTypeConstraint) : FileContentEntry list = | SynTypeConstraint.WhereTyparIsEnum(typeArgs = typeArgs) -> List.collect visitSynType typeArgs | SynTypeConstraint.WhereTyparIsDelegate(typeArgs = typeArgs) -> List.collect visitSynType typeArgs +/// Special case of `nameof Module` type of expression +let (|NameofExpr|_|) (e: SynExpr) = + let rec stripParen (e: SynExpr) = + match e with + | SynExpr.Paren(expr = expr) -> stripParen expr + | _ -> e + + match e with + | SynExpr.App(flag = ExprAtomicFlag.NonAtomic; isInfix = false; funcExpr = SynExpr.Ident nameofIdent; argExpr = moduleNameExpr) -> + if nameofIdent.idText <> "nameof" then + None + else + match stripParen moduleNameExpr with + | SynExpr.Ident moduleNameIdent -> Some moduleNameIdent + | _ -> None + | _ -> None + let visitSynExpr (e: SynExpr) : FileContentEntry list = let rec visit (e: SynExpr) (continuation: FileContentEntry list -> FileContentEntry list) : FileContentEntry list = match e with + | NameofExpr moduleNameIdent -> continuation [ visitIdentAsPotentialModuleName moduleNameIdent ] | SynExpr.Const _ -> continuation [] | SynExpr.Paren(expr = expr) -> visit expr continuation | SynExpr.Quote(operator = operator; quotedExpr = quotedExpr) -> @@ -394,8 +412,8 @@ let visitSynExpr (e: SynExpr) : FileContentEntry list = | SynExpr.IfThenElse(ifExpr = ifExpr; thenExpr = thenExpr; elseExpr = elseExpr) -> let continuations = List.map visit (ifExpr :: thenExpr :: Option.toList elseExpr) Continuation.concatenate continuations continuation - | SynExpr.Typar _ -> continuation [] - | SynExpr.Ident ident -> continuation [ visitIdentAsPotentialModuleName ident ] + | SynExpr.Typar _ + | SynExpr.Ident _ -> continuation [] | SynExpr.LongIdent(longDotId = longDotId) -> continuation (visitSynLongIdent longDotId) | SynExpr.LongIdentSet(longDotId, expr, _) -> visit expr (fun nodes -> visitSynLongIdent longDotId @ nodes |> continuation) | SynExpr.DotGet(expr = expr; longDotId = longDotId) -> @@ -522,9 +540,32 @@ let visitSynExpr (e: SynExpr) : FileContentEntry list = visit e id +/// Special case of `| nameof Module ->` type of pattern +let (|NameofPat|_|) (pat: SynPat) = + let rec stripPats p = + match p with + | SynPat.Paren(pat = pat) -> stripPats pat + | _ -> p + + match pat with + | SynPat.LongIdent(longDotId = SynLongIdent(id = [ nameofIdent ]); typarDecls = None; argPats = SynArgPats.Pats [ moduleNamePat ]) -> + if nameofIdent.idText <> "nameof" then + None + else + match stripPats moduleNamePat with + | SynPat.LongIdent( + longDotId = SynLongIdent.SynLongIdent(id = [ moduleNameIdent ]; dotRanges = []; trivia = [ None ]) + extraId = None + typarDecls = None + argPats = SynArgPats.Pats [] + accessibility = None) -> Some moduleNameIdent + | _ -> None + | _ -> None + let visitPat (p: SynPat) : FileContentEntry list = let rec visit (p: SynPat) (continuation: FileContentEntry list -> FileContentEntry list) : FileContentEntry list = match p with + | NameofPat moduleNameIdent -> continuation [ visitIdentAsPotentialModuleName moduleNameIdent ] | SynPat.Paren(pat = pat) -> visit pat continuation | SynPat.Typed(pat = pat; targetType = t) -> visit pat (fun nodes -> nodes @ visitSynType t) | SynPat.Const _ -> continuation [] @@ -543,10 +584,6 @@ let visitPat (p: SynPat) : FileContentEntry list = | SynPat.As(lhsPat, rhsPat, _) -> let continuations = List.map visit [ lhsPat; rhsPat ] Continuation.concatenate continuations continuation - // Special case of `| nameof Module ->` type of pattern - // We check for `Module` below - | SynPat.LongIdent(longDotId = SynLongIdent(id = [ moduleNameIdent ]); typarDecls = None; argPats = SynArgPats.Pats []) -> - continuation [ visitIdentAsPotentialModuleName moduleNameIdent ] | SynPat.LongIdent(longDotId = longDotId; typarDecls = typarDecls; argPats = argPats) -> continuation [