From 985b85c52f7fcf1f6aa9ff7c59b0fc0b673e0f54 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Thu, 14 Jan 2021 16:55:56 +0300 Subject: [PATCH 01/16] Diagnostics: add production rule index --- src/fsharp/CompilerDiagnostics.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsharp/CompilerDiagnostics.fs b/src/fsharp/CompilerDiagnostics.fs index c689c68deb3..d0f80e1da0e 100644 --- a/src/fsharp/CompilerDiagnostics.fs +++ b/src/fsharp/CompilerDiagnostics.fs @@ -1169,7 +1169,7 @@ let OutputPhasedErrorR (os: StringBuilder) (err: PhasedDiagnostic) (canSuggestNa printfn " ----" //printfn " state %d" state for rp in rps do - printfn " non-terminal %+A: ... " (Parser.prodIdxToNonTerminal rp) + printfn " non-terminal %+A (idx %d): ... " (Parser.prodIdxToNonTerminal rp) rp #endif match ctxt.CurrentToken with From 7bfec2c0058a5e9a9052b49d2998a78f2d8ed586 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Thu, 14 Jan 2021 17:37:29 +0300 Subject: [PATCH 02/16] Parser: fix recovery for unfinished match clause Fixes recovery for missing right hand sides: ``` match () with | x ``` --- src/fsharp/pars.fsy | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/src/fsharp/pars.fsy b/src/fsharp/pars.fsy index cbbdece5bd2..c163397510f 100644 --- a/src/fsharp/pars.fsy +++ b/src/fsharp/pars.fsy @@ -36,6 +36,9 @@ let debugPrint s = ignore s let exprFromParseError (e:SynExpr) = SynExpr.FromParseError (e, e.Range) +let unitExprFromRange m = SynExpr.Const (SynConst.Unit, m) +let unitExprFromParseError m = unitExprFromRange m |> exprFromParseError + let patFromParseError (e:SynPat) = SynPat.FromParseError(e, e.Range) // record bindings returned by the recdExprBindings rule has shape: @@ -2337,13 +2340,6 @@ opt_explicitValTyparDecls: | { SynValTyparDecls(None, true) } -opt_explicitValTyparDecls2: - | explicitValTyparDecls - { Some $1 } - - | /* EMPTY */ - { None } - /* Any tokens in this grammar must be added to the lex filter rule 'peekAdjacentTypars' */ /* See the F# specification "Lexical analysis of type applications and type parameter definitions" */ opt_typeConstraints: @@ -3103,17 +3099,26 @@ namePatPair: { ($1, $3) } constrPattern: - | atomicPatternLongIdent explicitValTyparDecls + | atomicPatternLongIdent explicitValTyparDecls { let vis, lid = $1 in SynPat.LongIdent (lid, None, Some $2, SynArgPats.Pats [], vis, lhs parseState) } - | atomicPatternLongIdent opt_explicitValTyparDecls2 atomicPatsOrNamePatPairs %prec pat_app - { let vis, lid = $1 in SynPat.LongIdent (lid, None, $2, $3, vis, lhs parseState) } + | atomicPatternLongIdent explicitValTyparDecls atomicPatsOrNamePatPairs %prec pat_app + { let vis, lid = $1 in SynPat.LongIdent (lid, None, Some $2, $3, vis, lhs parseState) } + + | atomicPatternLongIdent explicitValTyparDecls HIGH_PRECEDENCE_PAREN_APP atomicPatsOrNamePatPairs + { let vis, lid = $1 in SynPat.LongIdent (lid, None, Some $2, $4, vis, lhs parseState) } + + | atomicPatternLongIdent explicitValTyparDecls HIGH_PRECEDENCE_BRACK_APP atomicPatsOrNamePatPairs + { let vis, lid = $1 in SynPat.LongIdent (lid, None, Some $2, $4, vis, lhs parseState) } + + | atomicPatternLongIdent atomicPatsOrNamePatPairs %prec pat_app + { let vis, lid = $1 in SynPat.LongIdent (lid, None, None, $2, vis, lhs parseState) } - | atomicPatternLongIdent opt_explicitValTyparDecls2 HIGH_PRECEDENCE_PAREN_APP atomicPatsOrNamePatPairs - { let vis, lid = $1 in SynPat.LongIdent (lid, None, $2, $4, vis, lhs parseState) } + | atomicPatternLongIdent HIGH_PRECEDENCE_PAREN_APP atomicPatsOrNamePatPairs + { let vis, lid = $1 in SynPat.LongIdent (lid, None, None, $3, vis, lhs parseState) } - | atomicPatternLongIdent opt_explicitValTyparDecls2 HIGH_PRECEDENCE_BRACK_APP atomicPatsOrNamePatPairs - { let vis, lid = $1 in SynPat.LongIdent (lid, None, $2, $4, vis, lhs parseState) } + | atomicPatternLongIdent HIGH_PRECEDENCE_BRACK_APP atomicPatsOrNamePatPairs + { let vis, lid = $1 in SynPat.LongIdent (lid, None, None, $3, vis, lhs parseState) } | COLON_QMARK atomTypeOrAnonRecdType %prec pat_isinst { SynPat.IsInst($2, lhs parseState) } @@ -3994,7 +3999,7 @@ patternClauses: | Some e -> unionRanges patm e.Range | _ -> patm // silent recovery - [SynMatchClause(pat, guard, None, SynExpr.Const (SynConst.Unit, mLast.EndRange), m, DebugPointAtTarget.Yes)], mLast } + [SynMatchClause(pat, guard, None, unitExprFromParseError mLast.EndRange, m, DebugPointAtTarget.Yes)], mLast } patternGuard: | WHEN declExpr From 3b74b213451a7325c10618a19c810f5860085a1b Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Mon, 23 Aug 2021 17:07:02 +0300 Subject: [PATCH 03/16] Add tests --- tests/service/Common.fs | 13 ++++++ tests/service/ParserTests.fs | 81 +++++++++++++++++++++++------------- 2 files changed, 64 insertions(+), 30 deletions(-) diff --git a/tests/service/Common.fs b/tests/service/Common.fs index d0105acca52..e36c5449c1d 100644 --- a/tests/service/Common.fs +++ b/tests/service/Common.fs @@ -253,6 +253,19 @@ let getSingleModuleLikeDecl (input: ParsedInput) = | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ decl ])) -> decl | _ -> failwith "Could not get module decls" +let getSingleModuleMemberDecls (input: ParsedInput) = + match getSingleModuleLikeDecl input with + | SynModuleOrNamespace (decls = decls) -> decls + +let getSingleExprInModule (input: ParsedInput) = + match getSingleModuleLikeDecl input with + | SynModuleOrNamespace (decls = decls) -> + + match decls with + | [ SynModuleDecl.DoExpr (_, expr, _) ] -> expr + | _ -> failwith "Can't get single expression" + + let parseSourceCodeAndGetModule (source: string) = parseSourceCode ("test.fsx", source) |> getSingleModuleLikeDecl diff --git a/tests/service/ParserTests.fs b/tests/service/ParserTests.fs index 76acd1ba6aa..efc94289b32 100644 --- a/tests/service/ParserTests.fs +++ b/tests/service/ParserTests.fs @@ -1,46 +1,67 @@ -module Tests.Parser +module FSharp.Compiler.Service.Tests.Parser.Recovery open FSharp.Compiler.Service.Tests.Common open FSharp.Compiler.Syntax open NUnit.Framework -module Recovery = - [] - let ``Unfinished interface member`` () = - let parseResults = getParseResults """ +[] +let ``Interface impl - No members`` () = + let parseResults = getParseResults """ type T = interface I with member x.P2 = () let x = () """ - let (SynModuleOrNamespace (decls = decls)) = getSingleModuleLikeDecl parseResults - match decls with - | [ SynModuleDecl.Types ([ SynTypeDefn (typeRepr = SynTypeDefnRepr.ObjectModel (members = [ _; _ ])) ], _) - SynModuleDecl.Let _ ] -> () - | _ -> failwith "Unexpected tree" - - [] - let ``Union case 01 - of`` () = - let parseResults = getParseResults """ + match getSingleModuleMemberDecls parseResults with + | [ SynModuleDecl.Types ([ SynTypeDefn (typeRepr = SynTypeDefnRepr.ObjectModel (members = [ _; _ ])) ], _) + SynModuleDecl.Let _ ] -> () + | _ -> failwith "Unexpected tree" + + +[] +let ``Union case 01 - of`` () = + let parseResults = getParseResults """ type U1 = - | A of +| A of type U2 = - | B of - | C +| B of +| C let x = () - """ - let (|UnionWithCases|_|) typeDefn = - match typeDefn with - | SynTypeDefn (typeRepr = SynTypeDefnRepr.Simple (SynTypeDefnSimpleRepr.Union (unionCases = cases), _)) -> - cases |> List.map (fun (SynUnionCase (ident = ident)) -> ident.idText) |> Some - | _ -> None - - let (SynModuleOrNamespace (decls = decls)) = getSingleModuleLikeDecl parseResults - match decls with - | [ SynModuleDecl.Types ([ UnionWithCases ["A"]], _) - SynModuleDecl.Types ([ UnionWithCases ["B"; "C"] ], _) - SynModuleDecl.Let _ ] -> () - | _ -> failwith "Unexpected tree" +""" + let (|UnionWithCases|_|) typeDefn = + match typeDefn with + | SynTypeDefn (typeRepr = SynTypeDefnRepr.Simple (SynTypeDefnSimpleRepr.Union (unionCases = cases), _)) -> + cases |> List.map (fun (SynUnionCase (ident = ident)) -> ident.idText) |> Some + | _ -> None + + match getSingleModuleMemberDecls parseResults with + | [ SynModuleDecl.Types ([ UnionWithCases ["A"]], _) + SynModuleDecl.Types ([ UnionWithCases ["B"; "C"] ], _) + SynModuleDecl.Let _ ] -> () + | _ -> failwith "Unexpected tree" + + +[] +let ``Match clause 01`` () = + let parseResults = getParseResults """ +match () with +| x +""" + match getSingleExprInModule parseResults with + | SynExpr.Match (_, _, [ SynMatchClause (_, _, _, SynExpr.FromParseError _, _, _) ], _) -> () + | _ -> failwith "Unexpected tree" + + +[] +let ``Match clause 02 - When`` () = + let parseResults = getParseResults """ +match () with +| x when true +""" + + match getSingleExprInModule parseResults with + | SynExpr.Match (_, _, [ SynMatchClause (_, _, _, SynExpr.FromParseError _, _, _) ], _) -> () + | _ -> failwith "Unexpected tree" From fce6e1b6978f7e1c1c7cac88c3b6c5b5b5a859f0 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Mon, 23 Aug 2021 17:29:50 +0300 Subject: [PATCH 04/16] Add recovery near to next clause --- src/fsharp/pars.fsy | 13 ++++++++----- tests/service/ParserTests.fs | 12 ++++++++++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/fsharp/pars.fsy b/src/fsharp/pars.fsy index c163397510f..8d3bb596036 100644 --- a/src/fsharp/pars.fsy +++ b/src/fsharp/pars.fsy @@ -3975,6 +3975,12 @@ patternClauses: let m = unionRanges resultExpr.Range patm (SynMatchClause(pat, guard, (Some mArrow), resultExpr, m, DebugPointAtTarget.Yes) :: clauses), mLast } + | patternAndGuard error BAR patternClauses + { let pat, guard, patm = $1 + let clauses, mLast = $4 + let m = guard |> Option.map (fun e -> unionRanges patm e.Range) |> Option.defaultValue patm + (SynMatchClause(pat, guard, None, unitExprFromParseError mLast.EndRange, m, DebugPointAtTarget.Yes) :: clauses), mLast } + | patternAndGuard patternResult BAR error { let pat, guard, patm = $1 let mArrow, resultExpr = $2 @@ -3994,12 +4000,9 @@ patternClauses: | patternAndGuard error { let pat, guard, patm = $1 let mLast = rhs parseState 2 - let m = - match guard with - | Some e -> unionRanges patm e.Range - | _ -> patm + let m = guard |> Option.map (fun e -> unionRanges patm e.Range) |> Option.defaultValue patm // silent recovery - [SynMatchClause(pat, guard, None, unitExprFromParseError mLast.EndRange, m, DebugPointAtTarget.Yes)], mLast } + [SynMatchClause(pat, guard, None, unitExprFromParseError mLast.EndRange, m, DebugPointAtTarget.Yes)], mLast } patternGuard: | WHEN declExpr diff --git a/tests/service/ParserTests.fs b/tests/service/ParserTests.fs index efc94289b32..407468f49ee 100644 --- a/tests/service/ParserTests.fs +++ b/tests/service/ParserTests.fs @@ -65,3 +65,15 @@ match () with match getSingleExprInModule parseResults with | SynExpr.Match (_, _, [ SynMatchClause (_, _, _, SynExpr.FromParseError _, _, _) ], _) -> () | _ -> failwith "Unexpected tree" + +[] +let ``Match clause 03 - When`` () = + let parseResults = getParseResults """ +match () with +| x when true +| _ -> () +""" + + match getSingleExprInModule parseResults with + | SynExpr.Match (_, _, [ SynMatchClause (_, _, _, SynExpr.FromParseError _, _, _); _ ], _) -> () + | _ -> failwith "Unexpected tree" From a42670e70686526c39908b2750686875142492aa Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Mon, 23 Aug 2021 17:31:34 +0300 Subject: [PATCH 05/16] Restore indent in test data --- tests/service/ParserTests.fs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/service/ParserTests.fs b/tests/service/ParserTests.fs index 407468f49ee..5cea5f275ee 100644 --- a/tests/service/ParserTests.fs +++ b/tests/service/ParserTests.fs @@ -23,11 +23,11 @@ let x = () let ``Union case 01 - of`` () = let parseResults = getParseResults """ type U1 = -| A of + | A of type U2 = -| B of -| C + | B of + | C let x = () """ From e272ca71b585c5d4a3ebb9fdad608e7260713972 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Tue, 24 Aug 2021 14:11:20 +0300 Subject: [PATCH 06/16] Update desktop test baselines --- tests/fsharp/typecheck/sigs/neg104.bsl | 2 +- tests/fsharp/typecheck/sigs/neg104.vsbsl | 4 +--- tests/fsharp/typecheck/sigs/neg80.vsbsl | 4 ---- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/tests/fsharp/typecheck/sigs/neg104.bsl b/tests/fsharp/typecheck/sigs/neg104.bsl index 022a8e3e4b2..e93db87ef8d 100644 --- a/tests/fsharp/typecheck/sigs/neg104.bsl +++ b/tests/fsharp/typecheck/sigs/neg104.bsl @@ -7,7 +7,7 @@ neg104.fs(20,23,20,24): parse error FS0010: Incomplete structured construct at o neg104.fs(23,25,23,26): parse error FS0010: Incomplete structured construct at or before this point in expression -neg104.fs(26,28,26,29): parse error FS0010: Incomplete structured construct at or before this point in pattern +neg104.fs(26,28,26,29): parse error FS0010: Incomplete structured construct at or before this point in pattern matching. Expected '->' or other token. neg104.fs(29,31,29,32): parse error FS0010: Incomplete structured construct at or before this point in pattern matching diff --git a/tests/fsharp/typecheck/sigs/neg104.vsbsl b/tests/fsharp/typecheck/sigs/neg104.vsbsl index e4e6e79397a..87d4a4e89db 100644 --- a/tests/fsharp/typecheck/sigs/neg104.vsbsl +++ b/tests/fsharp/typecheck/sigs/neg104.vsbsl @@ -7,7 +7,7 @@ neg104.fs(20,23,20,24): parse error FS0010: Incomplete structured construct at o neg104.fs(23,25,23,26): parse error FS0010: Incomplete structured construct at or before this point in expression -neg104.fs(26,28,26,29): parse error FS0010: Incomplete structured construct at or before this point in pattern +neg104.fs(26,28,26,29): parse error FS0010: Incomplete structured construct at or before this point in pattern matching. Expected '->' or other token. neg104.fs(29,31,29,32): parse error FS0010: Incomplete structured construct at or before this point in pattern matching @@ -27,8 +27,6 @@ neg104.fs(20,9,20,22): typecheck error FS0025: Incomplete pattern matches on thi neg104.fs(23,9,23,22): typecheck error FS0025: Incomplete pattern matches on this expression. -neg104.fs(26,9,26,22): typecheck error FS0025: Incomplete pattern matches on this expression. - neg104.fs(32,21,32,26): typecheck error FS0003: This value is not a function and cannot be applied. neg104.fs(35,9,35,18): typecheck error FS0748: This construct may only be used within computation expressions. To return a value from an ordinary function simply write the expression without 'return'. diff --git a/tests/fsharp/typecheck/sigs/neg80.vsbsl b/tests/fsharp/typecheck/sigs/neg80.vsbsl index 26c5bcafa24..63aba7d33db 100644 --- a/tests/fsharp/typecheck/sigs/neg80.vsbsl +++ b/tests/fsharp/typecheck/sigs/neg80.vsbsl @@ -2,7 +2,3 @@ neg80.fsx(79,5,79,6): parse error FS0010: Unexpected symbol '|' in pattern matching neg80.fsx(79,5,79,6): parse error FS0010: Unexpected symbol '|' in pattern matching - -neg80.fsx(79,6,79,6): typecheck error FS0001: All branches of a pattern match expression must return values implicitly convertible to the type of the first branch, which here is 'string'. This branch returns a value of type 'unit'. - -neg80.fsx(76,11,76,13): typecheck error FS0025: Incomplete pattern matches on this expression. For example, the value 'Horizontal (_, _)' may indicate a case not covered by the pattern(s). From 9a17ce408326a0258e80d21b933c77a2b03b8486 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Tue, 24 Aug 2021 15:56:21 +0300 Subject: [PATCH 07/16] Update FSharpQA test baselines --- .../IdentifiersAndKeywords/E_KeywordIdent01.fs | 2 +- .../PatternMatching/TypeConstraint/E_typecontraint01.fs | 5 +++-- .../Source/Diagnostics/General/E_UnexpectedSymbol01.fs | 2 +- tests/fsharpqa/Source/InteractiveSession/Misc/E_let_id.fsx | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/tests/fsharpqa/Source/Conformance/LexicalAnalysis/IdentifiersAndKeywords/E_KeywordIdent01.fs b/tests/fsharpqa/Source/Conformance/LexicalAnalysis/IdentifiersAndKeywords/E_KeywordIdent01.fs index 7c185078802..5aeec2e163f 100644 --- a/tests/fsharpqa/Source/Conformance/LexicalAnalysis/IdentifiersAndKeywords/E_KeywordIdent01.fs +++ b/tests/fsharpqa/Source/Conformance/LexicalAnalysis/IdentifiersAndKeywords/E_KeywordIdent01.fs @@ -2,7 +2,7 @@ #light //Unexpected keyword 'type' in binding -//Unexpected keyword 'class' in pattern +//Unexpected keyword 'class' in binding. Expected '=' or other token. let type = 2 diff --git a/tests/fsharpqa/Source/Conformance/PatternMatching/TypeConstraint/E_typecontraint01.fs b/tests/fsharpqa/Source/Conformance/PatternMatching/TypeConstraint/E_typecontraint01.fs index b43a8a2927d..4ce19c52666 100644 --- a/tests/fsharpqa/Source/Conformance/PatternMatching/TypeConstraint/E_typecontraint01.fs +++ b/tests/fsharpqa/Source/Conformance/PatternMatching/TypeConstraint/E_typecontraint01.fs @@ -2,8 +2,9 @@ // Regression test for FSHARP1.0:1525 // type constraints on pattern matching are deprecated and are now errors (used to be warnings) // As of Beta2, we are not even giving the deprecation error. -//Unexpected symbol ':>' in pattern$ -//Unmatched '\('$ +//Unexpected symbol ':>' in pattern. Expected '\)' or other token. +//Unmatched '\('$ +//Files in libraries or multiple-file applications must begin with a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule'. Only the last source file of an application may omit such a declaration. type A() = class end diff --git a/tests/fsharpqa/Source/Diagnostics/General/E_UnexpectedSymbol01.fs b/tests/fsharpqa/Source/Diagnostics/General/E_UnexpectedSymbol01.fs index 67024e490cc..cd83283d263 100644 --- a/tests/fsharpqa/Source/Diagnostics/General/E_UnexpectedSymbol01.fs +++ b/tests/fsharpqa/Source/Diagnostics/General/E_UnexpectedSymbol01.fs @@ -1,7 +1,7 @@ // #Regression #Diagnostics // Regression test for FSHARP1.0:2099 // Regression test for FSHARP1.0:2670 -//Unexpected symbol '<-' in pattern +//Unexpected symbol '<-' in binding. Expected '=' or other token. //The block following this 'let' is unfinished. Every code block is an expression and must have a result. 'let' cannot be the final code element in a block. Consider giving this block an explicit result. //lambda diff --git a/tests/fsharpqa/Source/InteractiveSession/Misc/E_let_id.fsx b/tests/fsharpqa/Source/InteractiveSession/Misc/E_let_id.fsx index 9fac116ed39..09150ddb8e8 100644 --- a/tests/fsharpqa/Source/InteractiveSession/Misc/E_let_id.fsx +++ b/tests/fsharpqa/Source/InteractiveSession/Misc/E_let_id.fsx @@ -1,5 +1,5 @@ // #Regression #NoMT #FSI // Regression test for FSHARP1.0:5629 -//Incomplete structured construct at or before this point in pattern$ +//Incomplete structured construct at or before this point in binding. Expected '=' or other token. let f;; exit 1;; From 7e07e123e4bc5829e4ba4d085ed24a36cfee925b Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Fri, 27 Aug 2021 14:53:35 +0300 Subject: [PATCH 08/16] Fix recovered patterns ranges --- src/fsharp/SyntaxTree.fs | 5 +++++ src/fsharp/SyntaxTree.fsi | 2 ++ src/fsharp/pars.fsy | 32 +++++++++++++++++++++++--------- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/fsharp/SyntaxTree.fs b/src/fsharp/SyntaxTree.fs index 7d12a8e6965..76bfd822d31 100644 --- a/src/fsharp/SyntaxTree.fs +++ b/src/fsharp/SyntaxTree.fs @@ -1015,6 +1015,11 @@ type SynArgPats = pats: (Ident * SynPat) list * range: range + member x.Patterns = + match x with + | Pats pats -> pats + | NamePatPairs (pats, _) -> pats |> List.map snd + [] type SynPat = diff --git a/src/fsharp/SyntaxTree.fsi b/src/fsharp/SyntaxTree.fsi index 8e676ea3b4e..97a766b8ff5 100644 --- a/src/fsharp/SyntaxTree.fsi +++ b/src/fsharp/SyntaxTree.fsi @@ -1148,6 +1148,8 @@ type SynArgPats = pats: (Ident * SynPat) list * range: range + member Patterns: SynPat list + /// Represents a syntax tree for an F# pattern [] type SynPat = diff --git a/src/fsharp/pars.fsy b/src/fsharp/pars.fsy index 8d3bb596036..5441278d917 100644 --- a/src/fsharp/pars.fsy +++ b/src/fsharp/pars.fsy @@ -319,6 +319,7 @@ let rangeOfLongIdent(lid:LongIdent) = %type ident %type typ typEOF %type tyconSpfnList +%type atomicPatsOrNamePatPairs %type patternResult %type declExpr %type minusExpr @@ -3100,25 +3101,38 @@ namePatPair: constrPattern: | atomicPatternLongIdent explicitValTyparDecls - { let vis, lid = $1 in SynPat.LongIdent (lid, None, Some $2, SynArgPats.Pats [], vis, lhs parseState) } + { let vis, lid = $1 + SynPat.LongIdent (lid, None, Some $2, SynArgPats.Pats [], vis, lhs parseState) } | atomicPatternLongIdent explicitValTyparDecls atomicPatsOrNamePatPairs %prec pat_app - { let vis, lid = $1 in SynPat.LongIdent (lid, None, Some $2, $3, vis, lhs parseState) } + { let vis, lid = $1 + let m = (rhs2 parseState 1 2, $3.Patterns) ||> unionRangeWithListBy (fun p -> p.Range) + SynPat.LongIdent (lid, None, Some $2, $3, vis, m) } | atomicPatternLongIdent explicitValTyparDecls HIGH_PRECEDENCE_PAREN_APP atomicPatsOrNamePatPairs - { let vis, lid = $1 in SynPat.LongIdent (lid, None, Some $2, $4, vis, lhs parseState) } + { let vis, lid = $1 + let m = (rhs2 parseState 1 2, $4.Patterns) ||> unionRangeWithListBy (fun p -> p.Range) + SynPat.LongIdent (lid, None, Some $2, $4, vis, m) } | atomicPatternLongIdent explicitValTyparDecls HIGH_PRECEDENCE_BRACK_APP atomicPatsOrNamePatPairs - { let vis, lid = $1 in SynPat.LongIdent (lid, None, Some $2, $4, vis, lhs parseState) } + { let vis, lid = $1 + let m = (rhs2 parseState 1 2, $4.Patterns) ||> unionRangeWithListBy (fun p -> p.Range) + SynPat.LongIdent (lid, None, Some $2, $4, vis, m) } | atomicPatternLongIdent atomicPatsOrNamePatPairs %prec pat_app - { let vis, lid = $1 in SynPat.LongIdent (lid, None, None, $2, vis, lhs parseState) } + { let vis, lid = $1 + let m = (rhs parseState 1, $2.Patterns) ||> unionRangeWithListBy (fun p -> p.Range) + SynPat.LongIdent (lid, None, None, $2, vis, m) } | atomicPatternLongIdent HIGH_PRECEDENCE_PAREN_APP atomicPatsOrNamePatPairs - { let vis, lid = $1 in SynPat.LongIdent (lid, None, None, $3, vis, lhs parseState) } + { let vis, lid = $1 + let m = (rhs parseState 1, $3.Patterns) ||> unionRangeWithListBy (fun p -> p.Range) + SynPat.LongIdent (lid, None, None, $3, vis, m) } | atomicPatternLongIdent HIGH_PRECEDENCE_BRACK_APP atomicPatsOrNamePatPairs - { let vis, lid = $1 in SynPat.LongIdent (lid, None, None, $3, vis, lhs parseState) } + { let vis, lid = $1 + let m = (rhs parseState 1, $3.Patterns) ||> unionRangeWithListBy (fun p -> p.Range) + SynPat.LongIdent (lid, None, None, $3, vis, m) } | COLON_QMARK atomTypeOrAnonRecdType %prec pat_isinst { SynPat.IsInst($2, lhs parseState) } @@ -3979,7 +3993,7 @@ patternClauses: { let pat, guard, patm = $1 let clauses, mLast = $4 let m = guard |> Option.map (fun e -> unionRanges patm e.Range) |> Option.defaultValue patm - (SynMatchClause(pat, guard, None, unitExprFromParseError mLast.EndRange, m, DebugPointAtTarget.Yes) :: clauses), mLast } + (SynMatchClause(pat, guard, None, unitExprFromParseError m.EndRange, m, DebugPointAtTarget.Yes) :: clauses), mLast } | patternAndGuard patternResult BAR error { let pat, guard, patm = $1 @@ -4002,7 +4016,7 @@ patternClauses: let mLast = rhs parseState 2 let m = guard |> Option.map (fun e -> unionRanges patm e.Range) |> Option.defaultValue patm // silent recovery - [SynMatchClause(pat, guard, None, unitExprFromParseError mLast.EndRange, m, DebugPointAtTarget.Yes)], mLast } + [SynMatchClause(pat, guard, None, unitExprFromParseError m.EndRange, m, DebugPointAtTarget.Yes)], mLast } patternGuard: | WHEN declExpr From 6a695be34230a7b56c2e43c7e3a2154bc0083447 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Fri, 27 Aug 2021 14:53:46 +0300 Subject: [PATCH 09/16] Try to fix Desktop test suite --- src/fsharp/service/ServiceParsedInputOps.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsharp/service/ServiceParsedInputOps.fs b/src/fsharp/service/ServiceParsedInputOps.fs index eff845781d5..9df1f3c394d 100644 --- a/src/fsharp/service/ServiceParsedInputOps.fs +++ b/src/fsharp/service/ServiceParsedInputOps.fs @@ -1004,7 +1004,7 @@ module ParsedInput = | SynPat.Tuple(_, pats, _) -> pats |> List.tryPick visitParam | _ -> visitParam pat - | SynPat.Wild range when rangeContainsPos range pos -> + | SynPat.Wild range | SynPat.FromParseError (_, range) when rangeContainsPos range pos -> // let foo (x| Some CompletionContext.Invalid | _ -> visitParam pat From 2b82f1b3a3cd48f105988a54b1ea086f617942e3 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Fri, 27 Aug 2021 15:20:34 +0300 Subject: [PATCH 10/16] Update surface area --- ...erService.SurfaceArea.netstandard.expected | 48 ++++++++++--------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.CompilerService.SurfaceArea.netstandard.expected b/tests/FSharp.Compiler.Service.Tests/FSharp.CompilerService.SurfaceArea.netstandard.expected index 15cf4603032..07fb8a7e5c4 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.CompilerService.SurfaceArea.netstandard.expected +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.CompilerService.SurfaceArea.netstandard.expected @@ -5239,6 +5239,29 @@ FSharp.Compiler.Syntax.DebugPointAtSwitch: Int32 GetHashCode(System.Collections. FSharp.Compiler.Syntax.DebugPointAtSwitch: Int32 Tag FSharp.Compiler.Syntax.DebugPointAtSwitch: Int32 get_Tag() FSharp.Compiler.Syntax.DebugPointAtSwitch: System.String ToString() +FSharp.Compiler.Syntax.DebugPointAtTarget +FSharp.Compiler.Syntax.DebugPointAtTarget+Tags: Int32 No +FSharp.Compiler.Syntax.DebugPointAtTarget+Tags: Int32 Yes +FSharp.Compiler.Syntax.DebugPointAtTarget: Boolean Equals(FSharp.Compiler.Syntax.DebugPointAtTarget) +FSharp.Compiler.Syntax.DebugPointAtTarget: Boolean Equals(System.Object) +FSharp.Compiler.Syntax.DebugPointAtTarget: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.Syntax.DebugPointAtTarget: Boolean IsNo +FSharp.Compiler.Syntax.DebugPointAtTarget: Boolean IsYes +FSharp.Compiler.Syntax.DebugPointAtTarget: Boolean get_IsNo() +FSharp.Compiler.Syntax.DebugPointAtTarget: Boolean get_IsYes() +FSharp.Compiler.Syntax.DebugPointAtTarget: FSharp.Compiler.Syntax.DebugPointAtTarget No +FSharp.Compiler.Syntax.DebugPointAtTarget: FSharp.Compiler.Syntax.DebugPointAtTarget Yes +FSharp.Compiler.Syntax.DebugPointAtTarget: FSharp.Compiler.Syntax.DebugPointAtTarget get_No() +FSharp.Compiler.Syntax.DebugPointAtTarget: FSharp.Compiler.Syntax.DebugPointAtTarget get_Yes() +FSharp.Compiler.Syntax.DebugPointAtTarget: FSharp.Compiler.Syntax.DebugPointAtTarget+Tags +FSharp.Compiler.Syntax.DebugPointAtTarget: Int32 CompareTo(FSharp.Compiler.Syntax.DebugPointAtTarget) +FSharp.Compiler.Syntax.DebugPointAtTarget: Int32 CompareTo(System.Object) +FSharp.Compiler.Syntax.DebugPointAtTarget: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.Syntax.DebugPointAtTarget: Int32 GetHashCode() +FSharp.Compiler.Syntax.DebugPointAtTarget: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.Syntax.DebugPointAtTarget: Int32 Tag +FSharp.Compiler.Syntax.DebugPointAtTarget: Int32 get_Tag() +FSharp.Compiler.Syntax.DebugPointAtTarget: System.String ToString() FSharp.Compiler.Syntax.DebugPointAtTry FSharp.Compiler.Syntax.DebugPointAtTry+Tags: Int32 Body FSharp.Compiler.Syntax.DebugPointAtTry+Tags: Int32 No @@ -5310,29 +5333,6 @@ FSharp.Compiler.Syntax.DebugPointAtWith: Int32 GetHashCode(System.Collections.IE FSharp.Compiler.Syntax.DebugPointAtWith: Int32 Tag FSharp.Compiler.Syntax.DebugPointAtWith: Int32 get_Tag() FSharp.Compiler.Syntax.DebugPointAtWith: System.String ToString() -FSharp.Compiler.Syntax.DebugPointAtTarget -FSharp.Compiler.Syntax.DebugPointAtTarget+Tags: Int32 No -FSharp.Compiler.Syntax.DebugPointAtTarget+Tags: Int32 Yes -FSharp.Compiler.Syntax.DebugPointAtTarget: Boolean Equals(FSharp.Compiler.Syntax.DebugPointAtTarget) -FSharp.Compiler.Syntax.DebugPointAtTarget: Boolean Equals(System.Object) -FSharp.Compiler.Syntax.DebugPointAtTarget: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -FSharp.Compiler.Syntax.DebugPointAtTarget: Boolean IsNo -FSharp.Compiler.Syntax.DebugPointAtTarget: Boolean IsYes -FSharp.Compiler.Syntax.DebugPointAtTarget: Boolean get_IsNo() -FSharp.Compiler.Syntax.DebugPointAtTarget: Boolean get_IsYes() -FSharp.Compiler.Syntax.DebugPointAtTarget: FSharp.Compiler.Syntax.DebugPointAtTarget No -FSharp.Compiler.Syntax.DebugPointAtTarget: FSharp.Compiler.Syntax.DebugPointAtTarget Yes -FSharp.Compiler.Syntax.DebugPointAtTarget: FSharp.Compiler.Syntax.DebugPointAtTarget get_No() -FSharp.Compiler.Syntax.DebugPointAtTarget: FSharp.Compiler.Syntax.DebugPointAtTarget get_Yes() -FSharp.Compiler.Syntax.DebugPointAtTarget: FSharp.Compiler.Syntax.DebugPointAtTarget+Tags -FSharp.Compiler.Syntax.DebugPointAtTarget: Int32 CompareTo(FSharp.Compiler.Syntax.DebugPointAtTarget) -FSharp.Compiler.Syntax.DebugPointAtTarget: Int32 CompareTo(System.Object) -FSharp.Compiler.Syntax.DebugPointAtTarget: Int32 CompareTo(System.Object, System.Collections.IComparer) -FSharp.Compiler.Syntax.DebugPointAtTarget: Int32 GetHashCode() -FSharp.Compiler.Syntax.DebugPointAtTarget: Int32 GetHashCode(System.Collections.IEqualityComparer) -FSharp.Compiler.Syntax.DebugPointAtTarget: Int32 Tag -FSharp.Compiler.Syntax.DebugPointAtTarget: Int32 get_Tag() -FSharp.Compiler.Syntax.DebugPointAtTarget: System.String ToString() FSharp.Compiler.Syntax.ExprAtomicFlag FSharp.Compiler.Syntax.ExprAtomicFlag: FSharp.Compiler.Syntax.ExprAtomicFlag Atomic FSharp.Compiler.Syntax.ExprAtomicFlag: FSharp.Compiler.Syntax.ExprAtomicFlag NonAtomic @@ -5728,6 +5728,8 @@ FSharp.Compiler.Syntax.SynArgPats: FSharp.Compiler.Syntax.SynArgPats+Pats FSharp.Compiler.Syntax.SynArgPats: FSharp.Compiler.Syntax.SynArgPats+Tags FSharp.Compiler.Syntax.SynArgPats: Int32 Tag FSharp.Compiler.Syntax.SynArgPats: Int32 get_Tag() +FSharp.Compiler.Syntax.SynArgPats: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynPat] Patterns +FSharp.Compiler.Syntax.SynArgPats: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynPat] get_Patterns() FSharp.Compiler.Syntax.SynArgPats: System.String ToString() FSharp.Compiler.Syntax.SynAttribute FSharp.Compiler.Syntax.SynAttribute: Boolean AppliesToGetterAndSetter From fcb54ab4f031081da62069ef39e2057f0a2614b3 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Fri, 27 Aug 2021 15:33:02 +0300 Subject: [PATCH 11/16] Better diagnostics --- src/fsharp/pars.fsy | 47 +++++++++++++++++++++--------------- tests/service/ParserTests.fs | 6 ++--- 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/src/fsharp/pars.fsy b/src/fsharp/pars.fsy index 5441278d917..d7388a9969c 100644 --- a/src/fsharp/pars.fsy +++ b/src/fsharp/pars.fsy @@ -36,9 +36,6 @@ let debugPrint s = ignore s let exprFromParseError (e:SynExpr) = SynExpr.FromParseError (e, e.Range) -let unitExprFromRange m = SynExpr.Const (SynConst.Unit, m) -let unitExprFromParseError m = unitExprFromRange m |> exprFromParseError - let patFromParseError (e:SynPat) = SynPat.FromParseError(e, e.Range) // record bindings returned by the recdExprBindings rule has shape: @@ -319,7 +316,8 @@ let rangeOfLongIdent(lid:LongIdent) = %type ident %type typ typEOF %type tyconSpfnList -%type atomicPatsOrNamePatPairs +%type atomicPatsOrNamePatPairs +%type atomicPatterns %type patternResult %type declExpr %type minusExpr @@ -3106,33 +3104,39 @@ constrPattern: | atomicPatternLongIdent explicitValTyparDecls atomicPatsOrNamePatPairs %prec pat_app { let vis, lid = $1 - let m = (rhs2 parseState 1 2, $3.Patterns) ||> unionRangeWithListBy (fun p -> p.Range) - SynPat.LongIdent (lid, None, Some $2, $3, vis, m) } + let args, argsM = $3 + let m = unionRanges (rhs2 parseState 1 2) argsM + SynPat.LongIdent (lid, None, Some $2, args, vis, m) } | atomicPatternLongIdent explicitValTyparDecls HIGH_PRECEDENCE_PAREN_APP atomicPatsOrNamePatPairs { let vis, lid = $1 - let m = (rhs2 parseState 1 2, $4.Patterns) ||> unionRangeWithListBy (fun p -> p.Range) - SynPat.LongIdent (lid, None, Some $2, $4, vis, m) } + let args, argsM = $4 + let m = unionRanges (rhs2 parseState 1 2) argsM + SynPat.LongIdent (lid, None, Some $2, args, vis, m) } | atomicPatternLongIdent explicitValTyparDecls HIGH_PRECEDENCE_BRACK_APP atomicPatsOrNamePatPairs { let vis, lid = $1 - let m = (rhs2 parseState 1 2, $4.Patterns) ||> unionRangeWithListBy (fun p -> p.Range) - SynPat.LongIdent (lid, None, Some $2, $4, vis, m) } + let args, argsM = $4 + let m = unionRanges (rhs2 parseState 1 2) argsM + SynPat.LongIdent (lid, None, Some $2, args, vis, m) } | atomicPatternLongIdent atomicPatsOrNamePatPairs %prec pat_app { let vis, lid = $1 - let m = (rhs parseState 1, $2.Patterns) ||> unionRangeWithListBy (fun p -> p.Range) - SynPat.LongIdent (lid, None, None, $2, vis, m) } + let args, argsM = $2 + let m = unionRanges (rhs parseState 1) argsM + SynPat.LongIdent (lid, None, None, args, vis, m) } | atomicPatternLongIdent HIGH_PRECEDENCE_PAREN_APP atomicPatsOrNamePatPairs { let vis, lid = $1 - let m = (rhs parseState 1, $3.Patterns) ||> unionRangeWithListBy (fun p -> p.Range) - SynPat.LongIdent (lid, None, None, $3, vis, m) } + let args, argsM = $3 + let m = unionRanges (rhs parseState 1) argsM + SynPat.LongIdent (lid, None, None, args, vis, m) } | atomicPatternLongIdent HIGH_PRECEDENCE_BRACK_APP atomicPatsOrNamePatPairs { let vis, lid = $1 - let m = (rhs parseState 1, $3.Patterns) ||> unionRangeWithListBy (fun p -> p.Range) - SynPat.LongIdent (lid, None, None, $3, vis, m) } + let args, argsM = $3 + let m = unionRanges (rhs parseState 1) argsM + SynPat.LongIdent (lid, None, None, args, vis, m) } | COLON_QMARK atomTypeOrAnonRecdType %prec pat_isinst { SynPat.IsInst($2, lhs parseState) } @@ -3142,10 +3146,13 @@ constrPattern: atomicPatsOrNamePatPairs: | LPAREN namePatPairs rparen - { SynArgPats.NamePatPairs $2 } + { let m = rhs2 parseState 1 3 + SynArgPats.NamePatPairs $2, m } | atomicPatterns - { SynArgPats.Pats $1 } + { let mWhole = rhs parseState 1 + let m = (mWhole.StartRange, $1) ||> unionRangeWithListBy (fun p -> p.Range) + SynArgPats.Pats $1, m } atomicPatterns: | atomicPattern atomicPatterns %prec pat_args @@ -3993,7 +4000,7 @@ patternClauses: { let pat, guard, patm = $1 let clauses, mLast = $4 let m = guard |> Option.map (fun e -> unionRanges patm e.Range) |> Option.defaultValue patm - (SynMatchClause(pat, guard, None, unitExprFromParseError m.EndRange, m, DebugPointAtTarget.Yes) :: clauses), mLast } + (SynMatchClause(pat, guard, None, arbExpr ("patternClauses1", m.EndRange), m, DebugPointAtTarget.Yes) :: clauses), mLast } | patternAndGuard patternResult BAR error { let pat, guard, patm = $1 @@ -4016,7 +4023,7 @@ patternClauses: let mLast = rhs parseState 2 let m = guard |> Option.map (fun e -> unionRanges patm e.Range) |> Option.defaultValue patm // silent recovery - [SynMatchClause(pat, guard, None, unitExprFromParseError m.EndRange, m, DebugPointAtTarget.Yes)], mLast } + [SynMatchClause(pat, guard, None, arbExpr ("patternClauses2", m.EndRange), m, DebugPointAtTarget.Yes)], mLast } patternGuard: | WHEN declExpr diff --git a/tests/service/ParserTests.fs b/tests/service/ParserTests.fs index 5cea5f275ee..75aa00103f0 100644 --- a/tests/service/ParserTests.fs +++ b/tests/service/ParserTests.fs @@ -51,7 +51,7 @@ match () with | x """ match getSingleExprInModule parseResults with - | SynExpr.Match (_, _, [ SynMatchClause (_, _, _, SynExpr.FromParseError _, _, _) ], _) -> () + | SynExpr.Match (_, _, [ SynMatchClause (_, _, _, SynExpr.ArbitraryAfterError _, _, _) ], _) -> () | _ -> failwith "Unexpected tree" @@ -63,7 +63,7 @@ match () with """ match getSingleExprInModule parseResults with - | SynExpr.Match (_, _, [ SynMatchClause (_, _, _, SynExpr.FromParseError _, _, _) ], _) -> () + | SynExpr.Match (_, _, [ SynMatchClause (_, _, _, SynExpr.ArbitraryAfterError _, _, _) ], _) -> () | _ -> failwith "Unexpected tree" [] @@ -75,5 +75,5 @@ match () with """ match getSingleExprInModule parseResults with - | SynExpr.Match (_, _, [ SynMatchClause (_, _, _, SynExpr.FromParseError _, _, _); _ ], _) -> () + | SynExpr.Match (_, _, [ SynMatchClause (_, _, _, SynExpr.ArbitraryAfterError _, _, _); _ ], _) -> () | _ -> failwith "Unexpected tree" From bfdde71c5e88df65a6cc962850dec3c5210f77a0 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Fri, 27 Aug 2021 17:52:12 +0300 Subject: [PATCH 12/16] Try to fix Desktop test suite --- src/fsharp/pars.fsy | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/fsharp/pars.fsy b/src/fsharp/pars.fsy index d7388a9969c..768428b0c33 100644 --- a/src/fsharp/pars.fsy +++ b/src/fsharp/pars.fsy @@ -3146,8 +3146,7 @@ constrPattern: atomicPatsOrNamePatPairs: | LPAREN namePatPairs rparen - { let m = rhs2 parseState 1 3 - SynArgPats.NamePatPairs $2, m } + { SynArgPats.NamePatPairs $2, snd $2 } | atomicPatterns { let mWhole = rhs parseState 1 From 434af8967d2993b4efb4171cc22b627730ac946e Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Mon, 30 Aug 2021 18:32:52 +0300 Subject: [PATCH 13/16] Fix tests --- src/fsharp/service/ServiceParsedInputOps.fs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/fsharp/service/ServiceParsedInputOps.fs b/src/fsharp/service/ServiceParsedInputOps.fs index 9df1f3c394d..23462238334 100644 --- a/src/fsharp/service/ServiceParsedInputOps.fs +++ b/src/fsharp/service/ServiceParsedInputOps.fs @@ -908,6 +908,11 @@ module ParsedInput = if isOnTheRightOfComma elements commas e then Some args else None | _ -> None + let (|SkipFromParseErrorPat|) pat = + match pat with + | SynPat.FromParseError(pat, _) -> pat + | _ -> pat + let walker = { new SyntaxVisitorBase<_>() with @@ -980,7 +985,8 @@ module ParsedInput = member _.VisitBinding(_path, defaultTraverse, (SynBinding(headPat = headPat) as synBinding)) = - let visitParam = function + let visitParam (SkipFromParseErrorPat pat) = + match pat with | SynPat.Named (range = range) | SynPat.As (_, SynPat.Named (range = range), _) when rangeContainsPos range pos -> // parameter without type hint, no completion @@ -999,12 +1005,13 @@ module ParsedInput = | SynArgPats.Pats pats -> pats |> List.tryPick (fun pat -> match pat with + | SynPat.FromParseError(pat, _) | SynPat.Paren(pat, _) -> match pat with | SynPat.Tuple(_, pats, _) -> pats |> List.tryPick visitParam | _ -> visitParam pat - | SynPat.Wild range | SynPat.FromParseError (_, range) when rangeContainsPos range pos -> + | SynPat.Wild range | SynPat.FromParseError (SynPat.Named _, range) when rangeContainsPos range pos -> // let foo (x| Some CompletionContext.Invalid | _ -> visitParam pat From 2fbdbbe3a542243b136cb74f21c50ed68467e7f6 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Mon, 30 Aug 2021 21:17:20 +0300 Subject: [PATCH 14/16] Simplify test --- tests/service/Common.fs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/tests/service/Common.fs b/tests/service/Common.fs index e36c5449c1d..27031dbcd16 100644 --- a/tests/service/Common.fs +++ b/tests/service/Common.fs @@ -254,14 +254,11 @@ let getSingleModuleLikeDecl (input: ParsedInput) = | _ -> failwith "Could not get module decls" let getSingleModuleMemberDecls (input: ParsedInput) = - match getSingleModuleLikeDecl input with - | SynModuleOrNamespace (decls = decls) -> decls + let (SynModuleOrNamespace (decls = decls)) = getSingleModuleLikeDecl input + decls let getSingleExprInModule (input: ParsedInput) = - match getSingleModuleLikeDecl input with - | SynModuleOrNamespace (decls = decls) -> - - match decls with + match getSingleModuleMemberDecls input with | [ SynModuleDecl.DoExpr (_, expr, _) ] -> expr | _ -> failwith "Can't get single expression" From 8d607c40b8e94c2c4427b45962cbfae2349efef0 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Mon, 30 Aug 2021 21:17:26 +0300 Subject: [PATCH 15/16] Add more tests --- tests/service/ParserTests.fs | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/service/ParserTests.fs b/tests/service/ParserTests.fs index 75aa00103f0..8e35c0fc4ca 100644 --- a/tests/service/ParserTests.fs +++ b/tests/service/ParserTests.fs @@ -77,3 +77,28 @@ match () with match getSingleExprInModule parseResults with | SynExpr.Match (_, _, [ SynMatchClause (_, _, _, SynExpr.ArbitraryAfterError _, _, _); _ ], _) -> () | _ -> failwith "Unexpected tree" + +[] +let ``Match clause 04 - Or pat`` () = + let parseResults = getParseResults """ +match () with +| x +| _ -> () +""" + + match getSingleExprInModule parseResults with + | SynExpr.Match (_, _, [ SynMatchClause (SynPat.Or _, _, _, SynExpr.Const _, _, _) ], _) -> () + | _ -> failwith "Unexpected tree" + +[] +let ``Match clause 05 - Missing body`` () = + let parseResults = getParseResults """ +match () with +| x -> +| _ -> () +""" + + match getSingleExprInModule parseResults with + | SynExpr.Match (_, _, [ SynMatchClause (_, _, _, SynExpr.ArbitraryAfterError _, _, _) + SynMatchClause (_, _, _, SynExpr.Const _, _, _) ], _) -> () + | _ -> failwith "Unexpected tree" \ No newline at end of file From 97dceffdf8b52ae1aef2d5405a276c8d6dac4b3b Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Mon, 30 Aug 2021 21:18:52 +0300 Subject: [PATCH 16/16] Disable failing test --- .../LegacyLanguageService/Tests.LanguageService.Completion.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.Completion.fs b/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.Completion.fs index 82bdd085587..675ee60617c 100644 --- a/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.Completion.fs +++ b/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.Completion.fs @@ -6239,7 +6239,7 @@ let rec f l = marker = "(*MarkerMethodInType*)", list = ["PrivateMethod"]) - [] +// [] member this.``VariableIdentifier.AsParameter``() = this.VerifyDotCompListContainAllAtStartOfMarker( fileContents = """