diff --git a/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md b/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md index b49aa2d0835..6bfd568cf9a 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md +++ b/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md @@ -125,6 +125,7 @@ * Fix FSI pretty printing to distinguish anonymous records (`{| ... |}`) from nominal records (`{ ... }`). ([Issue #6116](https://github.com/dotnet/fsharp/issues/6116), [PR #19919](https://github.com/dotnet/fsharp/pull/19919)) * Fix dot-completion after indexed expressions (`a.[0].Data.`, `a[0].Data.`, `[1;2].Length.`) returning unrelated global completions instead of expression-typings members. ([Issue #4966](https://github.com/dotnet/fsharp/issues/4966), [PR #19934](https://github.com/dotnet/fsharp/pull/19934)) * Quotations of `match s with "" -> _` no longer leak the `s <> null && s.Length = 0` lowering; the empty-string optimization moved from pattern-match compilation to the optimizer so quoted expressions keep `op_Equality(s, "")`. ([Issue #19873](https://github.com/dotnet/fsharp/issues/19873)) +* Parser: recover on unfinished abstract members ([PR #20070](https://github.com/dotnet/fsharp/pull/20070)) ### Added diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index b5055ce2dd9..7b81000a792 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -3723,17 +3723,16 @@ module EstablishTypeDefinitionCores = let abstractSlots = [ for synValSig, memberFlags in slotsigs do - - let (SynValSig(range=m)) = synValSig - - CheckMemberFlags None NewSlotsOK OverridesOK memberFlags m - - let slots = fst (TcAndPublishValSpec (cenv, envinner, containerInfo, ModuleOrMemberBinding, Some memberFlags, tpenv, synValSig)) - // Multiple slots may be returned, e.g. for - // abstract P: int with get, set - - for slot in slots do - yield mkLocalValRef slot ] + let (SynValSig(ident = (SynIdent(id, _)); range = m)) = synValSig + if id.idText <> "" then + CheckMemberFlags None NewSlotsOK OverridesOK memberFlags m + + let slots = fst (TcAndPublishValSpec (cenv, envinner, containerInfo, ModuleOrMemberBinding, Some memberFlags, tpenv, synValSig)) + // Multiple slots may be returned, e.g. for + // abstract P: int with get, set + + for slot in slots do + yield mkLocalValRef slot ] let kind = match kind with diff --git a/src/Compiler/SyntaxTree/ParseHelpers.fs b/src/Compiler/SyntaxTree/ParseHelpers.fs index b329d48ee34..62893e04c52 100644 --- a/src/Compiler/SyntaxTree/ParseHelpers.fs +++ b/src/Compiler/SyntaxTree/ParseHelpers.fs @@ -1136,3 +1136,95 @@ let mkLetBangExpression Trivia = { InKeyword = mIn } IsFromSource = true // User-written let!/use! bindings } + +let mkAbstractMember + parseState + attrs + (accessBeforeKeyword: SynAccess option) + memberFlags + (accessBeforeId: SynAccess option) + mInline + id + typeParams + typeWithConstraints + accessors + = + if Option.isSome accessBeforeKeyword then + errorR (Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier (), rhs parseState 2)) + + let (ty: SynType), arity = typeWithConstraints + + let isInline, doc, explicitValTyparDecls = + Option.isSome mInline, grabXmlDoc (parseState, attrs, 1), typeParams + + let mWith, (getSet, getSetRangeOpt: GetSetKeywords option, getterAccess, setterAccess) = + accessors + + let getSetAdjuster arity = + match arity, getSet with + | SynValInfo([], _), SynMemberKind.Member -> SynMemberKind.PropertyGet + | _ -> getSet + + let mWhole = + let m = rhs parseState 1 + + match getSetRangeOpt with + | None -> unionRanges m ty.Range + | Some gs -> unionRanges m gs.Range + |> unionRangeWithXmlDoc doc + + [ accessBeforeKeyword; accessBeforeId; getterAccess; setterAccess ] + |> List.iter (function + | None -> () + | Some access -> errorR (Error(FSComp.SR.parsAccessibilityModsIllegalForAbstract (), access.Range))) + + let mkFlags, leadingKeyword = memberFlags + + let trivia = + { + LeadingKeyword = leadingKeyword + InlineKeyword = mInline + WithKeyword = mWith + EqualsRange = None + } + + let vis2 = SynValSigAccess.Single None + + let valSpfn = + SynValSig(attrs, id, explicitValTyparDecls, ty, arity, isInline, false, doc, vis2, None, mWhole, trivia) + + let trivia: SynMemberDefnAbstractSlotTrivia = { GetSetKeywords = getSetRangeOpt } + + [ + SynMemberDefn.AbstractSlot(valSpfn, mkFlags (getSetAdjuster arity), mWhole, trivia) + ] + +let mkMatchClauses patternAndGuard patternResult (mNextBar: range option) nextClauses mLastOuter = + let (pat: SynPat), guard = patternAndGuard + let (mArrow: range option), (resultExpr: SynExpr) = patternResult + fun mBar -> + let m = unionRanges resultExpr.Range pat.Range + let clause = SynMatchClause(pat, guard, resultExpr, m, DebugPointAtTarget.Yes, { ArrowRange = mArrow; BarRange = mBar }) + + let clauses, mLast = + match nextClauses with + | Some patternClauses -> + let clauses, mLast = patternClauses mNextBar + clause :: clauses, mLast + + | _ -> [clause], resultExpr.Range + + clauses, mLastOuter |> Option.defaultValue mLast + +let mkMatchClausesRecoverMissingResult (patternAndGuard: SynPat * SynExpr option) exprDebugString (mExpr: range option) (mNextBar: range option) nextClauses mLastOuter = + let pat, guard = patternAndGuard + let mBeforeResult = + match mExpr with + | Some m -> m + | _ -> + + match guard with + | Some expr -> expr.Range + | _ -> pat.Range + let patternResult = None, arbExpr (exprDebugString, mBeforeResult.EndRange) + mkMatchClauses patternAndGuard patternResult (mNextBar: range option) nextClauses mLastOuter diff --git a/src/Compiler/SyntaxTree/ParseHelpers.fsi b/src/Compiler/SyntaxTree/ParseHelpers.fsi index aae952d210c..e1091f90028 100644 --- a/src/Compiler/SyntaxTree/ParseHelpers.fsi +++ b/src/Compiler/SyntaxTree/ParseHelpers.fsi @@ -285,3 +285,33 @@ val mkSynField: SynField val leadingKeywordIsAbstract: SynLeadingKeyword -> bool + +val mkAbstractMember: + parseState: IParseState -> + attrs: SynAttributeList list -> + accessBeforeKeyword: SynAccess option -> + abstractMemberFlags: (SynMemberKind -> SynMemberFlags) * SynLeadingKeyword -> + accessBeforeId: SynAccess option -> + mInline: range option -> + id: SynIdent -> + typeParams: SynValTyparDecls -> + typeWithConstraints: SynType * SynValInfo -> + accessors: range option * (SynMemberKind * GetSetKeywords option * SynAccess option * SynAccess option) -> + SynMemberDefn list + +val mkMatchClauses: + patternAndGuard: SynPat * SynExpr option -> + patternResult: range option * SynExpr -> + mNextBar: range option -> + nextClauses: (range option -> SynMatchClause list * range) option -> + mLastOuter: range option -> + (range option -> SynMatchClause list * range) + +val mkMatchClausesRecoverMissingResult: + patternAndGuard: SynPat * SynExpr option -> + exprDebugString: string -> + mExpr: range option -> + mNextBar: range option -> + nextClauses: (range option -> SynMatchClause list * range) option -> + mLastOuter: range option -> + (range option -> SynMatchClause list * range) diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index 01120123a36..31d6b0f8615 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -164,7 +164,7 @@ let parse_error_rich = Some(fun (ctxt: ParseErrorContext<_>) -> %type tyconSpfnList %type atomicPatsOrNamePatPairs %type atomicPatterns -%type patternResult +%type patternResult %type declExpr %type minusExpr %type appExpr @@ -2058,27 +2058,33 @@ classDefnMember: [ SynMemberDefn.Interface(ty, None, None, rhs2 parseState 1 3) ] } | opt_attributes opt_access abstractMemberFlags opt_access opt_inline nameop opt_explicitValTyparDecls COLON topTypeWithTypeConstraints classMemberSpfnGetSet opt_ODECLEND - { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) - let ty, arity = $9 - let isInline, doc, id, explicitValTyparDecls = (Option.isSome $5), grabXmlDoc(parseState, $1, 1), $6, $7 - let mWith, (getSet, getSetRangeOpt, getterAccess, setterAccess) = $10 - let getSetAdjuster arity = match arity, getSet with SynValInfo([], _), SynMemberKind.Member -> SynMemberKind.PropertyGet | _ -> getSet - let mWhole = - let m = rhs parseState 1 - match getSetRangeOpt with - | None -> unionRanges m ty.Range - | Some gs -> unionRanges m gs.Range - |> unionRangeWithXmlDoc doc - - [ $2; $4; getterAccess; setterAccess ] - |> List.iter (function None -> () | Some access -> errorR(Error(FSComp.SR.parsAccessibilityModsIllegalForAbstract(), access.Range))) + { mkAbstractMember parseState $1 $2 $3 $4 $5 $6 $7 $9 $10 } + + | opt_attributes opt_access abstractMemberFlags opt_access opt_inline nameop opt_explicitValTyparDecls COLON recover opt_ODECLEND + { let id = $6 + let typeWithConstraints = SynType.FromParseError(id.Range.EndRange), SynValInfo([], SynInfo.unnamedRetVal) + let accessors = None, (SynMemberKind.Member, None, None, None) + mkAbstractMember parseState $1 $2 $3 $4 $5 id $7 typeWithConstraints accessors } + + | opt_attributes opt_access abstractMemberFlags opt_access opt_inline nameop opt_explicitValTyparDecls recover opt_ODECLEND + { let id = $6 + let typeWithConstraints = SynType.FromParseError(id.Range.EndRange), SynValInfo([], SynInfo.unnamedRetVal) + let accessors = None, (SynMemberKind.Member, None, None, None) + mkAbstractMember parseState $1 $2 $3 $4 $5 id $7 typeWithConstraints accessors } + + | opt_attributes opt_access abstractMemberFlags opt_access opt_inline recover opt_ODECLEND + { let mBeforeId = + match $2 with + | Some access -> access.Range + | _ -> + let _, leadingKeyword = $3 + leadingKeyword.Range - let mkFlags, leadingKeyword = $3 - let trivia = { LeadingKeyword = leadingKeyword; InlineKeyword = $5; WithKeyword = mWith; EqualsRange = None } - let vis2 = SynValSigAccess.Single(None) - let valSpfn = SynValSig($1, id, explicitValTyparDecls, ty, arity, isInline, false, doc, vis2, None, mWhole, trivia) - let trivia: SynMemberDefnAbstractSlotTrivia = { GetSetKeywords = getSetRangeOpt } - [ SynMemberDefn.AbstractSlot(valSpfn, mkFlags (getSetAdjuster arity), mWhole, trivia) ] } + let id = SynIdent(mkSynId mBeforeId.EndRange "", None) + let typeParams = SynValTyparDecls(None, true) + let typeWithConstraints = SynType.FromParseError(id.Range.EndRange), SynValInfo([], SynInfo.unnamedRetVal) + let accessors = None, (SynMemberKind.Member, None, None, None) + mkAbstractMember parseState $1 $2 $3 $4 $5 id typeParams typeWithConstraints accessors } | opt_attributes opt_access inheritsDefn { if not (isNil $1) then errorR(Error(FSComp.SR.parsAttributesIllegalOnInherit(), rhs parseState 1)) @@ -5055,66 +5061,64 @@ patternAndGuard: patternClauses: | patternAndGuard patternResult %prec prec_pat_pat_action - { let pat, guard = $1 - let mArrow, resultExpr = $2 - let mLast = resultExpr.Range - let m = unionRanges resultExpr.Range pat.Range - fun mBar -> - [SynMatchClause(pat, guard, resultExpr, m, DebugPointAtTarget.Yes, { ArrowRange = Some mArrow; BarRange = mBar })], mLast } + { mkMatchClauses $1 $2 None None None } | patternAndGuard patternResult barCanBeRightBeforeNull patternClauses - { let pat, guard = $1 - let mArrow, resultExpr = $2 - let mNextBar = rhs parseState 3 |> Some - let clauses, mLast = $4 mNextBar - let m = unionRanges resultExpr.Range pat.Range - fun mBar -> - (SynMatchClause(pat, guard, resultExpr, m, DebugPointAtTarget.Yes, { ArrowRange = Some mArrow; BarRange = mBar }) :: clauses), mLast } + { let mNextBar = rhs parseState 3 |> Some + mkMatchClauses $1 $2 mNextBar (Some $4) None } | patternAndGuard patternResult BAR barCanBeRightBeforeNull patternClauses - { let pat, guard = $1 - let mArrow, resultExpr = $2 + { let mNextBar = rhs parseState 3 |> Some let mBar1 = rhs parseState 3 let mBar2 = rhs parseState 4 reportParseErrorAt mBar2 (FSComp.SR.parsExpectingPattern ()) - let clauses, mLast = Some mBar1 |> $5 - let clauses = addEmptyMatchClause mBar1 mBar2 clauses + let patternClauses = + fun mNextBar -> + let clauses, mLast = Some mBar1 |> $5 + let clauses = addEmptyMatchClause mBar1 mBar2 clauses + clauses, mLast - fun mBar -> - let m = unionRanges resultExpr.Range pat.Range - let trivia = { ArrowRange = Some mArrow; BarRange = mBar } - SynMatchClause(pat, guard, resultExpr, m, DebugPointAtTarget.Yes, trivia) :: clauses, mLast } + mkMatchClauses $1 $2 mNextBar (Some patternClauses) None } | patternAndGuard error barCanBeRightBeforeNull patternClauses - { let pat, guard = $1 - let mNextBar = rhs parseState 3 |> Some - let clauses, mLast = $4 mNextBar - let patm = pat.Range - let m = guard |> Option.map (fun e -> unionRanges patm e.Range) |> Option.defaultValue patm - fun _mBar -> - (SynMatchClause(pat, guard, arbExpr ("patternClauses1", m.EndRange), m, DebugPointAtTarget.Yes, SynMatchClauseTrivia.Zero) :: clauses), mLast } + { let mNextBar = rhs parseState 3 |> Some + mkMatchClausesRecoverMissingResult $1 "patternClauses1" None mNextBar (Some $4) None } | patternAndGuard patternResult barCanBeRightBeforeNull recover - { let pat, guard = $1 - let mArrow, resultExpr = $2 - let mLast = rhs parseState 3 - let m = unionRanges resultExpr.Range pat.Range - fun mBar -> - [SynMatchClause(pat, guard, resultExpr, m, DebugPointAtTarget.Yes, { ArrowRange = Some mArrow; BarRange = mBar })], mLast } + { let mLast = rhs parseState 3 |> Some + mkMatchClauses $1 $2 None None mLast } | patternAndGuard patternResult recover - { let pat, guard = $1 - let mArrow, resultExpr = $2 - let m = unionRanges resultExpr.Range pat.Range - fun mBar -> - [SynMatchClause(pat, guard, resultExpr, m, DebugPointAtTarget.Yes, { ArrowRange = Some mArrow; BarRange = mBar })], m } + { mkMatchClauses $1 $2 None None None } | patternAndGuard recover - { let pat, guard = $1 - let patm = pat.Range - let m = guard |> Option.map (fun e -> unionRanges patm e.Range) |> Option.defaultValue patm - fun mBar -> - [SynMatchClause(pat, guard, arbExpr ("patternClauses2", m.EndRange), m, DebugPointAtTarget.Yes, { ArrowRange = None; BarRange = mBar })], m } + { mkMatchClausesRecoverMissingResult $1 "patternClauses2" None None None None } + + | parenPattern WHEN patternResult %prec prec_recover + { let patternAndGuard = $1, None + let mWhen = rhs parseState 2 + reportParseErrorAt mWhen (FSComp.SR.parsExpectingExpression ()) + mkMatchClauses patternAndGuard $3 None None None } + + | parenPattern WHEN %prec prec_recover + { let patternAndGuard = $1, None + let mWhen = rhs parseState 2 + reportParseErrorAt mWhen (FSComp.SR.parsExpectingExpression ()) + mkMatchClausesRecoverMissingResult patternAndGuard "patternClauses3" (Some mWhen) None None None } + + | parenPattern WHEN barCanBeRightBeforeNull patternClauses %prec prec_recover + { let patternAndGuard = $1, None + let mWhen = rhs parseState 2 + reportParseErrorAt mWhen (FSComp.SR.parsExpectingExpression ()) + let mNextBar = rhs parseState 3 |> Some + mkMatchClausesRecoverMissingResult patternAndGuard "patternClauses4" (Some mWhen) mNextBar (Some $4) None } + + | parenPattern WHEN barCanBeRightBeforeNull %prec prec_recover + { let patternAndGuard = $1, None + let mWhen = rhs parseState 2 + reportParseErrorAt mWhen (FSComp.SR.parsExpectingExpression ()) + let mLast = rhs parseState 3 |> Some + mkMatchClausesRecoverMissingResult patternAndGuard "patternClauses5" (Some mWhen) None None mLast } patternGuard: | WHEN declExpr @@ -5127,7 +5131,7 @@ patternResult: | RARROW typedSequentialExprBlockR { let mArrow = rhs parseState 1 let expr = $2 mArrow - mArrow, expr } + Some mArrow, expr } ifExprCases: | ifExprThen ifExprElifs diff --git a/tests/service/data/SyntaxTree/Expression/Match - When 01.fs b/tests/service/data/SyntaxTree/Expression/Match - When 01.fs new file mode 100644 index 00000000000..8975d41270d --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/Match - When 01.fs @@ -0,0 +1,4 @@ +module Module + +match () with +| _ when true -> () diff --git a/tests/service/data/SyntaxTree/Expression/Match - When 01.fs.bsl b/tests/service/data/SyntaxTree/Expression/Match - When 01.fs.bsl new file mode 100644 index 00000000000..1a863c9a413 --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/Match - When 01.fs.bsl @@ -0,0 +1,21 @@ +ImplFile + (ParsedImplFileInput + ("/root/Expression/Match - When 01.fs", false, QualifiedNameOfFile Module, + [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (Match + (Yes (3,0--3,13), Const (Unit, (3,6--3,8)), + [SynMatchClause + (Wild (4,2--4,3), Some (Const (Bool true, (4,9--4,13))), + Const (Unit, (4,17--4,19)), (4,2--4,19), Yes, + { ArrowRange = Some (4,14--4,16) + BarRange = Some (4,0--4,1) })], (3,0--4,19), + { MatchKeyword = (3,0--3,5) + WithKeyword = (3,9--3,13) }), (3,0--4,19))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--4,19), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Expression/Match - When 02.fs b/tests/service/data/SyntaxTree/Expression/Match - When 02.fs new file mode 100644 index 00000000000..a9e4204bac3 --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/Match - When 02.fs @@ -0,0 +1,4 @@ +module Module + +match () with +| _ when -> () diff --git a/tests/service/data/SyntaxTree/Expression/Match - When 02.fs.bsl b/tests/service/data/SyntaxTree/Expression/Match - When 02.fs.bsl new file mode 100644 index 00000000000..b9101cf081c --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/Match - When 02.fs.bsl @@ -0,0 +1,22 @@ +ImplFile + (ParsedImplFileInput + ("/root/Expression/Match - When 02.fs", false, QualifiedNameOfFile Module, + [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (Match + (Yes (3,0--3,13), Const (Unit, (3,6--3,8)), + [SynMatchClause + (Wild (4,2--4,3), None, Const (Unit, (4,12--4,14)), + (4,2--4,14), Yes, { ArrowRange = Some (4,9--4,11) + BarRange = Some (4,0--4,1) })], + (3,0--4,14), { MatchKeyword = (3,0--3,5) + WithKeyword = (3,9--3,13) }), (3,0--4,14))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--4,14), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) + +(4,4)-(4,8) parse error Expecting expression diff --git a/tests/service/data/SyntaxTree/Expression/Match - When 03.fs b/tests/service/data/SyntaxTree/Expression/Match - When 03.fs new file mode 100644 index 00000000000..71813e0919f --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/Match - When 03.fs @@ -0,0 +1,5 @@ +module Module + +match () with +| a when +| b -> () diff --git a/tests/service/data/SyntaxTree/Expression/Match - When 03.fs.bsl b/tests/service/data/SyntaxTree/Expression/Match - When 03.fs.bsl new file mode 100644 index 00000000000..89142485a76 --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/Match - When 03.fs.bsl @@ -0,0 +1,28 @@ +ImplFile + (ParsedImplFileInput + ("/root/Expression/Match - When 03.fs", false, QualifiedNameOfFile Module, + [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (Match + (Yes (3,0--3,13), Const (Unit, (3,6--3,8)), + [SynMatchClause + (Named (SynIdent (a, None), false, None, (4,2--4,3)), None, + ArbitraryAfterError ("patternClauses4", (4,8--4,8)), + (4,2--4,8), Yes, { ArrowRange = None + BarRange = Some (4,0--4,1) }); + SynMatchClause + (Named (SynIdent (b, None), false, None, (5,2--5,3)), None, + Const (Unit, (5,7--5,9)), (5,2--5,9), Yes, + { ArrowRange = Some (5,4--5,6) + BarRange = Some (5,0--5,1) })], (3,0--5,9), + { MatchKeyword = (3,0--3,5) + WithKeyword = (3,9--3,13) }), (3,0--5,9))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--5,9), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) + +(4,4)-(4,8) parse error Expecting expression diff --git a/tests/service/data/SyntaxTree/Expression/Match - When 04.fs b/tests/service/data/SyntaxTree/Expression/Match - When 04.fs new file mode 100644 index 00000000000..4f5848f5851 --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/Match - When 04.fs @@ -0,0 +1,7 @@ +module Module + +match () with +| a when +| + +() \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/Expression/Match - When 04.fs.bsl b/tests/service/data/SyntaxTree/Expression/Match - When 04.fs.bsl new file mode 100644 index 00000000000..7dfb6e7f1ec --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/Match - When 04.fs.bsl @@ -0,0 +1,24 @@ +ImplFile + (ParsedImplFileInput + ("/root/Expression/Match - When 04.fs", false, QualifiedNameOfFile Module, + [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (Match + (Yes (3,0--3,13), Const (Unit, (3,6--3,8)), + [SynMatchClause + (Named (SynIdent (a, None), false, None, (4,2--4,3)), None, + ArbitraryAfterError ("patternClauses5", (4,8--4,8)), + (4,2--4,8), Yes, { ArrowRange = None + BarRange = Some (4,0--4,1) })], + (3,0--5,1), { MatchKeyword = (3,0--3,5) + WithKeyword = (3,9--3,13) }), (3,0--5,1)); + Expr (Const (Unit, (7,0--7,2)), (7,0--7,2))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--7,2), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) + +(4,4)-(4,8) parse error Expecting expression diff --git a/tests/service/data/SyntaxTree/Expression/Try - With 09.fs.bsl b/tests/service/data/SyntaxTree/Expression/Try - With 09.fs.bsl index 03940fb6220..f26155af677 100644 --- a/tests/service/data/SyntaxTree/Expression/Try - With 09.fs.bsl +++ b/tests/service/data/SyntaxTree/Expression/Try - With 09.fs.bsl @@ -12,15 +12,21 @@ ImplFile (None, SynValInfo ([], SynArgInfo ([], false, None)), None), Wild (3,4--3,5), None, TryWith - (Const (Int32 1, (4,8--4,9)), [], (4,4--5,8), Yes (4,4--4,7), - Yes (5,4--5,8), { TryKeyword = (4,4--4,7) - TryToWithRange = (4,4--5,8) - WithKeyword = (5,4--5,8) - WithToEndRange = (5,4--5,8) }), - (3,4--3,5), NoneAtLet, { LeadingKeyword = Let (3,0--3,3) - InlineKeyword = None - EqualsRange = Some (3,6--3,7) })], - (3,0--5,8), { InKeyword = None }); + (Const (Int32 1, (4,8--4,9)), + [SynMatchClause + (Wild (5,9--5,10), None, + ArbitraryAfterError ("patternClauses3", (5,15--5,15)), + (5,9--5,15), Yes, { ArrowRange = None + BarRange = None })], (4,4--5,15), + Yes (4,4--4,7), Yes (5,4--5,8), + { TryKeyword = (4,4--4,7) + TryToWithRange = (4,4--5,8) + WithKeyword = (5,4--5,8) + WithToEndRange = (5,4--5,15) }), (3,4--3,5), NoneAtLet, + { LeadingKeyword = Let (3,0--3,3) + InlineKeyword = None + EqualsRange = Some (3,6--3,7) })], (3,0--5,15), + { InKeyword = None }); Expr (Const (Int32 3, (7,0--7,1)), (7,0--7,1))], PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, (1,0--7,1), { LeadingKeyword = Module (1,0--1,6) })], (true, true), @@ -28,4 +34,4 @@ ImplFile WarnDirectives = [] CodeComments = [] }, set [])) -(7,0)-(7,1) parse error Incomplete structured construct at or before this point in expression +(5,11)-(5,15) parse error Expecting expression diff --git a/tests/service/data/SyntaxTree/Member/Abstract - Method 01.fs b/tests/service/data/SyntaxTree/Member/Abstract - Method 01.fs new file mode 100644 index 00000000000..0b53d40f7c5 --- /dev/null +++ b/tests/service/data/SyntaxTree/Member/Abstract - Method 01.fs @@ -0,0 +1,6 @@ +module Module + +type T = + abstract M: unit -> unit + +() diff --git a/tests/service/data/SyntaxTree/Member/Abstract - Method 01.fs.bsl b/tests/service/data/SyntaxTree/Member/Abstract - Method 01.fs.bsl new file mode 100644 index 00000000000..657523d0bf6 --- /dev/null +++ b/tests/service/data/SyntaxTree/Member/Abstract - Method 01.fs.bsl @@ -0,0 +1,47 @@ +ImplFile + (ParsedImplFileInput + ("/root/Member/Abstract - Method 01.fs", false, QualifiedNameOfFile Module, + [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], None, [], [T], + PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector), + false, None, (3,5--3,6)), + ObjectModel + (Unspecified, + [AbstractSlot + (SynValSig + ([], SynIdent (M, None), + SynValTyparDecls (None, true), + Fun + (LongIdent (SynLongIdent ([unit], [], [None])), + LongIdent (SynLongIdent ([unit], [], [None])), + (4,16--4,28), { ArrowRange = (4,21--4,23) }), + SynValInfo + ([[SynArgInfo ([], false, None)]], + SynArgInfo ([], false, None)), false, false, + PreXmlDoc ((4,4), FSharp.Compiler.Xml.XmlDocCollector), + Single None, None, (4,4--4,28), + { LeadingKeyword = Abstract (4,4--4,12) + InlineKeyword = None + WithKeyword = None + EqualsRange = None }), + { IsInstance = true + IsDispatchSlot = true + IsOverrideOrExplicitImpl = false + IsFinal = false + GetterOrSetterIsCompilerGenerated = false + MemberKind = Member }, (4,4--4,28), + { GetSetKeywords = None })], (4,4--4,28)), [], None, + (3,5--4,28), { LeadingKeyword = Type (3,0--3,4) + EqualsRange = Some (3,7--3,8) + WithKeyword = None })], (3,0--4,28)); + Expr (Const (Unit, (6,0--6,2)), (6,0--6,2))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--6,2), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Member/Abstract - Method 02.fs b/tests/service/data/SyntaxTree/Member/Abstract - Method 02.fs new file mode 100644 index 00000000000..c1ed8cc87e2 --- /dev/null +++ b/tests/service/data/SyntaxTree/Member/Abstract - Method 02.fs @@ -0,0 +1,6 @@ +module Module + +type T = + abstract M: unit -> + +() diff --git a/tests/service/data/SyntaxTree/Member/Abstract - Method 02.fs.bsl b/tests/service/data/SyntaxTree/Member/Abstract - Method 02.fs.bsl new file mode 100644 index 00000000000..19dd586af47 --- /dev/null +++ b/tests/service/data/SyntaxTree/Member/Abstract - Method 02.fs.bsl @@ -0,0 +1,49 @@ +ImplFile + (ParsedImplFileInput + ("/root/Member/Abstract - Method 02.fs", false, QualifiedNameOfFile Module, + [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], None, [], [T], + PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector), + false, None, (3,5--3,6)), + ObjectModel + (Unspecified, + [AbstractSlot + (SynValSig + ([], SynIdent (M, None), + SynValTyparDecls (None, true), + Fun + (LongIdent (SynLongIdent ([unit], [], [None])), + FromParseError (4,23--4,23), (4,16--6,1), + { ArrowRange = (4,21--4,23) }), + SynValInfo + ([[SynArgInfo ([], false, None)]], + SynArgInfo ([], false, None)), false, false, + PreXmlDoc ((4,4), FSharp.Compiler.Xml.XmlDocCollector), + Single None, None, (4,4--6,1), + { LeadingKeyword = Abstract (4,4--4,12) + InlineKeyword = None + WithKeyword = None + EqualsRange = None }), + { IsInstance = true + IsDispatchSlot = true + IsOverrideOrExplicitImpl = false + IsFinal = false + GetterOrSetterIsCompilerGenerated = false + MemberKind = Member }, (4,4--6,1), + { GetSetKeywords = None })], (4,4--6,1)), [], None, + (3,5--6,1), { LeadingKeyword = Type (3,0--3,4) + EqualsRange = Some (3,7--3,8) + WithKeyword = None })], (3,0--6,1)); + Expr (Const (Unit, (6,0--6,2)), (6,0--6,2))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--6,2), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) + +(6,0)-(6,1) parse error Incomplete structured construct at or before this point in member definition diff --git a/tests/service/data/SyntaxTree/Member/Abstract - Property 06.fs b/tests/service/data/SyntaxTree/Member/Abstract - Property 06.fs new file mode 100644 index 00000000000..205e747f228 --- /dev/null +++ b/tests/service/data/SyntaxTree/Member/Abstract - Property 06.fs @@ -0,0 +1,6 @@ +module Module + +type T = + abstract P: + +() diff --git a/tests/service/data/SyntaxTree/Member/Abstract - Property 06.fs.bsl b/tests/service/data/SyntaxTree/Member/Abstract - Property 06.fs.bsl new file mode 100644 index 00000000000..1f7e40460e0 --- /dev/null +++ b/tests/service/data/SyntaxTree/Member/Abstract - Property 06.fs.bsl @@ -0,0 +1,45 @@ +ImplFile + (ParsedImplFileInput + ("/root/Member/Abstract - Property 06.fs", false, + QualifiedNameOfFile Module, [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], None, [], [T], + PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector), + false, None, (3,5--3,6)), + ObjectModel + (Unspecified, + [AbstractSlot + (SynValSig + ([], SynIdent (P, None), + SynValTyparDecls (None, true), + FromParseError (4,14--4,14), + SynValInfo ([], SynArgInfo ([], false, None)), false, + false, + PreXmlDoc ((4,4), FSharp.Compiler.Xml.XmlDocCollector), + Single None, None, (4,4--4,14), + { LeadingKeyword = Abstract (4,4--4,12) + InlineKeyword = None + WithKeyword = None + EqualsRange = None }), + { IsInstance = true + IsDispatchSlot = true + IsOverrideOrExplicitImpl = false + IsFinal = false + GetterOrSetterIsCompilerGenerated = false + MemberKind = PropertyGet }, (4,4--4,14), + { GetSetKeywords = None })], (4,4--4,14)), [], None, + (3,5--4,14), { LeadingKeyword = Type (3,0--3,4) + EqualsRange = Some (3,7--3,8) + WithKeyword = None })], (3,0--4,14)); + Expr (Const (Unit, (6,0--6,2)), (6,0--6,2))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--6,2), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) + +(6,0)-(6,1) parse error Incomplete structured construct at or before this point in member definition diff --git a/tests/service/data/SyntaxTree/Member/Abstract - Property 07.fs b/tests/service/data/SyntaxTree/Member/Abstract - Property 07.fs new file mode 100644 index 00000000000..92411d7b86a --- /dev/null +++ b/tests/service/data/SyntaxTree/Member/Abstract - Property 07.fs @@ -0,0 +1,6 @@ +module Module + +type T = + abstract P + +() diff --git a/tests/service/data/SyntaxTree/Member/Abstract - Property 07.fs.bsl b/tests/service/data/SyntaxTree/Member/Abstract - Property 07.fs.bsl new file mode 100644 index 00000000000..cd6eb0ca2bf --- /dev/null +++ b/tests/service/data/SyntaxTree/Member/Abstract - Property 07.fs.bsl @@ -0,0 +1,45 @@ +ImplFile + (ParsedImplFileInput + ("/root/Member/Abstract - Property 07.fs", false, + QualifiedNameOfFile Module, [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], None, [], [T], + PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector), + false, None, (3,5--3,6)), + ObjectModel + (Unspecified, + [AbstractSlot + (SynValSig + ([], SynIdent (P, None), + SynValTyparDecls (None, true), + FromParseError (4,14--4,14), + SynValInfo ([], SynArgInfo ([], false, None)), false, + false, + PreXmlDoc ((4,4), FSharp.Compiler.Xml.XmlDocCollector), + Single None, None, (4,4--4,14), + { LeadingKeyword = Abstract (4,4--4,12) + InlineKeyword = None + WithKeyword = None + EqualsRange = None }), + { IsInstance = true + IsDispatchSlot = true + IsOverrideOrExplicitImpl = false + IsFinal = false + GetterOrSetterIsCompilerGenerated = false + MemberKind = PropertyGet }, (4,4--4,14), + { GetSetKeywords = None })], (4,4--4,14)), [], None, + (3,5--4,14), { LeadingKeyword = Type (3,0--3,4) + EqualsRange = Some (3,7--3,8) + WithKeyword = None })], (3,0--4,14)); + Expr (Const (Unit, (6,0--6,2)), (6,0--6,2))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--6,2), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) + +(6,0)-(6,1) parse error Incomplete structured construct at or before this point in member definition. Expected ':' or other token. diff --git a/tests/service/data/SyntaxTree/Member/Abstract - Property 08.fs b/tests/service/data/SyntaxTree/Member/Abstract - Property 08.fs new file mode 100644 index 00000000000..94854918086 --- /dev/null +++ b/tests/service/data/SyntaxTree/Member/Abstract - Property 08.fs @@ -0,0 +1,6 @@ +module Module + +type T = + abstract + +() diff --git a/tests/service/data/SyntaxTree/Member/Abstract - Property 08.fs.bsl b/tests/service/data/SyntaxTree/Member/Abstract - Property 08.fs.bsl new file mode 100644 index 00000000000..b42b585f3d2 --- /dev/null +++ b/tests/service/data/SyntaxTree/Member/Abstract - Property 08.fs.bsl @@ -0,0 +1,44 @@ +ImplFile + (ParsedImplFileInput + ("/root/Member/Abstract - Property 08.fs", false, + QualifiedNameOfFile Module, [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], None, [], [T], + PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector), + false, None, (3,5--3,6)), + ObjectModel + (Unspecified, + [AbstractSlot + (SynValSig + ([], SynIdent (, None), SynValTyparDecls (None, true), + FromParseError (4,12--4,12), + SynValInfo ([], SynArgInfo ([], false, None)), false, + false, + PreXmlDoc ((4,4), FSharp.Compiler.Xml.XmlDocCollector), + Single None, None, (4,4--4,12), + { LeadingKeyword = Abstract (4,4--4,12) + InlineKeyword = None + WithKeyword = None + EqualsRange = None }), + { IsInstance = true + IsDispatchSlot = true + IsOverrideOrExplicitImpl = false + IsFinal = false + GetterOrSetterIsCompilerGenerated = false + MemberKind = PropertyGet }, (4,4--4,12), + { GetSetKeywords = None })], (4,4--4,12)), [], None, + (3,5--4,12), { LeadingKeyword = Type (3,0--3,4) + EqualsRange = Some (3,7--3,8) + WithKeyword = None })], (3,0--4,12)); + Expr (Const (Unit, (6,0--6,2)), (6,0--6,2))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--6,2), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) + +(6,0)-(6,1) parse error Incomplete structured construct at or before this point in member definition. Expected identifier, '(', '(*)' or other token. diff --git a/tests/service/data/SyntaxTree/Member/Abstract - Property 09.fs b/tests/service/data/SyntaxTree/Member/Abstract - Property 09.fs new file mode 100644 index 00000000000..7f6917e8cdf --- /dev/null +++ b/tests/service/data/SyntaxTree/Member/Abstract - Property 09.fs @@ -0,0 +1,6 @@ +module Module + +type T = + abstract private + +() diff --git a/tests/service/data/SyntaxTree/Member/Abstract - Property 09.fs.bsl b/tests/service/data/SyntaxTree/Member/Abstract - Property 09.fs.bsl new file mode 100644 index 00000000000..9577ce92270 --- /dev/null +++ b/tests/service/data/SyntaxTree/Member/Abstract - Property 09.fs.bsl @@ -0,0 +1,45 @@ +ImplFile + (ParsedImplFileInput + ("/root/Member/Abstract - Property 09.fs", false, + QualifiedNameOfFile Module, [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], None, [], [T], + PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector), + false, None, (3,5--3,6)), + ObjectModel + (Unspecified, + [AbstractSlot + (SynValSig + ([], SynIdent (, None), SynValTyparDecls (None, true), + FromParseError (4,12--4,12), + SynValInfo ([], SynArgInfo ([], false, None)), false, + false, + PreXmlDoc ((4,4), FSharp.Compiler.Xml.XmlDocCollector), + Single None, None, (4,4--4,12), + { LeadingKeyword = Abstract (4,4--4,12) + InlineKeyword = None + WithKeyword = None + EqualsRange = None }), + { IsInstance = true + IsDispatchSlot = true + IsOverrideOrExplicitImpl = false + IsFinal = false + GetterOrSetterIsCompilerGenerated = false + MemberKind = PropertyGet }, (4,4--4,12), + { GetSetKeywords = None })], (4,4--4,12)), [], None, + (3,5--4,12), { LeadingKeyword = Type (3,0--3,4) + EqualsRange = Some (3,7--3,8) + WithKeyword = None })], (3,0--4,12)); + Expr (Const (Unit, (6,0--6,2)), (6,0--6,2))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--6,2), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) + +(6,0)-(6,1) parse error Incomplete structured construct at or before this point in member definition. Expected identifier, '(', '(*)' or other token. +(4,13)-(4,20) parse error Accessibility modifiers are not allowed on this member. Abstract slots always have the same visibility as the enclosing type.