diff --git a/docs/release-notes/.FSharp.Compiler.Service/10.0.100.md b/docs/release-notes/.FSharp.Compiler.Service/10.0.100.md index c7f68777166..57835215763 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/10.0.100.md +++ b/docs/release-notes/.FSharp.Compiler.Service/10.0.100.md @@ -8,7 +8,7 @@ * Fix parsing errors using anonymous records and code quotations ([PR #18603](https://github.com/dotnet/fsharp/pull/18603)) * Better error message for attribute targets. ([PR #18641](https://github.com/dotnet/fsharp/pull/18641)) * Fixed: Allow `return`, `return!`, `yield`, `yield!` type annotations without parentheses ([PR #18533](https://github.com/dotnet/fsharp/pull/18533)) -* Allow `let!` and `use!` type annotations without requiring parentheses ([PR #18508](https://github.com/dotnet/fsharp/pull/18508)) +* Allow `let!`, `use!`, `and!` type annotations without requiring parentheses (([PR #18508](https://github.com/dotnet/fsharp/pull/18508) and [PR #18682](https://github.com/dotnet/fsharp/pull/18682))) * Fix find all references for F# exceptions ([PR #18565](https://github.com/dotnet/fsharp/pull/18565)) * Shorthand lambda: fix completion for chained calls and analysis for unfinished expression ([PR #18560](https://github.com/dotnet/fsharp/pull/18560)) * Completion: fix previous namespace considered opened [PR #18609](https://github.com/dotnet/fsharp/pull/18609) diff --git a/docs/release-notes/.Language/preview.md b/docs/release-notes/.Language/preview.md index 687402597c5..0ba66727cd1 100644 --- a/docs/release-notes/.Language/preview.md +++ b/docs/release-notes/.Language/preview.md @@ -8,7 +8,7 @@ * Warn when `unit` is passed to an `obj`-typed argument ([PR #18330](https://github.com/dotnet/fsharp/pull/18330)) * Fix parsing errors using anonymous records and units of measures ([PR #18543](https://github.com/dotnet/fsharp/pull/18543)) * Scoped Nowarn: added the #warnon compiler directive ([Language suggestion #278](https://github.com/fsharp/fslang-suggestions/issues/278), [RFC FS-1146 PR](https://github.com/fsharp/fslang-design/pull/782), [PR #18049](https://github.com/dotnet/fsharp/pull/18049)) -* Allow `let!` and `use!` type annotations without requiring parentheses. ([PR #18508](https://github.com/dotnet/fsharp/pull/18508)) +* Allow `let!`, `use!`, `and!` type annotations without requiring parentheses (([PR #18508](https://github.com/dotnet/fsharp/pull/18508) and [PR #18682](https://github.com/dotnet/fsharp/pull/18682))) ### Fixed diff --git a/src/Compiler/Checking/Expressions/CheckComputationExpressions.fs b/src/Compiler/Checking/Expressions/CheckComputationExpressions.fs index 0d2404c5b1a..00b992a6f92 100644 --- a/src/Compiler/Checking/Expressions/CheckComputationExpressions.fs +++ b/src/Compiler/Checking/Expressions/CheckComputationExpressions.fs @@ -1794,7 +1794,7 @@ let rec TryTranslateComputationExpression ceenv.cenv.g.langVersion.SupportsFeature LanguageFeature.UseBangBindingValueDiscard let supportsTypedLetOrUseBang = - ceenv.cenv.g.langVersion.SupportsFeature LanguageFeature.AllowTypedLetOrUseBang + ceenv.cenv.g.langVersion.SupportsFeature LanguageFeature.AllowTypedLetUseAndBang // use! x = ... // use! (x) = ... diff --git a/src/Compiler/Facilities/LanguageFeatures.fs b/src/Compiler/Facilities/LanguageFeatures.fs index c4b3661bac7..a3a9a3855aa 100644 --- a/src/Compiler/Facilities/LanguageFeatures.fs +++ b/src/Compiler/Facilities/LanguageFeatures.fs @@ -102,7 +102,7 @@ type LanguageFeature = | UseBangBindingValueDiscard | BetterAnonymousRecordParsing | ScopedNowarn - | AllowTypedLetOrUseBang + | AllowTypedLetUseAndBang /// LanguageVersion management type LanguageVersion(versionText) = @@ -235,7 +235,7 @@ type LanguageVersion(versionText) = LanguageFeature.UseBangBindingValueDiscard, languageVersion100 LanguageFeature.BetterAnonymousRecordParsing, languageVersion100 LanguageFeature.ScopedNowarn, languageVersion100 - LanguageFeature.AllowTypedLetOrUseBang, languageVersion100 + LanguageFeature.AllowTypedLetUseAndBang, languageVersion100 LanguageFeature.UnmanagedConstraintCsharpInterop, languageVersion100 LanguageFeature.AllowAccessModifiersToAutoPropertiesGettersAndSetters, languageVersion100 @@ -408,7 +408,7 @@ type LanguageVersion(versionText) = | LanguageFeature.UseBangBindingValueDiscard -> FSComp.SR.featureUseBangBindingValueDiscard () | LanguageFeature.BetterAnonymousRecordParsing -> FSComp.SR.featureBetterAnonymousRecordParsing () | LanguageFeature.ScopedNowarn -> FSComp.SR.featureScopedNowarn () - | LanguageFeature.AllowTypedLetOrUseBang -> FSComp.SR.featureAllowLetOrUseBangTypeAnnotationWithoutParens () + | LanguageFeature.AllowTypedLetUseAndBang -> FSComp.SR.featureAllowLetOrUseBangTypeAnnotationWithoutParens () /// Get a version string associated with the given feature. static member GetFeatureVersionString feature = diff --git a/src/Compiler/Facilities/LanguageFeatures.fsi b/src/Compiler/Facilities/LanguageFeatures.fsi index c9e70ce1567..f034979a6d3 100644 --- a/src/Compiler/Facilities/LanguageFeatures.fsi +++ b/src/Compiler/Facilities/LanguageFeatures.fsi @@ -93,7 +93,7 @@ type LanguageFeature = | UseBangBindingValueDiscard | BetterAnonymousRecordParsing | ScopedNowarn - | AllowTypedLetOrUseBang + | AllowTypedLetUseAndBang /// LanguageVersion management type LanguageVersion = diff --git a/src/Compiler/SyntaxTree/ParseHelpers.fs b/src/Compiler/SyntaxTree/ParseHelpers.fs index 17d2c998012..4aeffc3a056 100644 --- a/src/Compiler/SyntaxTree/ParseHelpers.fs +++ b/src/Compiler/SyntaxTree/ParseHelpers.fs @@ -867,41 +867,19 @@ let mkClassMemberLocalBindings SynMemberDefn.LetBindings(decls, isStatic, isRec, mWhole) -let mkLocalBindings (mWhole, BindingSetPreAttrs(_, isRec, isUse, declsPreAttrs, _), mIn, body: SynExpr) = - let ignoredFreeAttrs, decls = declsPreAttrs [] None +/// Creates a SynExprAndBang node for and! bindings in computation expressions +let mkAndBang (mKeyword: range, pat: SynPat, rhs: SynExpr, mWhole: range, mEquals: range, mIn: range option) = + let spBind = DebugPointAtBinding.Yes(unionRanges mKeyword rhs.Range) - let mWhole = - match decls with - | SynBinding(xmlDoc = xmlDoc) :: _ -> unionRangeWithXmlDoc xmlDoc mWhole - | _ -> mWhole - - if not (isNil ignoredFreeAttrs) then - warning (Error(FSComp.SR.parsAttributesIgnored (), mWhole)) - - let mIn = - mIn - |> Option.bind (fun (mIn: range) -> - if Position.posEq mIn.Start body.Range.Start then - None - else - Some mIn) - - let mLetOrUse = - match decls with - | SynBinding(trivia = trivia) :: _ -> trivia.LeadingKeyword.Range - | _ -> range0 - - SynExpr.LetOrUse( - isRec, - isUse, - decls, - body, - mWhole, + let trivia: SynExprAndBangTrivia = { - LetOrUseKeyword = mLetOrUse + AndBangKeyword = mKeyword + EqualsRange = mEquals InKeyword = mIn } - ) + + // For and!, isUse is always true, isFromSource is always true + SynExprAndBang(spBind, false, true, pat, rhs, mWhole, trivia) let mkDefnBindings (mWhole, BindingSetPreAttrs(_, isRec, isUse, declsPreAttrs, _bindingSetRange), attrs, vis, attrsm) = if isUse then @@ -1073,3 +1051,70 @@ let leadingKeywordIsAbstract = | SynLeadingKeyword.StaticAbstract _ | SynLeadingKeyword.StaticAbstractMember _ -> true | _ -> false + +/// Unified helper for creating let/let!/use/use! expressions +/// Creates either SynExpr.LetOrUse or SynExpr.LetOrUseBang based on isBang parameter +/// Handles all four cases: 'let', 'let!', 'use', and 'use!' +let mkLetExpression + ( + isBang: bool, + mKeyword: range, + mIn: Option, + mWhole: range, + body: SynExpr, + bindingInfo: (bool * BindingSet) option, + bangInfo: (SynPat * SynExpr * SynExprAndBang list * range option * bool) option + ) = + if isBang then + match bangInfo with + | Some(pat, rhs, andBangs, mEquals, isUse) -> + // Create let! or use! expression + let spBind = DebugPointAtBinding.Yes(unionRanges mKeyword rhs.Range) + + let trivia: SynExprLetOrUseBangTrivia = + { + LetOrUseBangKeyword = mKeyword + EqualsRange = mEquals + } + // isFromSource is true for user-written code + SynExpr.LetOrUseBang(spBind, isUse, true, pat, rhs, andBangs, body, mWhole, trivia) + | None -> SynExpr.FromParseError(body, mWhole) + else + match bindingInfo with + | Some(isRec, BindingSetPreAttrs(_, _, isUse, declsPreAttrs, _)) -> + // Create regular let or use expression + let ignoredFreeAttrs, decls = declsPreAttrs [] None + + let mWhole' = + match decls with + | SynBinding(xmlDoc = xmlDoc) :: _ -> unionRangeWithXmlDoc xmlDoc mWhole + | _ -> mWhole + + if not (isNil ignoredFreeAttrs) then + warning (Error(FSComp.SR.parsAttributesIgnored (), mWhole')) + + let mIn' = + mIn + |> Option.bind (fun (mIn: range) -> + if Position.posEq mIn.Start body.Range.Start then + None + else + Some mIn) + + let mLetOrUse = + match decls with + | SynBinding(trivia = trivia) :: _ -> trivia.LeadingKeyword.Range + | _ -> range0 + + SynExpr.LetOrUse( + isRec, + isUse, // Pass through the isUse flag from binding info + decls, + body, + mWhole', + { + LetOrUseKeyword = mLetOrUse + InKeyword = mIn' + } + ) + | None -> SynExpr.FromParseError(body, mWhole) diff --git a/src/Compiler/SyntaxTree/ParseHelpers.fsi b/src/Compiler/SyntaxTree/ParseHelpers.fsi index 84be5f0e4f7..190545286a4 100644 --- a/src/Compiler/SyntaxTree/ParseHelpers.fsi +++ b/src/Compiler/SyntaxTree/ParseHelpers.fsi @@ -196,7 +196,20 @@ val mkClassMemberLocalBindings: isStatic: bool * initialRangeOpt: range option * attrs: SynAttributes * vis: SynAccess option * BindingSet -> SynMemberDefn -val mkLocalBindings: mWhole: range * BindingSet * mIn: range option * body: SynExpr -> SynExpr +/// Creates either SynExpr.LetOrUse or SynExpr.LetOrUseBang based on isBang parameter +/// Handles all four cases: 'let', 'let!', 'use', and 'use!' +val mkLetExpression: + isBang: bool * + mKeyword: range * + mIn: range option * + mWhole: range * + body: SynExpr * + bindingInfo: (bool * BindingSet) option * + bangInfo: (SynPat * SynExpr * SynExprAndBang list * range option * bool) option -> + SynExpr + +val mkAndBang: + mKeyword: range * pat: SynPat * rhs: SynExpr * mWhole: range * mEquals: range * mIn: range option -> SynExprAndBang val mkDefnBindings: mWhole: range * BindingSet * attrs: SynAttributes * vis: SynAccess option * attrsm: range -> SynModuleDecl list diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index f4c291ce262..ee2e4de3fde 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -3520,6 +3520,37 @@ bindingPattern: | headBindingPattern { $1, $1.Range } +// This rule unifies the pattern parsing for both regular 'let' bindings and (let!, use!, and!) +bindingPatternWithOptType: + | headBindingPattern + { // Simple pattern without type annotation + $1, $1.Range, None } + + | headBindingPattern opt_topReturnTypeWithTypeConstraints + { // Pattern with optional type annotation + match $2 with + | None -> + // No type annotation + $1, $1.Range, None + | Some(colonRangeOpt, SynReturnInfo((ty, _), _)) -> + // Pattern with type annotation (e.g., x: int) + let mWhole = unionRanges $1.Range ty.Range + let typedPat = SynPat.Typed($1, ty, mWhole) + typedPat, mWhole, Some ty } + +// Handles the pattern part of let!, use!, and! bindings +ceBindingCore: + | opt_inline opt_mutable bindingPatternWithOptType + { let pat, mPat, tyOpt = $3 + let isInline = Option.isSome $1 + let isMutable = Option.isSome $2 + match tyOpt with + | Some ty -> + parseState.LexBuffer.CheckLanguageFeatureAndRecover LanguageFeature.AllowTypedLetUseAndBang ty.Range + | None -> () + + pat, mPat, isInline, isMutable, tyOpt } + opt_simplePatterns: | simplePatterns { Some $1 } @@ -4080,12 +4111,13 @@ sequentialExpr: SynExpr.Sequential(DebugPointAtSequential.SuppressNeither, false, $1, $4, unionRanges $1.Range $4.Range, trivia) } | hardwhiteLetBindings %prec prec_args_error - { let hwlb, m, mIn = $1 - let mLetKwd, isUse = match hwlb with (BindingSetPreAttrs(m, _, isUse, _, _)) -> m, isUse + { let bindingSet, m, mIn = $1 + let mLetKwd, isUse = match bindingSet with (BindingSetPreAttrs(m, _, isUse, _, _)) -> m, isUse let usedKeyword = if isUse then "use" else "let" reportParseErrorAt mLetKwd (FSComp.SR.parsExpectedExpressionAfterLet(usedKeyword, usedKeyword)) let fauxRange = m.EndRange // zero width range at end of m - mkLocalBindings (m, hwlb, mIn, arbExpr ("seqExpr", fauxRange)) } + let isRec = match bindingSet with BindingSetPreAttrs(_, isRec, _, _, _) -> isRec + mkLetExpression(false, mLetKwd, mIn, m, arbExpr ("seqExpr", fauxRange), Some(isRec, bindingSet), None) } /* Use this as the last terminal when performing error recovery */ /* The contract for using this is that (a) if EOF occurs then the */ @@ -4099,22 +4131,35 @@ recover: { debugPrint("recovering via EOF"); false } moreBinders: - | AND_BANG headBindingPattern EQUALS typedSequentialExprBlock IN moreBinders %prec expr_let - { let spBind = DebugPointAtBinding.Yes(rhs2 parseState 1 5) (* TODO Pretty sure this is wrong *) + | AND_BANG ceBindingCore EQUALS typedSequentialExprBlock IN moreBinders %prec expr_let + { let pat, mPat, isInline, isMutable, tyOpt = $2 + + // and! bindings don't support inline or mutable modifiers + if isInline then errorR(Error(FSComp.SR.parsInvalidDeclarationSyntax(), rhs parseState 2)) + if isMutable then errorR(Error(FSComp.SR.parsInvalidDeclarationSyntax(), rhs parseState 2)) + + let mKeyword = rhs parseState 1 let mEquals = rhs parseState 3 - let m = unionRanges (rhs parseState 1) $4.Range - let mIn = rhs parseState 5 - let trivia = { AndBangKeyword = rhs parseState 1; EqualsRange = mEquals; InKeyword = Some mIn } - SynExprAndBang(spBind, $1, true, $2, $4, m, trivia) :: $6 } - - | OAND_BANG headBindingPattern EQUALS typedSequentialExprBlock hardwhiteDefnBindingsTerminator opt_OBLOCKSEP moreBinders %prec expr_let - { let report, mIn, _ = $5 + let m = unionRanges mKeyword $4.Range + let mIn = Some(rhs parseState 5) + + mkAndBang(mKeyword, pat, $4, m, mEquals, mIn) :: $6 } + + | OAND_BANG ceBindingCore EQUALS typedSequentialExprBlock hardwhiteDefnBindingsTerminator opt_OBLOCKSEP moreBinders %prec expr_let + { // Offside-sensitive version of and! binding + let pat, mPat, isInline, isMutable, tyOpt = $2 + + // and! bindings don't support inline or mutable modifiers + if isInline then errorR(Error(FSComp.SR.parsInvalidDeclarationSyntax(), rhs parseState 2)) + if isMutable then errorR(Error(FSComp.SR.parsInvalidDeclarationSyntax(), rhs parseState 2)) + + let report, mIn, _ = $5 report "and!" (rhs parseState 1) // report unterminated error - let spBind = DebugPointAtBinding.Yes(rhs2 parseState 1 5) (* TODO Pretty sure this is wrong *) + let mKeyword = rhs parseState 1 let mEquals = rhs parseState 3 - let m = unionRanges (rhs parseState 1) $4.Range - let trivia = { AndBangKeyword = rhs parseState 1; EqualsRange = mEquals; InKeyword = mIn } - SynExprAndBang(spBind, $1, true, $2, $4, m, trivia) :: $7 } + let m = unionRanges mKeyword $4.Range + + mkAndBang(mKeyword, pat, $4, m, mEquals, mIn) :: $7 } | %prec prec_no_more_attr_bindings { [] } @@ -4122,32 +4167,45 @@ moreBinders: declExpr: | defnBindings IN typedSequentialExpr %prec expr_let { let mIn = rhs parseState 2 |> Some - mkLocalBindings (unionRanges (rhs2 parseState 1 2) $3.Range, $1, mIn, $3) } + let mWhole = unionRanges (rhs2 parseState 1 2) $3.Range + let bindingSet = $1 + let mKeyword, isRec = match bindingSet with BindingSetPreAttrs(m, isRec, _, _, _) -> m, isRec + mkLetExpression(false, mKeyword, mIn, mWhole, $3, Some(isRec, bindingSet), None) } | defnBindings IN error %prec expr_let { let mIn = rhs parseState 2 |> Some - mkLocalBindings (rhs2 parseState 1 2, $1, mIn, arbExpr ("declExpr1", (rhs parseState 3))) } + let mWhole = rhs2 parseState 1 2 + let bindingSet = $1 + let mKeyword, isRec = match bindingSet with BindingSetPreAttrs(m, isRec, _, _, _) -> m, isRec + mkLetExpression(false, mKeyword, mIn, mWhole, arbExpr ("declExpr1", (rhs parseState 3)), Some(isRec, bindingSet), None) } /* FSComp.SR.parsNoMatchingInForLet() -- leave this in for now - it's an unused error string */ | hardwhiteLetBindings typedSequentialExprBlock %prec expr_let - { let hwlb, m, mIn = $1 - mkLocalBindings (unionRanges m $2.Range, hwlb, mIn, $2) } + { let bindingSet, m, mIn = $1 + let mWhole = unionRanges m $2.Range + let mKeyword, isRec = match bindingSet with BindingSetPreAttrs(m, isRec, _, _, _) -> m, isRec + mkLetExpression(false, mKeyword, mIn, mWhole, $2, Some(isRec, bindingSet), None) } | hardwhiteLetBindings error %prec expr_let - { let hwlb, m, mIn = $1 - reportParseErrorAt (match hwlb with (BindingSetPreAttrs(m, _, _, _, _)) -> m) (FSComp.SR.parsErrorInReturnForLetIncorrectIndentation()) - mkLocalBindings (m, hwlb, mIn, arbExpr ("declExpr2", (rhs parseState 2))) } + { let bindingSet, m, mIn = $1 + reportParseErrorAt (match bindingSet with (BindingSetPreAttrs(m, _, _, _, _)) -> m) (FSComp.SR.parsErrorInReturnForLetIncorrectIndentation()) + let mKeyword, isRec = match bindingSet with BindingSetPreAttrs(m, isRec, _, _, _) -> m, isRec + mkLetExpression(false, mKeyword, mIn, m, arbExpr ("declExpr2", (rhs parseState 2)), Some(isRec, bindingSet), None) } | hardwhiteLetBindings OBLOCKSEP typedSequentialExprBlock %prec expr_let - { let hwlb, m, mIn = $1 - mkLocalBindings (unionRanges m $3.Range, hwlb, mIn, $3) } + { let bindingSet, m, mIn = $1 + let mWhole = unionRanges m $3.Range + let mKeyword, isRec = match bindingSet with BindingSetPreAttrs(m, isRec, _, _, _) -> m, isRec + mkLetExpression(false, mKeyword, mIn, mWhole, $3, Some(isRec, bindingSet), None) } | hardwhiteLetBindings OBLOCKSEP error %prec expr_let - { let hwlb, m, mIn = $1 - //reportParseErrorAt (match hwlb with (BindingSetPreAttrs(m, _, _, _, _)) -> m) (FSComp.SR.parsErrorInReturnForLetIncorrectIndentation()) - mkLocalBindings (unionRanges m (rhs parseState 3), hwlb, mIn, arbExpr ("declExpr3", (rhs parseState 3))) } + { let bindingSet, m, mIn = $1 + //reportParseErrorAt (match bindingSet with (BindingSetPreAttrs(m, _, _, _, _)) -> m) (FSComp.SR.parsErrorInReturnForLetIncorrectIndentation()) + let mWhole = unionRanges m (rhs parseState 3) + let mKeyword, isRec = match bindingSet with BindingSetPreAttrs(m, isRec, _, _, _) -> m, isRec + mkLetExpression(false, mKeyword, mIn, mWhole, arbExpr ("declExpr3", (rhs parseState 3)), Some(isRec, bindingSet), None) } | hardwhiteDoBinding %prec expr_let { let (BindingSetPreAttrs(_, _, _, _, m)), e = $1 @@ -4429,7 +4487,7 @@ declExpr: | YIELD declExpr COLON typ { let trivia: SynExprYieldOrReturnTrivia = { YieldOrReturnKeyword = rhs parseState 1 } let typedExpr = SynExpr.Typed($2, $4, unionRanges $2.Range $4.Range) - parseState.LexBuffer.CheckLanguageFeatureAndRecover LanguageFeature.AllowTypedLetOrUseBang typedExpr.Range + parseState.LexBuffer.CheckLanguageFeatureAndRecover LanguageFeature.AllowTypedLetUseAndBang typedExpr.Range SynExpr.YieldOrReturn(($1, not $1), typedExpr, (unionRanges (rhs parseState 1) $4.Range), trivia) } | YIELD declExpr opt_topReturnTypeWithTypeConstraints @@ -4439,7 +4497,7 @@ declExpr: | None -> $2 | Some(_, SynReturnInfo((ty, _), m)) -> let m = unionRanges $2.Range m - parseState.LexBuffer.CheckLanguageFeatureAndRecover LanguageFeature.AllowTypedLetOrUseBang m + parseState.LexBuffer.CheckLanguageFeatureAndRecover LanguageFeature.AllowTypedLetUseAndBang m SynExpr.Typed($2, ty, m) SynExpr.YieldOrReturn(($1, not $1), expr, (unionRanges (rhs parseState 1) expr.Range), trivia) } @@ -4456,7 +4514,7 @@ declExpr: | YIELD_BANG declExpr COLON typ { let trivia: SynExprYieldOrReturnFromTrivia = { YieldOrReturnFromKeyword = rhs parseState 1 } let typedExpr = SynExpr.Typed($2, $4, unionRanges $2.Range $4.Range) - parseState.LexBuffer.CheckLanguageFeatureAndRecover LanguageFeature.AllowTypedLetOrUseBang typedExpr.Range + parseState.LexBuffer.CheckLanguageFeatureAndRecover LanguageFeature.AllowTypedLetUseAndBang typedExpr.Range SynExpr.YieldOrReturnFrom(($1, not $1), typedExpr, (unionRanges (rhs parseState 1) $2.Range), trivia) } | YIELD_BANG declExpr opt_topReturnTypeWithTypeConstraints @@ -4466,73 +4524,63 @@ declExpr: | None -> $2 | Some(_, SynReturnInfo((ty, _), m)) -> let m = unionRanges $2.Range m - parseState.LexBuffer.CheckLanguageFeatureAndRecover LanguageFeature.AllowTypedLetOrUseBang m + parseState.LexBuffer.CheckLanguageFeatureAndRecover LanguageFeature.AllowTypedLetUseAndBang m SynExpr.Typed($2, ty, m) SynExpr.YieldOrReturnFrom(($1, not $1), expr, (unionRanges (rhs parseState 1) $2.Range), trivia) } - | BINDER headBindingPattern EQUALS typedSequentialExprBlock IN opt_OBLOCKSEP moreBinders typedSequentialExprBlock %prec expr_let - { (* This rule handles the 'use!' and 'let!' binding expressions in computation expressions *) - (* The BINDER token represents keywords like 'use!' or 'let!' *) - (* headBindingPattern represents patterns in the binding: - - Underscore ('_') patterns are preserved as SynPat.Wild - - Named patterns ('__') are represented as SynPat.Named - - Identifiers (like 'value') are represented as SynPat.LongIdent *) - let spBind = DebugPointAtBinding.Yes(rhs2 parseState 1 5) - let mEquals = rhs parseState 3 - let m = unionRanges (rhs parseState 1) $8.Range - let trivia: SynExprLetOrUseBangTrivia = { LetOrUseBangKeyword = rhs parseState 1 ; EqualsRange = Some mEquals } - SynExpr.LetOrUseBang(spBind, ($1 = "use"), true, $2, $4, $7, $8, m, trivia) } - - | OBINDER headBindingPattern EQUALS typedSequentialExprBlock hardwhiteDefnBindingsTerminator opt_OBLOCKSEP moreBinders typedSequentialExprBlock %prec expr_let - { let report, mIn, _ = $5 + | BINDER ceBindingCore EQUALS typedSequentialExprBlock IN opt_OBLOCKSEP moreBinders typedSequentialExprBlock %prec expr_let + { // Handle let! and use! bindings with unified pattern parsing + let pat, mPat, isInline, isMutable, tyOpt = $2 + + // let! and use! bindings don't support inline or mutable modifiers + if isInline then errorR(Error(FSComp.SR.parsInvalidDeclarationSyntax(), rhs parseState 2)) + if isMutable then errorR(Error(FSComp.SR.parsInvalidDeclarationSyntax(), rhs parseState 2)) + + let mKeyword = rhs parseState 1 + let mEquals = Some(rhs parseState 3) + let m = unionRanges mKeyword $8.Range + + // $1 contains the actual keyword ("let" or "use") + let isUse = ($1 = "use") + + mkLetExpression(true, mKeyword, None, m, $8, None, Some(pat, $4, $7, mEquals, isUse)) } + + | OBINDER ceBindingCore EQUALS typedSequentialExprBlock hardwhiteDefnBindingsTerminator opt_OBLOCKSEP moreBinders typedSequentialExprBlock %prec expr_let + { // Offside-sensitive version of let!/use! binding + let pat, mPat, isInline, isMutable, tyOpt = $2 + + // let! and use! bindings don't support inline or mutable modifiers + if isInline then errorR(Error(FSComp.SR.parsInvalidDeclarationSyntax(), rhs parseState 2)) + if isMutable then errorR(Error(FSComp.SR.parsInvalidDeclarationSyntax(), rhs parseState 2)) + + let report, mIn, _ = $5 report (if $1 = "use" then "use!" else "let!") (rhs parseState 1) // report unterminated error - let spBind = DebugPointAtBinding.Yes(unionRanges (rhs parseState 1) $4.Range) - let mEquals = rhs parseState 3 - let m = unionRanges (rhs parseState 1) $8.Range - let trivia: SynExprLetOrUseBangTrivia = { LetOrUseBangKeyword = rhs parseState 1 ; EqualsRange = Some mEquals } - SynExpr.LetOrUseBang(spBind, ($1 = "use"), true, $2, $4, $7, $8, m, trivia) } - - | BINDER headBindingPattern opt_topReturnTypeWithTypeConstraints EQUALS typedSequentialExprBlock IN opt_OBLOCKSEP moreBinders typedSequentialExprBlock %prec expr_let - { // Handle type annotations on patterns in let!/use! bindings - // Examples: let! x: int = async { return 1 } - // use! _: IDisposable = async { return new MemoryStream() } - let spBind = DebugPointAtBinding.Yes(rhs2 parseState 1 7) - let pat = - match $3 with - | None -> $2 - | Some (_, SynReturnInfo((ty, _), _)) -> - SynPat.Typed($2, ty, unionRanges $2.Range ty.Range) - parseState.LexBuffer.CheckLanguageFeatureAndRecover LanguageFeature.AllowTypedLetOrUseBang pat.Range - let mEquals = rhs parseState 4 - let m = unionRanges (rhs parseState 1) $9.Range - let trivia: SynExprLetOrUseBangTrivia = { LetOrUseBangKeyword = rhs parseState 1 ; EqualsRange = Some mEquals } - SynExpr.LetOrUseBang(spBind, ($1 = "use"), true, pat, $5, $8, $9, m, trivia) } - - | OBINDER headBindingPattern opt_topReturnTypeWithTypeConstraints EQUALS typedSequentialExprBlock hardwhiteDefnBindingsTerminator opt_OBLOCKSEP moreBinders typedSequentialExprBlock %prec expr_let - { // Handle type annotations on patterns in let!/use! bindings (offside-sensitive version) - // This rule maintains consistent handling of binding constructs across different syntactic contexts - let report, mIn, _ = $6 - report (if $1 = "use" then "use!" else "let!") (rhs parseState 1) // report unterminated error - let spBind = DebugPointAtBinding.Yes(unionRanges (rhs parseState 1) $5.Range) - let pat = - match $3 with - | None -> $2 - | Some (_, SynReturnInfo((ty, _), _)) -> - SynPat.Typed($2, ty, unionRanges $2.Range ty.Range) - parseState.LexBuffer.CheckLanguageFeatureAndRecover LanguageFeature.AllowTypedLetOrUseBang pat.Range - let mEquals = rhs parseState 4 - let m = unionRanges (rhs parseState 1) $9.Range - let trivia: SynExprLetOrUseBangTrivia = { LetOrUseBangKeyword = rhs parseState 1 ; EqualsRange = Some mEquals } - SynExpr.LetOrUseBang(spBind, ($1 = "use"), true, pat, $5, $8, $9, m, trivia) } - - | OBINDER headBindingPattern EQUALS typedSequentialExprBlock hardwhiteDefnBindingsTerminator opt_OBLOCKSEP error %prec expr_let - { // error recovery that allows intellisense when writing incomplete computation expressions - let spBind = DebugPointAtBinding.Yes(unionRanges (rhs parseState 1) $4.Range) - let mEquals = rhs parseState 3 - let mAll = unionRanges (rhs parseState 1) (rhs parseState 7) + let mKeyword = rhs parseState 1 + let mEquals = Some(rhs parseState 3) + let m = unionRanges mKeyword $8.Range + + let isUse = ($1 = "use") + + mkLetExpression(true, mKeyword, None, m, $8, None, Some(pat, $4, $7, mEquals, isUse)) } + + | OBINDER ceBindingCore EQUALS typedSequentialExprBlock hardwhiteDefnBindingsTerminator opt_OBLOCKSEP error %prec expr_let + { // Error recovery for incomplete let!/use! bindings + // Allows intellisense to work when writing incomplete computation expressions + let pat, mPat, isInline, isMutable, tyOpt = $2 + + // Error checking for invalid modifiers + if isInline then errorR(Error(FSComp.SR.parsInvalidDeclarationSyntax(), rhs parseState 2)) + if isMutable then errorR(Error(FSComp.SR.parsInvalidDeclarationSyntax(), rhs parseState 2)) + + let mKeyword = rhs parseState 1 + let mEquals = Some(rhs parseState 3) + let mAll = unionRanges mKeyword (rhs parseState 7) let m = $4.Range.EndRange // zero-width range - let trivia: SynExprLetOrUseBangTrivia = { LetOrUseBangKeyword = rhs parseState 1 ; EqualsRange = Some mEquals } - SynExpr.LetOrUseBang(spBind, ($1 = "use"), true, $2, $4, [], SynExpr.ImplicitZero m, mAll, trivia) } + + let isUse = ($1 = "use") + + // Use ImplicitZero as the continuation expression for error recovery + mkLetExpression(true, mKeyword, None, mAll, SynExpr.ImplicitZero m, None, Some(pat, $4, [], mEquals, isUse)) } | DO_BANG typedSequentialExpr IN opt_OBLOCKSEP typedSequentialExprBlock %prec expr_let { let spBind = DebugPointAtBinding.NoneAtDo @@ -5991,6 +6039,7 @@ opt_topReturnTypeWithTypeConstraints: | COLON recover { let mColon = rhs parseState 1 let ty, arity = SynType.FromParseError(mColon.EndRange), SynInfo.unnamedRetVal + reportParseErrorAt mColon.EndRange (FSComp.SR.parsExpectingType ()) Some(Some mColon, SynReturnInfo((ty, arity), mColon.EndRange)) } topType: diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/UseBindings/UseBangBindings.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/UseBindings/UseBangBindings.fs index 77ac4e5706f..79fd3535db9 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/UseBindings/UseBangBindings.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/UseBindings/UseBangBindings.fs @@ -59,9 +59,9 @@ module UseBangBindingsVersion9 = |> typecheck |> shouldFail |> withDiagnostics [ - (Error 3350, Line 43, Col 14, Line 43, Col 28, "Feature 'Allow let! and use! type annotations without requiring parentheses' is not available in F# 9.0. Please use language version 10.0 or greater.") - (Error 3350, Line 41, Col 14, Line 41, Col 28, "Feature 'Allow let! and use! type annotations without requiring parentheses' is not available in F# 9.0. Please use language version 10.0 or greater.") - (Error 3350, Line 40, Col 14, Line 40, Col 29, "Feature 'Allow let! and use! type annotations without requiring parentheses' is not available in F# 9.0. Please use language version 10.0 or greater.") + (Error 3350, Line 40, Col 18, Line 40, Col 29, "Feature 'Allow let! and use! type annotations without requiring parentheses' is not available in F# 9.0. Please use language version 10.0 or greater.") + (Error 3350, Line 41, Col 17, Line 41, Col 28, "Feature 'Allow let! and use! type annotations without requiring parentheses' is not available in F# 9.0. Please use language version 10.0 or greater.") + (Error 3350, Line 43, Col 17, Line 43, Col 28, "Feature 'Allow let! and use! type annotations without requiring parentheses' is not available in F# 9.0. Please use language version 10.0 or greater.") ] module UseBangBindingsPreview = diff --git a/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs index b9dc7b2b76d..d7a6d342996 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs @@ -1521,4 +1521,511 @@ let fooTask () : Task = task { is not compatible with type 'TaskCode' ") - ] \ No newline at end of file + ] + + [] + let ``Version 9.0: and! with type annotations requires parentheses`` () = + FSharp """ +module Test + +type ParallelBuilder() = + member _.Return(x) = async { return x } + member _.ReturnFrom(computation: Async<'T>) = computation + member _.Bind(computation: Async<'T>, binder: 'T -> Async<'U>) = + async { + let! x = computation + return! binder x + } + member _.Bind2(comp1: Async<'T1>, comp2: Async<'T2>, binder: 'T1 * 'T2 -> Async<'U>) = + async { + let! task1 = Async.StartChild comp1 + let! task2 = Async.StartChild comp2 + let! result1 = task1 + let! result2 = task2 + return! binder (result1, result2) + } + + member _.Zero() = async.Zero() + member _.Combine(comp1, comp2) = async.Combine(comp1, comp2) + member _.Delay(f) = async.Delay(f) + +let parallelCE = ParallelBuilder() + +let testParallel() = + parallelCE { + let! x = async { return 1 } + and! y = async { return 2 } + return x + y + } + +let testParallel2() = + parallelCE { + let! (x: int) = async { return 1 } + and! (y: int) = async { return 2 } + return x + y + } + +let testParallel3() = + parallelCE { + let! x: int = async { return 1 } + and! y: int = async { return 2 } + return x + y + } + """ + |> withLangVersion90 + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 3350, Line 43, Col 17, Line 43, Col 20, "Feature 'Allow let! and use! type annotations without requiring parentheses' is not available in F# 9.0. Please use language version 10.0 or greater."); + (Error 3350, Line 44, Col 17, Line 44, Col 20, "Feature 'Allow let! and use! type annotations without requiring parentheses' is not available in F# 9.0. Please use language version 10.0 or greater.") + ] + + [] + let ``Preview: and! with type annotations works without parentheses`` () = + FSharp """ +module Test + +type ParallelBuilder() = + member _.Return(x) = async { return x } + member _.ReturnFrom(computation: Async<'T>) = computation + member _.Bind(computation: Async<'T>, binder: 'T -> Async<'U>) = + async { + let! x = computation + return! binder x + } + member _.Bind2(comp1: Async<'T1>, comp2: Async<'T2>, binder: 'T1 * 'T2 -> Async<'U>) = + async { + let! task1 = Async.StartChild comp1 + let! task2 = Async.StartChild comp2 + let! result1 = task1 + let! result2 = task2 + return! binder (result1, result2) + } + + member _.Zero() = async.Zero() + member _.Combine(comp1, comp2) = async.Combine(comp1, comp2) + member _.Delay(f) = async.Delay(f) + +let parallelCE = ParallelBuilder() + +let testParallel() = + parallelCE { + let! x = async { return 1 } + and! y = async { return 2 } + return x + y + } + +let testParallel2() = + parallelCE { + let! (x: int) = async { return 1 } + and! (y: int) = async { return 2 } + return x + y + } + +let testParallel3() = + parallelCE { + let! x: int = async { return 1 } + and! y: int = async { return 2 } + return x + y + } + +let result = testParallel() |> Async.RunSynchronously +let result2 = testParallel2() |> Async.RunSynchronously +let result3 = testParallel3() |> Async.RunSynchronously +if result <> 3 then failwithf $"Expected 3, but got {result}" +if result2 <> 3 then failwithf $"Expected 3, but got {result2}" +if result3 <> 3 then failwithf $"Expected 3, but got {result3}" + """ + |> withLangVersionPreview + |> asExe + |> compileAndRun + |> shouldSucceed + + [] + let ``Version 9.0: and! with record patterns and type annotations requires parentheses`` () = + FSharp """ +module Test + +type Person = { Name: string; Age: int } +type User = { Id: int; Username: string } + +type ParallelBuilder() = + member _.Return(x) = async { return x } + member _.ReturnFrom(computation: Async<'T>) = computation + member _.Bind(computation: Async<'T>, binder: 'T -> Async<'U>) = + async { + let! x = computation + return! binder x + } + member _.Bind2(comp1: Async<'T1>, comp2: Async<'T2>, binder: 'T1 * 'T2 -> Async<'U>) = + async { + let! task1 = Async.StartChild comp1 + let! task2 = Async.StartChild comp2 + let! result1 = task1 + let! result2 = task2 + return! binder (result1, result2) + } + + member _.Zero() = async.Zero() + member _.Combine(comp1, comp2) = async.Combine(comp1, comp2) + member _.Delay(f) = async.Delay(f) + +let parallelCE = ParallelBuilder() + +let asyncPerson() = async { return { Name = "John"; Age = 30 } } +let asyncUser() = async { return { Id = 1; Username = "john_doe" } } + +let testParallel1() = + parallelCE { + let! ({ Name = name; Age = age }: Person) = asyncPerson() + and! ({ Id = id; Username = username }: User) = asyncUser() + return (name, age, id, username) + } + +let testParallel2() = + parallelCE { + let! { Name = name; Age = age }: Person = asyncPerson() + and! { Id = id; Username = username }: User = asyncUser() + return (name, age, id, username) + } + """ + |> withLangVersion90 + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 3350, Line 42, Col 42, Line 42, Col 48, "Feature 'Allow let! and use! type annotations without requiring parentheses' is not available in F# 9.0. Please use language version 10.0 or greater."); + (Error 3350, Line 43, Col 48, Line 43, Col 52, "Feature 'Allow let! and use! type annotations without requiring parentheses' is not available in F# 9.0. Please use language version 10.0 or greater.") + ] + + [] + let ``Preview: and! with record patterns and type annotations works without parentheses`` () = + FSharp """ +module Test + +type Person = { Name: string; Age: int } +type User = { Id: int; Username: string } + +type ParallelBuilder() = + member _.Return(x) = async { return x } + member _.ReturnFrom(computation: Async<'T>) = computation + member _.Bind(computation: Async<'T>, binder: 'T -> Async<'U>) = + async { + let! x = computation + return! binder x + } + member _.Bind2(comp1: Async<'T1>, comp2: Async<'T2>, binder: 'T1 * 'T2 -> Async<'U>) = + async { + let! task1 = Async.StartChild comp1 + let! task2 = Async.StartChild comp2 + let! result1 = task1 + let! result2 = task2 + return! binder (result1, result2) + } + + member _.Zero() = async.Zero() + member _.Combine(comp1, comp2) = async.Combine(comp1, comp2) + member _.Delay(f) = async.Delay(f) + +let parallelCE = ParallelBuilder() + +let asyncPerson() = async { return { Name = "John"; Age = 30 } } +let asyncUser() = async { return { Id = 1; Username = "john_doe" } } + +let testParallel1() = + parallelCE { + let! ({ Name = name; Age = age }: Person) = asyncPerson() + and! ({ Id = id; Username = username }: User) = asyncUser() + return (name, age, id, username) + } + +let testParallel2() = + parallelCE { + let! { Name = name; Age = age }: Person = asyncPerson() + and! { Id = id; Username = username }: User = asyncUser() + return (name, age, id, username) + } + +let result1 = testParallel1() |> Async.RunSynchronously +let result2 = testParallel2() |> Async.RunSynchronously + +if result1 <> ("John", 30, 1, "john_doe") then + failwithf $"Expected ('John', 30, 1, 'john_doe'), but got %A{result1}" +if result2 <> ("John", 30, 1, "john_doe") then + failwithf $"Expected ('John', 30, 1, 'john_doe'), but got %A{result2}" + """ + |> withLangVersionPreview + |> asExe + |> compileAndRun + |> shouldSucceed + + [] + let ``Version 9.0: and! with union patterns and type annotations requires parentheses`` () = + FSharp """ +module Test + +type MyOption<'T> = Some of 'T | None + +type ParallelBuilder() = + member _.Return(x) = async { return x } + member _.ReturnFrom(computation: Async<'T>) = computation + member _.Bind(computation: Async<'T>, binder: 'T -> Async<'U>) = + async { + let! x = computation + return! binder x + } + member _.Bind2(comp1: Async<'T1>, comp2: Async<'T2>, binder: 'T1 * 'T2 -> Async<'U>) = + async { + let! task1 = Async.StartChild comp1 + let! task2 = Async.StartChild comp2 + let! result1 = task1 + let! result2 = task2 + return! binder (result1, result2) + } + + member _.Zero() = async.Zero() + member _.Combine(comp1, comp2) = async.Combine(comp1, comp2) + member _.Delay(f) = async.Delay(f) + +let parallelCE = ParallelBuilder() + +let asyncOption1() = async { return MyOption.Some 42 } +let asyncOption2() = async { return MyOption.Some "hello" } + +let testParallel() = + parallelCE { + let! (Some value1): MyOption = asyncOption1() + and! (Some value2): MyOption = asyncOption2() + return (value1, value2) + } + +let testParallel2() = + parallelCE { + let! Some value1: MyOption = asyncOption1() + and! Some value2: MyOption = asyncOption2() + return (value1, value2) + } + """ + |> withLangVersion90 + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 3350, Line 34, Col 29, Line 34, Col 42, "Feature 'Allow let! and use! type annotations without requiring parentheses' is not available in F# 9.0. Please use language version 10.0 or greater."); + (Error 3350, Line 35, Col 29, Line 35, Col 45, "Feature 'Allow let! and use! type annotations without requiring parentheses' is not available in F# 9.0. Please use language version 10.0 or greater."); + (Error 3350, Line 41, Col 27, Line 41, Col 40, "Feature 'Allow let! and use! type annotations without requiring parentheses' is not available in F# 9.0. Please use language version 10.0 or greater."); + (Error 3350, Line 42, Col 27, Line 42, Col 43, "Feature 'Allow let! and use! type annotations without requiring parentheses' is not available in F# 9.0. Please use language version 10.0 or greater.") + ] + + [] + let ``Preview: and! with union patterns and type annotations works without parentheses`` () = + FSharp """ +module Test + +type MyOption<'T> = Some of 'T | None + +type ParallelBuilder() = + member _.Return(x) = async { return x } + member _.ReturnFrom(computation: Async<'T>) = computation + member _.Bind(computation: Async<'T>, binder: 'T -> Async<'U>) = + async { + let! x = computation + return! binder x + } + member _.Bind2(comp1: Async<'T1>, comp2: Async<'T2>, binder: 'T1 * 'T2 -> Async<'U>) = + async { + let! task1 = Async.StartChild comp1 + let! task2 = Async.StartChild comp2 + let! result1 = task1 + let! result2 = task2 + return! binder (result1, result2) + } + + member _.Zero() = async.Zero() + member _.Combine(comp1, comp2) = async.Combine(comp1, comp2) + member _.Delay(f) = async.Delay(f) + +let parallelCE = ParallelBuilder() + +let asyncOption1() = async { return MyOption.Some 42 } +let asyncOption2() = async { return MyOption.Some "hello" } + +let testParallel1() = + parallelCE { + let! (Some value1): MyOption = asyncOption1() + and! (Some value2): MyOption = asyncOption2() + return (value1, value2) + } + +let testParallel2() = + parallelCE { + let! Some value1: MyOption = asyncOption1() + and! Some value2: MyOption = asyncOption2() + return (value1, value2) + } + +let result1 = testParallel1() |> Async.RunSynchronously +let result2 = testParallel2() |> Async.RunSynchronously + +if result1 <> (42, "hello") then + failwithf $"Expected (42, 'hello'), but got %A{result1}" +if result2 <> (42, "hello") then + failwithf $"Expected (42, 'hello'), but got %A{result2}" + """ + |> withLangVersionPreview + |> asExe + |> ignoreWarnings + |> compileAndRun + |> shouldSucceed + + [] + let ``Preview: and! with mixed patterns and type annotations works`` () = + FSharp """ +module Test + +type Person = { Name: string; Age: int } + +type ParallelBuilder() = + member _.Return(x) = async { return x } + member _.ReturnFrom(computation: Async<'T>) = computation + member _.Bind(computation: Async<'T>, binder: 'T -> Async<'U>) = + async { + let! x = computation + return! binder x + } + member _.Bind2(comp1: Async<'T1>, comp2: Async<'T2>, binder: 'T1 * 'T2 -> Async<'U>) = + async { + let! task1 = Async.StartChild comp1 + let! task2 = Async.StartChild comp2 + let! result1 = task1 + let! result2 = task2 + return! binder (result1, result2) + } + + member _.Zero() = async.Zero() + member _.Combine(comp1, comp2) = async.Combine(comp1, comp2) + member _.Delay(f) = async.Delay(f) + +let parallelCE = ParallelBuilder() + +let asyncInt() = async { return 42 } +let asyncPerson() = async { return { Name = "Alice"; Age = 25 } } + +// Test mixing different pattern types with type annotations +let testMixed() = + parallelCE { + let! x: int = asyncInt() + and! { Name = name; Age = age }: Person = asyncPerson() + return (x, name, age) + } + +// Test with parentheses on one and not the other +let testMixed2() = + parallelCE { + let! (y: int) = asyncInt() + and! { Name = name2; Age = age2 }: Person = asyncPerson() + return (y, name2, age2) + } + +let result1 = testMixed() |> Async.RunSynchronously +let result2 = testMixed2() |> Async.RunSynchronously + +if result1 <> (42, "Alice", 25) then + failwithf $"Expected (42, 'Alice', 25), but got %A{result1}" +if result2 <> (42, "Alice", 25) then + failwithf $"Expected (42, 'Alice', 25), but got %A{result2}" + """ + |> withLangVersionPreview + |> asExe + |> compileAndRun + |> shouldSucceed + + [] + let ``Preview: multiple and! with type annotations works`` () = + FSharp """ +module Test + +type Builder() = + member _.Return(x) = async { return x } + member _.Bind(computation: Async<'T>, binder: 'T -> Async<'U>) = + async { + let! x = computation + return! binder x + } + member _.Bind3(comp1: Async<'T1>, comp2: Async<'T2>, comp3: Async<'T3>, binder: 'T1 * 'T2 * 'T3 -> Async<'U>) = + async { + let! task1 = Async.StartChild comp1 + let! task2 = Async.StartChild comp2 + let! task3 = Async.StartChild comp3 + let! result1 = task1 + let! result2 = task2 + let! result3 = task3 + return! binder (result1, result2, result3) + } + + member _.Zero() = async.Zero() + member _.Combine(comp1, comp2) = async.Combine(comp1, comp2) + member _.Delay(f) = async.Delay(f) + +let builder = Builder() + +let asyncInt() = async { return 42 } +let asyncString() = async { return "test" } +let asyncFloat() = async { return 3.14 } + +// Test multiple and! with type annotations +let testMultiple() = + builder { + let! x: int = asyncInt() + and! y: string = asyncString() + and! z: float = asyncFloat() + return (x, y, z) + } + +let result = testMultiple() |> Async.RunSynchronously + +if result <> (42, "test", 3.14) then + failwithf $"Expected (42, 'test', 3.14), but got %A{result}" + """ + |> withLangVersionPreview + |> asExe + |> compileAndRun + |> shouldSucceed + + [] + let ``Preview: and! with generic type annotations works`` () = + FSharp """ +module Test + +type Result<'T, 'E> = Ok of 'T | Error of 'E + +type ResultBuilder() = + member _.Return(x) = Ok x + member _.Bind(m: Result<'T, 'E>, f: 'T -> Result<'U, 'E>) = + match m with + | Ok x -> f x + | Error e -> Error e + member _.Bind2(m1: Result<'T1, 'E>, m2: Result<'T2, 'E>, f: 'T1 * 'T2 -> Result<'U, 'E>) = + match m1, m2 with + | Ok x1, Ok x2 -> f (x1, x2) + | Error e, _ -> Error e + | _, Error e -> Error e + +let result = ResultBuilder() + +let getValue1() = Ok 42 +let getValue2() = Ok "success" + +let test() = + result { + let! x: int = getValue1() + and! y: string = getValue2() + return (x, y) + } + +match test() with +| Ok (42, "success") -> printfn "Test passed" +| _ -> failwith "Test failed" + """ + |> withLangVersionPreview + |> asExe + |> compileAndRun + |> shouldSucceed \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/ComputationExpression/MultipleSynExprAndBangHaveRangeThatStartsAtAndAndEndsAfterExpression.fs.bsl b/tests/service/data/SyntaxTree/ComputationExpression/MultipleSynExprAndBangHaveRangeThatStartsAtAndAndEndsAfterExpression.fs.bsl index 77bbe3164c6..a9f281321fa 100644 --- a/tests/service/data/SyntaxTree/ComputationExpression/MultipleSynExprAndBangHaveRangeThatStartsAtAndAndEndsAfterExpression.fs.bsl +++ b/tests/service/data/SyntaxTree/ComputationExpression/MultipleSynExprAndBangHaveRangeThatStartsAtAndAndEndsAfterExpression.fs.bsl @@ -19,7 +19,7 @@ ImplFile (NonAtomic, false, Ident getBar, Const (Unit, (3,22--3,24)), (3,15--3,24)), [SynExprAndBang - (Yes (4,4--4,27), false, true, + (Yes (4,4--4,24), false, true, Named (SynIdent (foo, None), false, None, (4,9--4,12)), App @@ -29,7 +29,7 @@ ImplFile EqualsRange = (4,13--4,14) InKeyword = Some (4,25--4,27) }); SynExprAndBang - (Yes (5,4--6,10), false, true, + (Yes (5,4--5,24), false, true, Named (SynIdent (meh, None), false, None, (5,9--5,12)), App diff --git a/tests/service/data/SyntaxTree/ComputationExpression/SynExprAndBangRangeStartsAtAndAndEndsAfterExpression.fs.bsl b/tests/service/data/SyntaxTree/ComputationExpression/SynExprAndBangRangeStartsAtAndAndEndsAfterExpression.fs.bsl index 610ab87132f..031ace760eb 100644 --- a/tests/service/data/SyntaxTree/ComputationExpression/SynExprAndBangRangeStartsAtAndAndEndsAfterExpression.fs.bsl +++ b/tests/service/data/SyntaxTree/ComputationExpression/SynExprAndBangRangeStartsAtAndAndEndsAfterExpression.fs.bsl @@ -19,7 +19,7 @@ ImplFile (NonAtomic, false, Ident getBar, Const (Unit, (3,22--3,24)), (3,15--3,24)), [SynExprAndBang - (Yes (5,4--7,10), false, true, + (Yes (5,4--5,24), false, true, Named (SynIdent (foo, None), false, None, (5,9--5,12)), App diff --git a/tests/service/data/SyntaxTree/Expression/Return 07.fs.bsl b/tests/service/data/SyntaxTree/Expression/Return 07.fs.bsl index 0bf151be5bb..d45aa5689ce 100644 --- a/tests/service/data/SyntaxTree/Expression/Return 07.fs.bsl +++ b/tests/service/data/SyntaxTree/Expression/Return 07.fs.bsl @@ -35,3 +35,4 @@ ImplFile CodeComments = [] }, set [])) (6,4)-(6,5) parse error Unexpected symbol '}' in expression +(5,29)-(5,29) parse error Expecting type diff --git a/tests/service/data/SyntaxTree/Expression/ReturnBang 03.fs.bsl b/tests/service/data/SyntaxTree/Expression/ReturnBang 03.fs.bsl index e23e8ccde38..1747359d47d 100644 --- a/tests/service/data/SyntaxTree/Expression/ReturnBang 03.fs.bsl +++ b/tests/service/data/SyntaxTree/Expression/ReturnBang 03.fs.bsl @@ -36,3 +36,4 @@ ImplFile CodeComments = [] }, set [])) (6,4)-(6,5) parse error Unexpected symbol '}' in expression +(5,30)-(5,30) parse error Expecting type diff --git a/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseBangContainsTheRangeOfTheEqualsSign.fs.bsl b/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseBangContainsTheRangeOfTheEqualsSign.fs.bsl index c5a6b577bc1..19bef59c8a3 100644 --- a/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseBangContainsTheRangeOfTheEqualsSign.fs.bsl +++ b/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseBangContainsTheRangeOfTheEqualsSign.fs.bsl @@ -16,7 +16,7 @@ ImplFile Named (SynIdent (x, None), false, None, (3,9--3,10)), Ident y, [SynExprAndBang - (Yes (4,4--5,10), false, true, + (Yes (4,4--4,28), false, true, Named (SynIdent (z, None), false, None, (4,9--4,10)), App (NonAtomic, false, Ident someFunction, diff --git a/tests/service/data/SyntaxTree/Expression/Yield 05.fs.bsl b/tests/service/data/SyntaxTree/Expression/Yield 05.fs.bsl index 1deada75f94..b3b6e05aabf 100644 --- a/tests/service/data/SyntaxTree/Expression/Yield 05.fs.bsl +++ b/tests/service/data/SyntaxTree/Expression/Yield 05.fs.bsl @@ -29,3 +29,4 @@ ImplFile CodeComments = [] }, set [])) (5,0)-(5,1) parse error Unexpected symbol '}' in expression +(4,23)-(4,23) parse error Expecting type diff --git a/tests/service/data/SyntaxTree/Expression/Yield 06.fs.bsl b/tests/service/data/SyntaxTree/Expression/Yield 06.fs.bsl index ced49e682d6..43a6887f39e 100644 --- a/tests/service/data/SyntaxTree/Expression/Yield 06.fs.bsl +++ b/tests/service/data/SyntaxTree/Expression/Yield 06.fs.bsl @@ -29,3 +29,4 @@ ImplFile CodeComments = [] }, set [])) (5,0)-(5,1) parse error Unexpected symbol '}' in expression +(4,23)-(4,23) parse error Expecting type diff --git a/tests/service/data/SyntaxTree/Expression/YieldBang 05.fs.bsl b/tests/service/data/SyntaxTree/Expression/YieldBang 05.fs.bsl index 595f455632d..317ca5dc112 100644 --- a/tests/service/data/SyntaxTree/Expression/YieldBang 05.fs.bsl +++ b/tests/service/data/SyntaxTree/Expression/YieldBang 05.fs.bsl @@ -29,3 +29,4 @@ ImplFile CodeComments = [] }, set [])) (5,0)-(5,1) parse error Unexpected symbol '}' in expression +(4,24)-(4,24) parse error Expecting type diff --git a/tests/service/data/SyntaxTree/Expression/YieldBang 06.fs.bsl b/tests/service/data/SyntaxTree/Expression/YieldBang 06.fs.bsl index de83602e2d5..dbbbe74f59a 100644 --- a/tests/service/data/SyntaxTree/Expression/YieldBang 06.fs.bsl +++ b/tests/service/data/SyntaxTree/Expression/YieldBang 06.fs.bsl @@ -22,3 +22,4 @@ ImplFile CodeComments = [] }, set [])) (5,0)-(5,0) parse error Incomplete structured construct at or before this point in expression +(3,20)-(3,20) parse error Expecting type diff --git a/tests/service/data/SyntaxTree/Member/Member 13.fs.bsl b/tests/service/data/SyntaxTree/Member/Member 13.fs.bsl index 929250cabbe..bb146d2a2ba 100644 --- a/tests/service/data/SyntaxTree/Member/Member 13.fs.bsl +++ b/tests/service/data/SyntaxTree/Member/Member 13.fs.bsl @@ -75,4 +75,5 @@ ImplFile CodeComments = [] }, set [])) (6,0)-(6,4) parse error Incomplete structured construct at or before this point in member definition +(4,20)-(4,20) parse error Expecting type (6,0)-(6,4) parse error Expecting member body diff --git a/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 01.fs.bsl b/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 01.fs.bsl index c3b01295134..47a126930af 100644 --- a/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 01.fs.bsl +++ b/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 01.fs.bsl @@ -29,5 +29,6 @@ ImplFile CodeComments = [] }, set [])) (5,0)-(5,1) parse error Incomplete structured construct at or before this point in binding +(3,6)-(3,6) parse error Expecting type (6,0)-(6,0) parse error Unexpected end of input in value, function or member definition (3,0)-(3,3) parse error Incomplete value or function definition. If this is in an expression, the body of the expression must be indented to the same column as the 'let' keyword. diff --git a/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 02.fs.bsl b/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 02.fs.bsl index d90f5c5d863..ead5a85c1af 100644 --- a/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 02.fs.bsl +++ b/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 02.fs.bsl @@ -30,3 +30,4 @@ ImplFile CodeComments = [] }, set [])) (3,7)-(3,8) parse error Unexpected symbol '=' in binding +(3,6)-(3,6) parse error Expecting type diff --git a/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 05.fs.bsl b/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 05.fs.bsl index 86cac0dc468..12785905c05 100644 --- a/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 05.fs.bsl +++ b/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 05.fs.bsl @@ -40,6 +40,7 @@ ImplFile CodeComments = [] }, set [])) (6,4)-(6,5) parse error Incomplete structured construct at or before this point in binding +(4,10)-(4,10) parse error Expecting type (7,0)-(7,0) parse error Unexpected end of input in value, function or member definition (4,4)-(4,7) parse error Incomplete value or function definition. If this is in an expression, the body of the expression must be indented to the same column as the 'let' keyword. (4,4)-(4,7) parse error 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. diff --git a/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 06.fs.bsl b/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 06.fs.bsl index 618cbcfcee8..a6e663f076a 100644 --- a/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 06.fs.bsl +++ b/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 06.fs.bsl @@ -36,3 +36,4 @@ ImplFile CodeComments = [] }, set [])) (4,11)-(4,12) parse error Unexpected symbol '=' in binding +(4,10)-(4,10) parse error Expecting type diff --git a/tests/service/data/SyntaxTree/SynType/Tuple 15.fs b/tests/service/data/SyntaxTree/SynType/Tuple 15.fs new file mode 100644 index 00000000000..eb13b88a326 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Tuple 15.fs @@ -0,0 +1,3 @@ +module Module + +let x: int, y: int = 0, 4 diff --git a/tests/service/data/SyntaxTree/SynType/Tuple 15.fs.bsl b/tests/service/data/SyntaxTree/SynType/Tuple 15.fs.bsl new file mode 100644 index 00000000000..44d8624017b --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Tuple 15.fs.bsl @@ -0,0 +1,31 @@ +ImplFile + (ParsedImplFileInput + ("/root/SynType/Tuple 15.fs", false, QualifiedNameOfFile Module, [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Let + (false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, SynValInfo ([], SynArgInfo ([], false, None)), None), + Named (SynIdent (x, None), false, None, (3,4--3,5)), + Some + (SynBindingReturnInfo + (LongIdent (SynLongIdent ([int], [], [None])), + (3,7--3,10), [], { ColonRange = Some (3,5--3,6) })), + Typed + (ArbitraryAfterError ("localBinding2", (3,10--3,10)), + LongIdent (SynLongIdent ([int], [], [None])), (3,10--3,10)), + (3,4--3,5), Yes (3,0--3,10), { LeadingKeyword = Let (3,0--3,3) + InlineKeyword = None + EqualsRange = None })], + (3,0--3,10))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--3,10), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) + +(3,10)-(3,11) parse error Unexpected symbol ',' in binding. Expected '=' or other token. diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang 07.fs b/tests/service/data/SyntaxTree/SynType/Typed LetBang 07.fs new file mode 100644 index 00000000000..5cbe57f4dbe --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang 07.fs @@ -0,0 +1,7 @@ +module Module +async { + let! ({ Name = name }: Person) = asyncPerson() + + return name + +} \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang 07.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang 07.fs.bsl new file mode 100644 index 00000000000..9493eb7270f --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang 07.fs.bsl @@ -0,0 +1,35 @@ +ImplFile + (ParsedImplFileInput + ("/root/SynType/Typed LetBang 07.fs", false, QualifiedNameOfFile Module, [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + LetOrUseBang + (Yes (3,4--3,50), false, true, + Paren + (Typed + (Record + ([(([], Name), Some (3,17--3,18), + Named + (SynIdent (name, None), false, None, + (3,19--3,23)))], (3,10--3,25)), + LongIdent (SynLongIdent ([Person], [], [None])), + (3,10--3,33)), (3,9--3,34)), + App + (Atomic, false, Ident asyncPerson, + Const (Unit, (3,48--3,50)), (3,37--3,50)), [], + YieldOrReturn + ((false, true), Ident name, (5,4--5,15), + { YieldOrReturnKeyword = (5,4--5,10) }), (3,4--5,15), + { LetOrUseBangKeyword = (3,4--3,8) + EqualsRange = Some (3,35--3,36) }), (2,6--7,1)), + (2,0--7,1)), (2,0--7,1))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--7,1), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang 08.fs b/tests/service/data/SyntaxTree/SynType/Typed LetBang 08.fs new file mode 100644 index 00000000000..941456b8732 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang 08.fs @@ -0,0 +1,6 @@ +module Module +async { + let! { Name = name }: Person = asyncPerson() + return name + +} \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang 08.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang 08.fs.bsl new file mode 100644 index 00000000000..62bf5bc63db --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang 08.fs.bsl @@ -0,0 +1,34 @@ +ImplFile + (ParsedImplFileInput + ("/root/SynType/Typed LetBang 08.fs", false, QualifiedNameOfFile Module, [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + LetOrUseBang + (Yes (3,4--3,48), false, true, + Typed + (Record + ([(([], Name), Some (3,16--3,17), + Named + (SynIdent (name, None), false, None, + (3,18--3,22)))], (3,9--3,24)), + LongIdent (SynLongIdent ([Person], [], [None])), + (3,9--3,32)), + App + (Atomic, false, Ident asyncPerson, + Const (Unit, (3,46--3,48)), (3,35--3,48)), [], + YieldOrReturn + ((false, true), Ident name, (4,4--4,15), + { YieldOrReturnKeyword = (4,4--4,10) }), (3,4--4,15), + { LetOrUseBangKeyword = (3,4--3,8) + EqualsRange = Some (3,33--3,34) }), (2,6--6,1)), + (2,0--6,1)), (2,0--6,1))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--6,1), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang 09.fs b/tests/service/data/SyntaxTree/SynType/Typed LetBang 09.fs new file mode 100644 index 00000000000..ffae5310fb2 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang 09.fs @@ -0,0 +1,5 @@ +module Module +async { + let! (Union value) = asyncOption() + return value +} diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang 09.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang 09.fs.bsl new file mode 100644 index 00000000000..0516dc630a8 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang 09.fs.bsl @@ -0,0 +1,34 @@ +ImplFile + (ParsedImplFileInput + ("/root/SynType/Typed LetBang 09.fs", false, QualifiedNameOfFile Module, [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + LetOrUseBang + (Yes (3,4--3,38), false, true, + Paren + (LongIdent + (SynLongIdent ([Union], [], [None]), None, None, + Pats + [Named + (SynIdent (value, None), false, None, + (3,16--3,21))], None, (3,10--3,21)), + (3,9--3,22)), + App + (Atomic, false, Ident asyncOption, + Const (Unit, (3,36--3,38)), (3,25--3,38)), [], + YieldOrReturn + ((false, true), Ident value, (4,4--4,16), + { YieldOrReturnKeyword = (4,4--4,10) }), (3,4--4,16), + { LetOrUseBangKeyword = (3,4--3,8) + EqualsRange = Some (3,23--3,24) }), (2,6--5,1)), + (2,0--5,1)), (2,0--5,1))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--5,1), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang 10.fs b/tests/service/data/SyntaxTree/SynType/Typed LetBang 10.fs new file mode 100644 index 00000000000..f96163293b7 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang 10.fs @@ -0,0 +1,5 @@ +module Module +async { + let! Union value = asyncOption() + return value +} diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang 10.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang 10.fs.bsl new file mode 100644 index 00000000000..f3758aff371 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang 10.fs.bsl @@ -0,0 +1,32 @@ +ImplFile + (ParsedImplFileInput + ("/root/SynType/Typed LetBang 10.fs", false, QualifiedNameOfFile Module, [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + LetOrUseBang + (Yes (3,4--3,36), false, true, + LongIdent + (SynLongIdent ([Union], [], [None]), None, None, + Pats + [Named + (SynIdent (value, None), false, None, + (3,15--3,20))], None, (3,9--3,20)), + App + (Atomic, false, Ident asyncOption, + Const (Unit, (3,34--3,36)), (3,23--3,36)), [], + YieldOrReturn + ((false, true), Ident value, (4,4--4,16), + { YieldOrReturnKeyword = (4,4--4,10) }), (3,4--4,16), + { LetOrUseBangKeyword = (3,4--3,8) + EqualsRange = Some (3,21--3,22) }), (2,6--5,1)), + (2,0--5,1)), (2,0--5,1))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--5,1), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang 11.fs b/tests/service/data/SyntaxTree/SynType/Typed LetBang 11.fs new file mode 100644 index 00000000000..48e18bbe04f --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang 11.fs @@ -0,0 +1,5 @@ +module Module +async { + let! (Union value): int option = asyncOption() + return value +} diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang 11.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang 11.fs.bsl new file mode 100644 index 00000000000..096e0effc20 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang 11.fs.bsl @@ -0,0 +1,40 @@ +ImplFile + (ParsedImplFileInput + ("/root/SynType/Typed LetBang 11.fs", false, QualifiedNameOfFile Module, [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + LetOrUseBang + (Yes (3,4--3,50), false, true, + Typed + (Paren + (LongIdent + (SynLongIdent ([Union], [], [None]), None, None, + Pats + [Named + (SynIdent (value, None), false, None, + (3,16--3,21))], None, (3,10--3,21)), + (3,9--3,22)), + App + (LongIdent (SynLongIdent ([option], [], [None])), + None, + [LongIdent (SynLongIdent ([int], [], [None]))], [], + None, true, (3,24--3,34)), (3,9--3,34)), + App + (Atomic, false, Ident asyncOption, + Const (Unit, (3,48--3,50)), (3,37--3,50)), [], + YieldOrReturn + ((false, true), Ident value, (4,4--4,16), + { YieldOrReturnKeyword = (4,4--4,10) }), (3,4--4,16), + { LetOrUseBangKeyword = (3,4--3,8) + EqualsRange = Some (3,35--3,36) }), (2,6--5,1)), + (2,0--5,1)), (2,0--5,1))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--5,1), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang 12.fs b/tests/service/data/SyntaxTree/SynType/Typed LetBang 12.fs new file mode 100644 index 00000000000..4fb0e0b1a5e --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang 12.fs @@ -0,0 +1,5 @@ +module Module +async { + let! Union value: int option = asyncOption() + return value +} diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang 12.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang 12.fs.bsl new file mode 100644 index 00000000000..b274a8880f3 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang 12.fs.bsl @@ -0,0 +1,38 @@ +ImplFile + (ParsedImplFileInput + ("/root/SynType/Typed LetBang 12.fs", false, QualifiedNameOfFile Module, [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + LetOrUseBang + (Yes (3,4--3,48), false, true, + Typed + (LongIdent + (SynLongIdent ([Union], [], [None]), None, None, + Pats + [Named + (SynIdent (value, None), false, None, + (3,15--3,20))], None, (3,9--3,20)), + App + (LongIdent (SynLongIdent ([option], [], [None])), + None, + [LongIdent (SynLongIdent ([int], [], [None]))], [], + None, true, (3,22--3,32)), (3,9--3,32)), + App + (Atomic, false, Ident asyncOption, + Const (Unit, (3,46--3,48)), (3,35--3,48)), [], + YieldOrReturn + ((false, true), Ident value, (4,4--4,16), + { YieldOrReturnKeyword = (4,4--4,10) }), (3,4--4,16), + { LetOrUseBangKeyword = (3,4--3,8) + EqualsRange = Some (3,33--3,34) }), (2,6--5,1)), + (2,0--5,1)), (2,0--5,1))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--5,1), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang 13.fs b/tests/service/data/SyntaxTree/SynType/Typed LetBang 13.fs new file mode 100644 index 00000000000..19c127c107f --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang 13.fs @@ -0,0 +1,5 @@ +module Module +async { + let! x: int, y: int = asyncInt() + return () +} diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang 13.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang 13.fs.bsl new file mode 100644 index 00000000000..54d1f846530 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang 13.fs.bsl @@ -0,0 +1,21 @@ +ImplFile + (ParsedImplFileInput + ("/root/SynType/Typed LetBang 13.fs", false, QualifiedNameOfFile Module, [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (Tuple + (false, + [App + (NonAtomic, false, Ident async, + Record (None, None, [], (2,6--2,7)), (2,0--2,7)); Ident y], + [(3,15--3,16)], (2,0--3,18)), (2,0--3,18))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--3,18), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) + +(3,15)-(3,16) parse error Unexpected symbol ',' in expression. Expected '=' or other token. +(2,6)-(2,7) parse error Unmatched '{' +(4,4)-(4,10) parse error Incomplete structured construct at or before this point in implementation file diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang 14.fs b/tests/service/data/SyntaxTree/SynType/Typed LetBang 14.fs new file mode 100644 index 00000000000..098e12cd639 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang 14.fs @@ -0,0 +1,7 @@ +module Module + +async { + let! (x as y): = asyncInt() + and! (a as b): string = asyncString() + return x + b +} \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang 14.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang 14.fs.bsl new file mode 100644 index 00000000000..c4ed5ee643f --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang 14.fs.bsl @@ -0,0 +1,68 @@ +ImplFile + (ParsedImplFileInput + ("/root/SynType/Typed LetBang 14.fs", false, QualifiedNameOfFile Module, [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + LetOrUseBang + (Yes (4,4--4,31), false, true, + Typed + (Paren + (As + (Named + (SynIdent (x, None), false, None, (4,10--4,11)), + Named + (SynIdent (y, None), false, None, (4,15--4,16)), + (4,10--4,16)), (4,9--4,17)), + FromParseError (4,18--4,18), (4,9--4,18)), + App + (Atomic, false, Ident asyncInt, + Const (Unit, (4,29--4,31)), (4,21--4,31)), + [SynExprAndBang + (Yes (5,4--5,41), false, true, + Typed + (Paren + (As + (Named + (SynIdent (a, None), false, None, + (5,10--5,11)), + Named + (SynIdent (b, None), false, None, + (5,15--5,16)), (5,10--5,16)), (5,9--5,17)), + LongIdent (SynLongIdent ([string], [], [None])), + (5,9--5,25)), + App + (Atomic, false, Ident asyncString, + Const (Unit, (5,39--5,41)), (5,28--5,41)), + (5,4--5,41), { AndBangKeyword = (5,4--5,8) + EqualsRange = (5,26--5,27) + InKeyword = None })], + YieldOrReturn + ((false, true), + App + (NonAtomic, false, + App + (NonAtomic, true, + LongIdent + (false, + SynLongIdent + ([op_Addition], [], + [Some (OriginalNotation "+")]), None, + (6,13--6,14)), Ident x, (6,11--6,14)), + Ident b, (6,11--6,16)), (6,4--6,16), + { YieldOrReturnKeyword = (6,4--6,10) }), (4,4--6,16), + { LetOrUseBangKeyword = (4,4--4,8) + EqualsRange = Some (4,19--4,20) }), (3,6--7,1)), + (3,0--7,1)), (3,0--7,1))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--7,1), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) + +(4,19)-(4,20) parse error Unexpected symbol '=' in expression +(4,18)-(4,18) parse error Expecting type diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang 15.fs b/tests/service/data/SyntaxTree/SynType/Typed LetBang 15.fs new file mode 100644 index 00000000000..141c53d6724 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang 15.fs @@ -0,0 +1,7 @@ +module Module + +async { + let! (x as y): + and! (a as b): string = asyncString() + return x + b +} \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang 15.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang 15.fs.bsl new file mode 100644 index 00000000000..1a461ef4b3e --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang 15.fs.bsl @@ -0,0 +1,49 @@ +ImplFile + (ParsedImplFileInput + ("/root/SynType/Typed LetBang 15.fs", false, QualifiedNameOfFile Module, [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + LetOrUseBang + (Yes (4,4--5,41), false, true, + Typed + (Paren + (As + (Named + (SynIdent (x, None), false, None, (4,10--4,11)), + Named + (SynIdent (y, None), false, None, (4,15--4,16)), + (4,10--4,16)), (4,9--4,17)), + FromParseError (4,18--4,18), (4,9--4,18)), + App + (Atomic, false, Ident asyncString, + Const (Unit, (5,39--5,41)), (5,28--5,41)), [], + YieldOrReturn + ((false, true), + App + (NonAtomic, false, + App + (NonAtomic, true, + LongIdent + (false, + SynLongIdent + ([op_Addition], [], + [Some (OriginalNotation "+")]), None, + (6,13--6,14)), Ident x, (6,11--6,14)), + Ident b, (6,11--6,16)), (6,4--6,16), + { YieldOrReturnKeyword = (6,4--6,10) }), (4,4--6,16), + { LetOrUseBangKeyword = (4,4--4,8) + EqualsRange = Some (5,26--5,27) }), (3,6--7,1)), + (3,0--7,1)), (3,0--7,1))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--7,1), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) + +(5,4)-(5,8) parse error Incomplete structured construct at or before this point in expression +(4,18)-(4,18) parse error Expecting type diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang 16.fs b/tests/service/data/SyntaxTree/SynType/Typed LetBang 16.fs new file mode 100644 index 00000000000..39041e9b461 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang 16.fs @@ -0,0 +1,7 @@ +module Module + +async { + let! (x as y): int = asyncInt() + and! (a as b): + return x + b +} \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang 16.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang 16.fs.bsl new file mode 100644 index 00000000000..5178a6c2714 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang 16.fs.bsl @@ -0,0 +1,13 @@ +ImplFile + (ParsedImplFileInput + ("/root/SynType/Typed LetBang 16.fs", false, + QualifiedNameOfFile Typed LetBang 16, [], + [SynModuleOrNamespace + ([Typed LetBang 16], false, AnonModule, [], PreXmlDocEmpty, [], None, + (7,1--7,1), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) + +(6,4)-(6,10) parse error Incomplete structured construct at or before this point in expression +(5,18)-(5,18) parse error Expecting type diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang 17.fs b/tests/service/data/SyntaxTree/SynType/Typed LetBang 17.fs new file mode 100644 index 00000000000..3365fee1357 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang 17.fs @@ -0,0 +1,5 @@ +module Module + +let (Even as x: int) = 1 + +let! (Even as x: int) = async { return 2 } \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang 17.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang 17.fs.bsl new file mode 100644 index 00000000000..6f78c27dca1 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang 17.fs.bsl @@ -0,0 +1,57 @@ +ImplFile + (ParsedImplFileInput + ("/root/SynType/Typed LetBang 17.fs", false, QualifiedNameOfFile Module, [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Let + (false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, SynValInfo ([], SynArgInfo ([], false, None)), None), + Paren + (Typed + (As + (LongIdent + (SynLongIdent ([Even], [], [None]), None, None, + Pats [], None, (3,5--3,9)), + Named (SynIdent (x, None), false, None, (3,13--3,14)), + (3,5--3,14)), + LongIdent (SynLongIdent ([int], [], [None])), + (3,5--3,19)), (3,4--3,20)), None, + Const (Int32 1, (3,23--3,24)), (3,4--3,20), Yes (3,0--3,24), + { LeadingKeyword = Let (3,0--3,3) + InlineKeyword = None + EqualsRange = Some (3,21--3,22) })], (3,0--3,24)); + Expr + (LetOrUseBang + (Yes (5,0--5,42), false, true, + Paren + (Typed + (As + (LongIdent + (SynLongIdent ([Even], [], [None]), None, None, + Pats [], None, (5,6--5,10)), + Named (SynIdent (x, None), false, None, (5,14--5,15)), + (5,6--5,15)), + LongIdent (SynLongIdent ([int], [], [None])), (5,6--5,20)), + (5,5--5,21)), + App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + YieldOrReturn + ((false, true), Const (Int32 2, (5,39--5,40)), + (5,32--5,40), { YieldOrReturnKeyword = (5,32--5,38) }), + (5,30--5,42)), (5,24--5,42)), [], + ImplicitZero (5,42--5,42), (5,0--5,42), + { LetOrUseBangKeyword = (5,0--5,4) + EqualsRange = Some (5,22--5,23) }), (5,0--5,42))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--5,42), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) + +(5,0)-(5,42) parse error Incomplete structured construct at or before this point in expression diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang 18.fs b/tests/service/data/SyntaxTree/SynType/Typed LetBang 18.fs new file mode 100644 index 00000000000..05a94e21d04 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang 18.fs @@ -0,0 +1,5 @@ +module Module + +let Even as x: int = 1 + +let! Even as x: int = async { return 2 } \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang 18.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang 18.fs.bsl new file mode 100644 index 00000000000..8579d42db13 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang 18.fs.bsl @@ -0,0 +1,58 @@ +ImplFile + (ParsedImplFileInput + ("/root/SynType/Typed LetBang 18.fs", false, QualifiedNameOfFile Module, [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Let + (false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, SynValInfo ([], SynArgInfo ([], false, None)), None), + As + (LongIdent + (SynLongIdent ([Even], [], [None]), None, None, Pats [], + None, (3,4--3,8)), + Named (SynIdent (x, None), false, None, (3,12--3,13)), + (3,4--3,13)), + Some + (SynBindingReturnInfo + (LongIdent (SynLongIdent ([int], [], [None])), + (3,15--3,18), [], { ColonRange = Some (3,13--3,14) })), + Typed + (Const (Int32 1, (3,21--3,22)), + LongIdent (SynLongIdent ([int], [], [None])), (3,21--3,22)), + (3,4--3,13), Yes (3,0--3,22), + { LeadingKeyword = Let (3,0--3,3) + InlineKeyword = None + EqualsRange = Some (3,19--3,20) })], (3,0--3,22)); + Expr + (LetOrUseBang + (Yes (5,0--5,40), false, true, + Typed + (As + (LongIdent + (SynLongIdent ([Even], [], [None]), None, None, Pats [], + None, (5,5--5,9)), + Named (SynIdent (x, None), false, None, (5,13--5,14)), + (5,5--5,14)), + LongIdent (SynLongIdent ([int], [], [None])), (5,5--5,19)), + App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + YieldOrReturn + ((false, true), Const (Int32 2, (5,37--5,38)), + (5,30--5,38), { YieldOrReturnKeyword = (5,30--5,36) }), + (5,28--5,40)), (5,22--5,40)), [], + ImplicitZero (5,40--5,40), (5,0--5,40), + { LetOrUseBangKeyword = (5,0--5,4) + EqualsRange = Some (5,20--5,21) }), (5,0--5,40))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--5,40), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) + +(5,0)-(5,40) parse error Incomplete structured construct at or before this point in expression diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang 19.fs b/tests/service/data/SyntaxTree/SynType/Typed LetBang 19.fs new file mode 100644 index 00000000000..57c7276c7a4 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang 19.fs @@ -0,0 +1,7 @@ +module Module + +async { + let (Even as x: int) = 1 + let! (Even as x: int) = async { return 2 } + return x +} \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang 19.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang 19.fs.bsl new file mode 100644 index 00000000000..4ccac506d64 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang 19.fs.bsl @@ -0,0 +1,69 @@ +ImplFile + (ParsedImplFileInput + ("/root/SynType/Typed LetBang 19.fs", false, QualifiedNameOfFile Module, [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + LetOrUse + (false, false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((4,4), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, + SynValInfo ([], SynArgInfo ([], false, None)), + None), + Paren + (Typed + (As + (LongIdent + (SynLongIdent ([Even], [], [None]), None, + None, Pats [], None, (4,9--4,13)), + Named + (SynIdent (x, None), false, None, + (4,17--4,18)), (4,9--4,18)), + LongIdent (SynLongIdent ([int], [], [None])), + (4,9--4,23)), (4,8--4,24)), None, + Const (Int32 1, (4,27--4,28)), (4,8--4,24), + Yes (4,4--4,28), { LeadingKeyword = Let (4,4--4,7) + InlineKeyword = None + EqualsRange = Some (4,25--4,26) })], + LetOrUseBang + (Yes (5,4--5,46), false, true, + Paren + (Typed + (As + (LongIdent + (SynLongIdent ([Even], [], [None]), None, + None, Pats [], None, (5,10--5,14)), + Named + (SynIdent (x, None), false, None, + (5,18--5,19)), (5,10--5,19)), + LongIdent (SynLongIdent ([int], [], [None])), + (5,10--5,24)), (5,9--5,25)), + App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + YieldOrReturn + ((false, true), Const (Int32 2, (5,43--5,44)), + (5,36--5,44), + { YieldOrReturnKeyword = (5,36--5,42) }), + (5,34--5,46)), (5,28--5,46)), [], + YieldOrReturn + ((false, true), Ident x, (6,4--6,12), + { YieldOrReturnKeyword = (6,4--6,10) }), + (5,4--6,12), { LetOrUseBangKeyword = (5,4--5,8) + EqualsRange = Some (5,26--5,27) }), + (4,4--6,12), { LetOrUseKeyword = (4,4--4,7) + InKeyword = None }), (3,6--7,1)), + (3,0--7,1)), (3,0--7,1))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--7,1), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang 20.fs b/tests/service/data/SyntaxTree/SynType/Typed LetBang 20.fs new file mode 100644 index 00000000000..8f1eaac2989 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang 20.fs @@ -0,0 +1,7 @@ +module Module + +async { + let Even as x: int = 1 + let! Even as x: int = async { return 2 } + return x +} \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang 20.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang 20.fs.bsl new file mode 100644 index 00000000000..e14813fde0c --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang 20.fs.bsl @@ -0,0 +1,72 @@ +ImplFile + (ParsedImplFileInput + ("/root/SynType/Typed LetBang 20.fs", false, QualifiedNameOfFile Module, [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + LetOrUse + (false, false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((4,4), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, + SynValInfo ([], SynArgInfo ([], false, None)), + None), + As + (LongIdent + (SynLongIdent ([Even], [], [None]), None, None, + Pats [], None, (4,8--4,12)), + Named + (SynIdent (x, None), false, None, (4,16--4,17)), + (4,8--4,17)), + Some + (SynBindingReturnInfo + (LongIdent (SynLongIdent ([int], [], [None])), + (4,19--4,22), [], + { ColonRange = Some (4,17--4,18) })), + Typed + (Const (Int32 1, (4,25--4,26)), + LongIdent (SynLongIdent ([int], [], [None])), + (4,25--4,26)), (4,8--4,17), Yes (4,4--4,26), + { LeadingKeyword = Let (4,4--4,7) + InlineKeyword = None + EqualsRange = Some (4,23--4,24) })], + LetOrUseBang + (Yes (5,4--5,44), false, true, + Typed + (As + (LongIdent + (SynLongIdent ([Even], [], [None]), None, None, + Pats [], None, (5,9--5,13)), + Named + (SynIdent (x, None), false, None, (5,17--5,18)), + (5,9--5,18)), + LongIdent (SynLongIdent ([int], [], [None])), + (5,9--5,23)), + App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + YieldOrReturn + ((false, true), Const (Int32 2, (5,41--5,42)), + (5,34--5,42), + { YieldOrReturnKeyword = (5,34--5,40) }), + (5,32--5,44)), (5,26--5,44)), [], + YieldOrReturn + ((false, true), Ident x, (6,4--6,12), + { YieldOrReturnKeyword = (6,4--6,10) }), + (5,4--6,12), { LetOrUseBangKeyword = (5,4--5,8) + EqualsRange = Some (5,24--5,25) }), + (4,4--6,12), { LetOrUseKeyword = (4,4--4,7) + InKeyword = None }), (3,6--7,1)), + (3,0--7,1)), (3,0--7,1))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--7,1), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 01.fs b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 01.fs new file mode 100644 index 00000000000..5ec258108d5 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 01.fs @@ -0,0 +1,7 @@ +module Module + +async { + let! res: int = async { return 1 } + and! res2: int = async { return 2 } + return res +} diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 01.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 01.fs.bsl new file mode 100644 index 00000000000..0aa056d6da5 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 01.fs.bsl @@ -0,0 +1,56 @@ +ImplFile + (ParsedImplFileInput + ("/root/SynType/Typed LetBang AndBang 01.fs", false, + QualifiedNameOfFile Module, [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + LetOrUseBang + (Yes (4,4--4,38), false, true, + Typed + (Named (SynIdent (res, None), false, None, (4,9--4,12)), + LongIdent (SynLongIdent ([int], [], [None])), + (4,9--4,17)), + App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + YieldOrReturn + ((false, true), Const (Int32 1, (4,35--4,36)), + (4,28--4,36), + { YieldOrReturnKeyword = (4,28--4,34) }), + (4,26--4,38)), (4,20--4,38)), + [SynExprAndBang + (Yes (5,4--5,39), false, true, + Typed + (Named + (SynIdent (res2, None), false, None, (5,9--5,13)), + LongIdent (SynLongIdent ([int], [], [None])), + (5,9--5,18)), + App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + YieldOrReturn + ((false, true), Const (Int32 2, (5,36--5,37)), + (5,29--5,37), + { YieldOrReturnKeyword = (5,29--5,35) }), + (5,27--5,39)), (5,21--5,39)), (5,4--5,39), + { AndBangKeyword = (5,4--5,8) + EqualsRange = (5,19--5,20) + InKeyword = None })], + YieldOrReturn + ((false, true), Ident res, (6,4--6,14), + { YieldOrReturnKeyword = (6,4--6,10) }), (4,4--6,14), + { LetOrUseBangKeyword = (4,4--4,8) + EqualsRange = Some (4,18--4,19) }), (3,6--7,1)), + (3,0--7,1)), (3,0--7,1))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--7,1), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 02.fs b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 02.fs new file mode 100644 index 00000000000..9e1d620a319 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 02.fs @@ -0,0 +1,7 @@ +module Module + +async { + let! (res: int) = async { return 1 } + and! (res2: int) = async { return 2 } + return res +} \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 02.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 02.fs.bsl new file mode 100644 index 00000000000..0f5f06df777 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 02.fs.bsl @@ -0,0 +1,60 @@ +ImplFile + (ParsedImplFileInput + ("/root/SynType/Typed LetBang AndBang 02.fs", false, + QualifiedNameOfFile Module, [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + LetOrUseBang + (Yes (4,4--4,40), false, true, + Paren + (Typed + (Named + (SynIdent (res, None), false, None, (4,10--4,13)), + LongIdent (SynLongIdent ([int], [], [None])), + (4,10--4,18)), (4,9--4,19)), + App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + YieldOrReturn + ((false, true), Const (Int32 1, (4,37--4,38)), + (4,30--4,38), + { YieldOrReturnKeyword = (4,30--4,36) }), + (4,28--4,40)), (4,22--4,40)), + [SynExprAndBang + (Yes (5,4--5,41), false, true, + Paren + (Typed + (Named + (SynIdent (res2, None), false, None, + (5,10--5,14)), + LongIdent (SynLongIdent ([int], [], [None])), + (5,10--5,19)), (5,9--5,20)), + App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + YieldOrReturn + ((false, true), Const (Int32 2, (5,38--5,39)), + (5,31--5,39), + { YieldOrReturnKeyword = (5,31--5,37) }), + (5,29--5,41)), (5,23--5,41)), (5,4--5,41), + { AndBangKeyword = (5,4--5,8) + EqualsRange = (5,21--5,22) + InKeyword = None })], + YieldOrReturn + ((false, true), Ident res, (6,4--6,14), + { YieldOrReturnKeyword = (6,4--6,10) }), (4,4--6,14), + { LetOrUseBangKeyword = (4,4--4,8) + EqualsRange = Some (4,20--4,21) }), (3,6--7,1)), + (3,0--7,1)), (3,0--7,1))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--7,1), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 03.fs b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 03.fs new file mode 100644 index 00000000000..0e211e05966 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 03.fs @@ -0,0 +1,7 @@ +module Module + +async { + let! ({ Name = name; Age = age }: Person) = asyncPerson() + and! ({ Id = id }: User) = asyncUser() + return name +} \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 03.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 03.fs.bsl new file mode 100644 index 00000000000..9d127609634 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 03.fs.bsl @@ -0,0 +1,57 @@ +ImplFile + (ParsedImplFileInput + ("/root/SynType/Typed LetBang AndBang 03.fs", false, + QualifiedNameOfFile Module, [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + LetOrUseBang + (Yes (4,4--4,61), false, true, + Paren + (Typed + (Record + ([(([], Name), Some (4,17--4,18), + Named + (SynIdent (name, None), false, None, + (4,19--4,23))); + (([], Age), Some (4,29--4,30), + Named + (SynIdent (age, None), false, None, + (4,31--4,34)))], (4,10--4,36)), + LongIdent (SynLongIdent ([Person], [], [None])), + (4,10--4,44)), (4,9--4,45)), + App + (Atomic, false, Ident asyncPerson, + Const (Unit, (4,59--4,61)), (4,48--4,61)), + [SynExprAndBang + (Yes (5,4--5,42), false, true, + Paren + (Typed + (Record + ([(([], Id), Some (5,15--5,16), + Named + (SynIdent (id, None), false, None, + (5,17--5,19)))], (5,10--5,21)), + LongIdent (SynLongIdent ([User], [], [None])), + (5,10--5,27)), (5,9--5,28)), + App + (Atomic, false, Ident asyncUser, + Const (Unit, (5,40--5,42)), (5,31--5,42)), + (5,4--5,42), { AndBangKeyword = (5,4--5,8) + EqualsRange = (5,29--5,30) + InKeyword = None })], + YieldOrReturn + ((false, true), Ident name, (6,4--6,15), + { YieldOrReturnKeyword = (6,4--6,10) }), (4,4--6,15), + { LetOrUseBangKeyword = (4,4--4,8) + EqualsRange = Some (4,46--4,47) }), (3,6--7,1)), + (3,0--7,1)), (3,0--7,1))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--7,1), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 04.fs b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 04.fs new file mode 100644 index 00000000000..b7318405b81 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 04.fs @@ -0,0 +1,7 @@ +module Module + +async { + let! { Name = name; Age = age }: Person = asyncPerson() + and! { Id = id }: User = asyncUser() + return name +} \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 04.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 04.fs.bsl new file mode 100644 index 00000000000..2377382104e --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 04.fs.bsl @@ -0,0 +1,55 @@ +ImplFile + (ParsedImplFileInput + ("/root/SynType/Typed LetBang AndBang 04.fs", false, + QualifiedNameOfFile Module, [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + LetOrUseBang + (Yes (4,4--4,59), false, true, + Typed + (Record + ([(([], Name), Some (4,16--4,17), + Named + (SynIdent (name, None), false, None, + (4,18--4,22))); + (([], Age), Some (4,28--4,29), + Named + (SynIdent (age, None), false, None, + (4,30--4,33)))], (4,9--4,35)), + LongIdent (SynLongIdent ([Person], [], [None])), + (4,9--4,43)), + App + (Atomic, false, Ident asyncPerson, + Const (Unit, (4,57--4,59)), (4,46--4,59)), + [SynExprAndBang + (Yes (5,4--5,40), false, true, + Typed + (Record + ([(([], Id), Some (5,14--5,15), + Named + (SynIdent (id, None), false, None, + (5,16--5,18)))], (5,9--5,20)), + LongIdent (SynLongIdent ([User], [], [None])), + (5,9--5,26)), + App + (Atomic, false, Ident asyncUser, + Const (Unit, (5,38--5,40)), (5,29--5,40)), + (5,4--5,40), { AndBangKeyword = (5,4--5,8) + EqualsRange = (5,27--5,28) + InKeyword = None })], + YieldOrReturn + ((false, true), Ident name, (6,4--6,15), + { YieldOrReturnKeyword = (6,4--6,10) }), (4,4--6,15), + { LetOrUseBangKeyword = (4,4--4,8) + EqualsRange = Some (4,44--4,45) }), (3,6--7,1)), + (3,0--7,1)), (3,0--7,1))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--7,1), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 05.fs b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 05.fs new file mode 100644 index 00000000000..3d99e5c9447 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 05.fs @@ -0,0 +1,7 @@ +module Module + +async { + let! ({ Name = name; Age = age }: Person) = asyncPerson() + and! { Id = id }: User = asyncUser() + return name +} \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 05.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 05.fs.bsl new file mode 100644 index 00000000000..2309e7f9490 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 05.fs.bsl @@ -0,0 +1,56 @@ +ImplFile + (ParsedImplFileInput + ("/root/SynType/Typed LetBang AndBang 05.fs", false, + QualifiedNameOfFile Module, [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + LetOrUseBang + (Yes (4,4--4,61), false, true, + Paren + (Typed + (Record + ([(([], Name), Some (4,17--4,18), + Named + (SynIdent (name, None), false, None, + (4,19--4,23))); + (([], Age), Some (4,29--4,30), + Named + (SynIdent (age, None), false, None, + (4,31--4,34)))], (4,10--4,36)), + LongIdent (SynLongIdent ([Person], [], [None])), + (4,10--4,44)), (4,9--4,45)), + App + (Atomic, false, Ident asyncPerson, + Const (Unit, (4,59--4,61)), (4,48--4,61)), + [SynExprAndBang + (Yes (5,4--5,40), false, true, + Typed + (Record + ([(([], Id), Some (5,14--5,15), + Named + (SynIdent (id, None), false, None, + (5,16--5,18)))], (5,9--5,20)), + LongIdent (SynLongIdent ([User], [], [None])), + (5,9--5,26)), + App + (Atomic, false, Ident asyncUser, + Const (Unit, (5,38--5,40)), (5,29--5,40)), + (5,4--5,40), { AndBangKeyword = (5,4--5,8) + EqualsRange = (5,27--5,28) + InKeyword = None })], + YieldOrReturn + ((false, true), Ident name, (6,4--6,15), + { YieldOrReturnKeyword = (6,4--6,10) }), (4,4--6,15), + { LetOrUseBangKeyword = (4,4--4,8) + EqualsRange = Some (4,46--4,47) }), (3,6--7,1)), + (3,0--7,1)), (3,0--7,1))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--7,1), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 06.fs b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 06.fs new file mode 100644 index 00000000000..7fa5f22d509 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 06.fs @@ -0,0 +1,7 @@ +module Module + +async { + let! (Union value) = asyncOption() + and! (Union value2) = asyncOption() + return value + value2 +} \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 06.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 06.fs.bsl new file mode 100644 index 00000000000..e46cfc2ef7c --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 06.fs.bsl @@ -0,0 +1,62 @@ +ImplFile + (ParsedImplFileInput + ("/root/SynType/Typed LetBang AndBang 06.fs", false, + QualifiedNameOfFile Module, [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + LetOrUseBang + (Yes (4,4--4,38), false, true, + Paren + (LongIdent + (SynLongIdent ([Union], [], [None]), None, None, + Pats + [Named + (SynIdent (value, None), false, None, + (4,16--4,21))], None, (4,10--4,21)), + (4,9--4,22)), + App + (Atomic, false, Ident asyncOption, + Const (Unit, (4,36--4,38)), (4,25--4,38)), + [SynExprAndBang + (Yes (5,4--5,39), false, true, + Paren + (LongIdent + (SynLongIdent ([Union], [], [None]), None, None, + Pats + [Named + (SynIdent (value2, None), false, None, + (5,16--5,22))], None, (5,10--5,22)), + (5,9--5,23)), + App + (Atomic, false, Ident asyncOption, + Const (Unit, (5,37--5,39)), (5,26--5,39)), + (5,4--5,39), { AndBangKeyword = (5,4--5,8) + EqualsRange = (5,24--5,25) + InKeyword = None })], + YieldOrReturn + ((false, true), + App + (NonAtomic, false, + App + (NonAtomic, true, + LongIdent + (false, + SynLongIdent + ([op_Addition], [], + [Some (OriginalNotation "+")]), None, + (6,17--6,18)), Ident value, (6,11--6,18)), + Ident value2, (6,11--6,25)), (6,4--6,25), + { YieldOrReturnKeyword = (6,4--6,10) }), (4,4--6,25), + { LetOrUseBangKeyword = (4,4--4,8) + EqualsRange = Some (4,23--4,24) }), (3,6--7,1)), + (3,0--7,1)), (3,0--7,1))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--7,1), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 07.fs b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 07.fs new file mode 100644 index 00000000000..4a8cdf52b91 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 07.fs @@ -0,0 +1,7 @@ +module Module + +async { + let! Union value = asyncOption() + and! Union value2 = asyncOption() + return value + value2 +} \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 07.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 07.fs.bsl new file mode 100644 index 00000000000..6bc6a07abec --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 07.fs.bsl @@ -0,0 +1,58 @@ +ImplFile + (ParsedImplFileInput + ("/root/SynType/Typed LetBang AndBang 07.fs", false, + QualifiedNameOfFile Module, [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + LetOrUseBang + (Yes (4,4--4,36), false, true, + LongIdent + (SynLongIdent ([Union], [], [None]), None, None, + Pats + [Named + (SynIdent (value, None), false, None, + (4,15--4,20))], None, (4,9--4,20)), + App + (Atomic, false, Ident asyncOption, + Const (Unit, (4,34--4,36)), (4,23--4,36)), + [SynExprAndBang + (Yes (5,4--5,37), false, true, + LongIdent + (SynLongIdent ([Union], [], [None]), None, None, + Pats + [Named + (SynIdent (value2, None), false, None, + (5,15--5,21))], None, (5,9--5,21)), + App + (Atomic, false, Ident asyncOption, + Const (Unit, (5,35--5,37)), (5,24--5,37)), + (5,4--5,37), { AndBangKeyword = (5,4--5,8) + EqualsRange = (5,22--5,23) + InKeyword = None })], + YieldOrReturn + ((false, true), + App + (NonAtomic, false, + App + (NonAtomic, true, + LongIdent + (false, + SynLongIdent + ([op_Addition], [], + [Some (OriginalNotation "+")]), None, + (6,17--6,18)), Ident value, (6,11--6,18)), + Ident value2, (6,11--6,25)), (6,4--6,25), + { YieldOrReturnKeyword = (6,4--6,10) }), (4,4--6,25), + { LetOrUseBangKeyword = (4,4--4,8) + EqualsRange = Some (4,21--4,22) }), (3,6--7,1)), + (3,0--7,1)), (3,0--7,1))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--7,1), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 08.fs b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 08.fs new file mode 100644 index 00000000000..730c2d82016 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 08.fs @@ -0,0 +1,7 @@ +module Module + +async { + let! (Union value): int option = asyncOption() + and! (Union value2): int option = asyncOption() + return value + value2 +} \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 08.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 08.fs.bsl new file mode 100644 index 00000000000..7ca03b4f9e3 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 08.fs.bsl @@ -0,0 +1,75 @@ +ImplFile + (ParsedImplFileInput + ("/root/SynType/Typed LetBang AndBang 08.fs", false, + QualifiedNameOfFile Module, [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + LetOrUseBang + (Yes (4,4--4,50), false, true, + Typed + (Paren + (LongIdent + (SynLongIdent ([Union], [], [None]), None, None, + Pats + [Named + (SynIdent (value, None), false, None, + (4,16--4,21))], None, (4,10--4,21)), + (4,9--4,22)), + App + (LongIdent (SynLongIdent ([option], [], [None])), + None, + [LongIdent (SynLongIdent ([int], [], [None]))], [], + None, true, (4,24--4,34)), (4,9--4,34)), + App + (Atomic, false, Ident asyncOption, + Const (Unit, (4,48--4,50)), (4,37--4,50)), + [SynExprAndBang + (Yes (5,4--5,51), false, true, + Typed + (Paren + (LongIdent + (SynLongIdent ([Union], [], [None]), None, + None, + Pats + [Named + (SynIdent (value2, None), false, None, + (5,16--5,22))], None, (5,10--5,22)), + (5,9--5,23)), + App + (LongIdent (SynLongIdent ([option], [], [None])), + None, + [LongIdent (SynLongIdent ([int], [], [None]))], + [], None, true, (5,25--5,35)), (5,9--5,35)), + App + (Atomic, false, Ident asyncOption, + Const (Unit, (5,49--5,51)), (5,38--5,51)), + (5,4--5,51), { AndBangKeyword = (5,4--5,8) + EqualsRange = (5,36--5,37) + InKeyword = None })], + YieldOrReturn + ((false, true), + App + (NonAtomic, false, + App + (NonAtomic, true, + LongIdent + (false, + SynLongIdent + ([op_Addition], [], + [Some (OriginalNotation "+")]), None, + (6,17--6,18)), Ident value, (6,11--6,18)), + Ident value2, (6,11--6,25)), (6,4--6,25), + { YieldOrReturnKeyword = (6,4--6,10) }), (4,4--6,25), + { LetOrUseBangKeyword = (4,4--4,8) + EqualsRange = Some (4,35--4,36) }), (3,6--7,1)), + (3,0--7,1)), (3,0--7,1))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--7,1), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 09.fs b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 09.fs new file mode 100644 index 00000000000..f5221c58c89 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 09.fs @@ -0,0 +1,7 @@ +module Module + +async { + let! Union value: int option = asyncOption() + and! Union value2: int option = asyncOption() + return value + value2 +} \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 09.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 09.fs.bsl new file mode 100644 index 00000000000..0233ea37538 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 09.fs.bsl @@ -0,0 +1,70 @@ +ImplFile + (ParsedImplFileInput + ("/root/SynType/Typed LetBang AndBang 09.fs", false, + QualifiedNameOfFile Module, [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + LetOrUseBang + (Yes (4,4--4,48), false, true, + Typed + (LongIdent + (SynLongIdent ([Union], [], [None]), None, None, + Pats + [Named + (SynIdent (value, None), false, None, + (4,15--4,20))], None, (4,9--4,20)), + App + (LongIdent (SynLongIdent ([option], [], [None])), + None, + [LongIdent (SynLongIdent ([int], [], [None]))], [], + None, true, (4,22--4,32)), (4,9--4,32)), + App + (Atomic, false, Ident asyncOption, + Const (Unit, (4,46--4,48)), (4,35--4,48)), + [SynExprAndBang + (Yes (5,4--5,49), false, true, + Typed + (LongIdent + (SynLongIdent ([Union], [], [None]), None, None, + Pats + [Named + (SynIdent (value2, None), false, None, + (5,15--5,21))], None, (5,9--5,21)), + App + (LongIdent (SynLongIdent ([option], [], [None])), + None, + [LongIdent (SynLongIdent ([int], [], [None]))], + [], None, true, (5,23--5,33)), (5,9--5,33)), + App + (Atomic, false, Ident asyncOption, + Const (Unit, (5,47--5,49)), (5,36--5,49)), + (5,4--5,49), { AndBangKeyword = (5,4--5,8) + EqualsRange = (5,34--5,35) + InKeyword = None })], + YieldOrReturn + ((false, true), + App + (NonAtomic, false, + App + (NonAtomic, true, + LongIdent + (false, + SynLongIdent + ([op_Addition], [], + [Some (OriginalNotation "+")]), None, + (6,17--6,18)), Ident value, (6,11--6,18)), + Ident value2, (6,11--6,25)), (6,4--6,25), + { YieldOrReturnKeyword = (6,4--6,10) }), (4,4--6,25), + { LetOrUseBangKeyword = (4,4--4,8) + EqualsRange = Some (4,33--4,34) }), (3,6--7,1)), + (3,0--7,1)), (3,0--7,1))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--7,1), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 10.fs b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 10.fs new file mode 100644 index 00000000000..820ef060e8f --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 10.fs @@ -0,0 +1,7 @@ +module Module + +async { + let! (x as y): int = asyncInt() + and! (a as b): string = asyncString() + return x + b +} \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 10.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 10.fs.bsl new file mode 100644 index 00000000000..4c616752ce3 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 10.fs.bsl @@ -0,0 +1,67 @@ +ImplFile + (ParsedImplFileInput + ("/root/SynType/Typed LetBang AndBang 10.fs", false, + QualifiedNameOfFile Module, [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + LetOrUseBang + (Yes (4,4--4,35), false, true, + Typed + (Paren + (As + (Named + (SynIdent (x, None), false, None, (4,10--4,11)), + Named + (SynIdent (y, None), false, None, (4,15--4,16)), + (4,10--4,16)), (4,9--4,17)), + LongIdent (SynLongIdent ([int], [], [None])), + (4,9--4,22)), + App + (Atomic, false, Ident asyncInt, + Const (Unit, (4,33--4,35)), (4,25--4,35)), + [SynExprAndBang + (Yes (5,4--5,41), false, true, + Typed + (Paren + (As + (Named + (SynIdent (a, None), false, None, + (5,10--5,11)), + Named + (SynIdent (b, None), false, None, + (5,15--5,16)), (5,10--5,16)), (5,9--5,17)), + LongIdent (SynLongIdent ([string], [], [None])), + (5,9--5,25)), + App + (Atomic, false, Ident asyncString, + Const (Unit, (5,39--5,41)), (5,28--5,41)), + (5,4--5,41), { AndBangKeyword = (5,4--5,8) + EqualsRange = (5,26--5,27) + InKeyword = None })], + YieldOrReturn + ((false, true), + App + (NonAtomic, false, + App + (NonAtomic, true, + LongIdent + (false, + SynLongIdent + ([op_Addition], [], + [Some (OriginalNotation "+")]), None, + (6,13--6,14)), Ident x, (6,11--6,14)), + Ident b, (6,11--6,16)), (6,4--6,16), + { YieldOrReturnKeyword = (6,4--6,10) }), (4,4--6,16), + { LetOrUseBangKeyword = (4,4--4,8) + EqualsRange = Some (4,23--4,24) }), (3,6--7,1)), + (3,0--7,1)), (3,0--7,1))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--7,1), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 11.fs b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 11.fs new file mode 100644 index 00000000000..08da39cd1d8 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 11.fs @@ -0,0 +1,7 @@ +module Module + +async { + let! x as y: int = asyncInt() + and! a as b: string = asyncString() + return x + b +} \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 11.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 11.fs.bsl new file mode 100644 index 00000000000..4c4991234a3 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 11.fs.bsl @@ -0,0 +1,64 @@ +ImplFile + (ParsedImplFileInput + ("/root/SynType/Typed LetBang AndBang 11.fs", false, + QualifiedNameOfFile Module, [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + LetOrUseBang + (Yes (4,4--4,33), false, true, + Typed + (As + (Named + (SynIdent (x, None), false, None, (4,9--4,10)), + Named + (SynIdent (y, None), false, None, (4,14--4,15)), + (4,9--4,15)), + LongIdent (SynLongIdent ([int], [], [None])), + (4,9--4,20)), + App + (Atomic, false, Ident asyncInt, + Const (Unit, (4,31--4,33)), (4,23--4,33)), + [SynExprAndBang + (Yes (5,4--5,39), false, true, + Typed + (As + (Named + (SynIdent (a, None), false, None, (5,9--5,10)), + Named + (SynIdent (b, None), false, None, + (5,14--5,15)), (5,9--5,15)), + LongIdent (SynLongIdent ([string], [], [None])), + (5,9--5,23)), + App + (Atomic, false, Ident asyncString, + Const (Unit, (5,37--5,39)), (5,26--5,39)), + (5,4--5,39), { AndBangKeyword = (5,4--5,8) + EqualsRange = (5,24--5,25) + InKeyword = None })], + YieldOrReturn + ((false, true), + App + (NonAtomic, false, + App + (NonAtomic, true, + LongIdent + (false, + SynLongIdent + ([op_Addition], [], + [Some (OriginalNotation "+")]), None, + (6,13--6,14)), Ident x, (6,11--6,14)), + Ident b, (6,11--6,16)), (6,4--6,16), + { YieldOrReturnKeyword = (6,4--6,10) }), (4,4--6,16), + { LetOrUseBangKeyword = (4,4--4,8) + EqualsRange = Some (4,21--4,22) }), (3,6--7,1)), + (3,0--7,1)), (3,0--7,1))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--7,1), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 12.fs b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 12.fs new file mode 100644 index 00000000000..f8d1d7fad52 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 12.fs @@ -0,0 +1,7 @@ +module Module + +async { + let! x as y = asyncInt() + and! a as b = asyncString() + return x + b +} \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 12.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 12.fs.bsl new file mode 100644 index 00000000000..ffb04e5db54 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 12.fs.bsl @@ -0,0 +1,56 @@ +ImplFile + (ParsedImplFileInput + ("/root/SynType/Typed LetBang AndBang 12.fs", false, + QualifiedNameOfFile Module, [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + LetOrUseBang + (Yes (4,4--4,28), false, true, + As + (Named (SynIdent (x, None), false, None, (4,9--4,10)), + Named (SynIdent (y, None), false, None, (4,14--4,15)), + (4,9--4,15)), + App + (Atomic, false, Ident asyncInt, + Const (Unit, (4,26--4,28)), (4,18--4,28)), + [SynExprAndBang + (Yes (5,4--5,31), false, true, + As + (Named + (SynIdent (a, None), false, None, (5,9--5,10)), + Named + (SynIdent (b, None), false, None, (5,14--5,15)), + (5,9--5,15)), + App + (Atomic, false, Ident asyncString, + Const (Unit, (5,29--5,31)), (5,18--5,31)), + (5,4--5,31), { AndBangKeyword = (5,4--5,8) + EqualsRange = (5,16--5,17) + InKeyword = None })], + YieldOrReturn + ((false, true), + App + (NonAtomic, false, + App + (NonAtomic, true, + LongIdent + (false, + SynLongIdent + ([op_Addition], [], + [Some (OriginalNotation "+")]), None, + (6,13--6,14)), Ident x, (6,11--6,14)), + Ident b, (6,11--6,16)), (6,4--6,16), + { YieldOrReturnKeyword = (6,4--6,10) }), (4,4--6,16), + { LetOrUseBangKeyword = (4,4--4,8) + EqualsRange = Some (4,16--4,17) }), (3,6--7,1)), + (3,0--7,1)), (3,0--7,1))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--7,1), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 13.fs b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 13.fs new file mode 100644 index 00000000000..2ec04876505 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 13.fs @@ -0,0 +1,7 @@ +module Module + +async { + let! ([| first; second |]: int array) = asyncArray() + and! (head :: tail: string list) = asyncList() + return first +} diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 13.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 13.fs.bsl new file mode 100644 index 00000000000..b79f90358d2 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 13.fs.bsl @@ -0,0 +1,70 @@ +ImplFile + (ParsedImplFileInput + ("/root/SynType/Typed LetBang AndBang 13.fs", false, + QualifiedNameOfFile Module, [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + LetOrUseBang + (Yes (4,4--4,56), false, true, + Paren + (Typed + (ArrayOrList + (true, + [Named + (SynIdent (first, None), false, None, + (4,13--4,18)); + Named + (SynIdent (second, None), false, None, + (4,20--4,26))], (4,10--4,29)), + App + (LongIdent (SynLongIdent ([array], [], [None])), + None, + [LongIdent (SynLongIdent ([int], [], [None]))], + [], None, true, (4,31--4,40)), (4,10--4,40)), + (4,9--4,41)), + App + (Atomic, false, Ident asyncArray, + Const (Unit, (4,54--4,56)), (4,44--4,56)), + [SynExprAndBang + (Yes (5,4--5,50), false, true, + Paren + (ListCons + (Named + (SynIdent (head, None), false, None, + (5,10--5,14)), + Typed + (Named + (SynIdent (tail, None), false, None, + (5,18--5,22)), + App + (LongIdent + (SynLongIdent ([list], [], [None])), + None, + [LongIdent + (SynLongIdent ([string], [], [None]))], + [], None, true, (5,24--5,35)), + (5,18--5,35)), (5,10--5,35), + { ColonColonRange = (5,15--5,17) }), + (5,9--5,36)), + App + (Atomic, false, Ident asyncList, + Const (Unit, (5,48--5,50)), (5,39--5,50)), + (5,4--5,50), { AndBangKeyword = (5,4--5,8) + EqualsRange = (5,37--5,38) + InKeyword = None })], + YieldOrReturn + ((false, true), Ident first, (6,4--6,16), + { YieldOrReturnKeyword = (6,4--6,10) }), (4,4--6,16), + { LetOrUseBangKeyword = (4,4--4,8) + EqualsRange = Some (4,42--4,43) }), (3,6--7,1)), + (3,0--7,1)), (3,0--7,1))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--7,1), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 14.fs b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 14.fs new file mode 100644 index 00000000000..95522afafc7 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 14.fs @@ -0,0 +1,7 @@ +module Module + +async { + let! [| first; second |]: int array = asyncArray() + and! head :: tail: string list = asyncList() + return first +} diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 14.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 14.fs.bsl new file mode 100644 index 00000000000..eaefd1aa4ef --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 14.fs.bsl @@ -0,0 +1,64 @@ +ImplFile + (ParsedImplFileInput + ("/root/SynType/Typed LetBang AndBang 14.fs", false, + QualifiedNameOfFile Module, [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + LetOrUseBang + (Yes (4,4--4,54), false, true, + Typed + (ArrayOrList + (true, + [Named + (SynIdent (first, None), false, None, + (4,12--4,17)); + Named + (SynIdent (second, None), false, None, + (4,19--4,25))], (4,9--4,28)), + App + (LongIdent (SynLongIdent ([array], [], [None])), + None, + [LongIdent (SynLongIdent ([int], [], [None]))], [], + None, true, (4,30--4,39)), (4,9--4,39)), + App + (Atomic, false, Ident asyncArray, + Const (Unit, (4,52--4,54)), (4,42--4,54)), + [SynExprAndBang + (Yes (5,4--5,48), false, true, + Typed + (ListCons + (Named + (SynIdent (head, None), false, None, + (5,9--5,13)), + Named + (SynIdent (tail, None), false, None, + (5,17--5,21)), (5,9--5,21), + { ColonColonRange = (5,14--5,16) }), + App + (LongIdent (SynLongIdent ([list], [], [None])), + None, + [LongIdent + (SynLongIdent ([string], [], [None]))], [], + None, true, (5,23--5,34)), (5,9--5,34)), + App + (Atomic, false, Ident asyncList, + Const (Unit, (5,46--5,48)), (5,37--5,48)), + (5,4--5,48), { AndBangKeyword = (5,4--5,8) + EqualsRange = (5,35--5,36) + InKeyword = None })], + YieldOrReturn + ((false, true), Ident first, (6,4--6,16), + { YieldOrReturnKeyword = (6,4--6,10) }), (4,4--6,16), + { LetOrUseBangKeyword = (4,4--4,8) + EqualsRange = Some (4,40--4,41) }), (3,6--7,1)), + (3,0--7,1)), (3,0--7,1))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--7,1), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 15.fs b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 15.fs new file mode 100644 index 00000000000..92646da071f --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 15.fs @@ -0,0 +1,7 @@ +module Module + +async { + let! (x, y): int * int = asyncInt() + and! x: int, y: int = asyncInt() + return () +} diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 15.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 15.fs.bsl new file mode 100644 index 00000000000..e60943e9933 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 15.fs.bsl @@ -0,0 +1,51 @@ +ImplFile + (ParsedImplFileInput + ("/root/SynType/Typed LetBang AndBang 15.fs", false, + QualifiedNameOfFile Module, [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + Tuple + (false, + [LetOrUseBang + (Yes (4,4--4,39), false, true, + Typed + (Paren + (Tuple + (false, + [Named + (SynIdent (x, None), false, None, + (4,10--4,11)); + Named + (SynIdent (y, None), false, None, + (4,13--4,14))], [(4,11--4,12)], + (4,10--4,14)), (4,9--4,15)), + Tuple + (false, + [Type + (LongIdent + (SynLongIdent ([int], [], [None]))); + Star (4,21--4,22); + Type + (LongIdent + (SynLongIdent ([int], [], [None])))], + (4,17--4,26)), (4,9--4,26)), + App + (Atomic, false, Ident asyncInt, + Const (Unit, (4,37--4,39)), (4,29--4,39)), [], + ImplicitZero (4,39--4,39), (4,4--5,16), + { LetOrUseBangKeyword = (4,4--4,8) + EqualsRange = Some (4,27--4,28) }); Ident y], + [(5,15--5,16)], (4,4--5,18)), (3,6--7,1)), (3,0--7,1)), + (3,0--7,1))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--7,1), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) + +(5,15)-(5,16) parse error Unexpected symbol ',' in expression. Expected '=' or other token. diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 16.fs b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 16.fs new file mode 100644 index 00000000000..b01631488a2 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 16.fs @@ -0,0 +1,7 @@ +module Module + +async { + let! (x, y): int * int = asyncInt() + and! (x: int, y: int) = asyncInt() + return () +} diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 16.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 16.fs.bsl new file mode 100644 index 00000000000..d9f64778935 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 16.fs.bsl @@ -0,0 +1,72 @@ +ImplFile + (ParsedImplFileInput + ("/root/SynType/Typed LetBang AndBang 16.fs", false, + QualifiedNameOfFile Module, [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + LetOrUseBang + (Yes (4,4--4,39), false, true, + Typed + (Paren + (Tuple + (false, + [Named + (SynIdent (x, None), false, None, + (4,10--4,11)); + Named + (SynIdent (y, None), false, None, + (4,13--4,14))], [(4,11--4,12)], (4,10--4,14)), + (4,9--4,15)), + Tuple + (false, + [Type + (LongIdent (SynLongIdent ([int], [], [None]))); + Star (4,21--4,22); + Type + (LongIdent (SynLongIdent ([int], [], [None])))], + (4,17--4,26)), (4,9--4,26)), + App + (Atomic, false, Ident asyncInt, + Const (Unit, (4,37--4,39)), (4,29--4,39)), + [SynExprAndBang + (Yes (5,4--5,38), false, true, + Paren + (Tuple + (false, + [Typed + (Named + (SynIdent (x, None), false, None, + (5,10--5,11)), + LongIdent + (SynLongIdent ([int], [], [None])), + (5,10--5,16)); + Typed + (Named + (SynIdent (y, None), false, None, + (5,18--5,19)), + LongIdent + (SynLongIdent ([int], [], [None])), + (5,18--5,24))], [(5,16--5,17)], + (5,10--5,24)), (5,9--5,25)), + App + (Atomic, false, Ident asyncInt, + Const (Unit, (5,36--5,38)), (5,28--5,38)), + (5,4--5,38), { AndBangKeyword = (5,4--5,8) + EqualsRange = (5,26--5,27) + InKeyword = None })], + YieldOrReturn + ((false, true), Const (Unit, (6,11--6,13)), (6,4--6,13), + { YieldOrReturnKeyword = (6,4--6,10) }), (4,4--6,13), + { LetOrUseBangKeyword = (4,4--4,8) + EqualsRange = Some (4,27--4,28) }), (3,6--7,1)), + (3,0--7,1)), (3,0--7,1))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--7,1), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 17.fs b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 17.fs new file mode 100644 index 00000000000..3918e729716 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 17.fs @@ -0,0 +1,7 @@ +module Module + +async { + let! (x, y): int * int = asyncInt() + and! (x, y): int * int = asyncInt() + return () +} diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 17.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 17.fs.bsl new file mode 100644 index 00000000000..f801b2d1319 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 17.fs.bsl @@ -0,0 +1,75 @@ +ImplFile + (ParsedImplFileInput + ("/root/SynType/Typed LetBang AndBang 17.fs", false, + QualifiedNameOfFile Module, [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + LetOrUseBang + (Yes (4,4--4,39), false, true, + Typed + (Paren + (Tuple + (false, + [Named + (SynIdent (x, None), false, None, + (4,10--4,11)); + Named + (SynIdent (y, None), false, None, + (4,13--4,14))], [(4,11--4,12)], (4,10--4,14)), + (4,9--4,15)), + Tuple + (false, + [Type + (LongIdent (SynLongIdent ([int], [], [None]))); + Star (4,21--4,22); + Type + (LongIdent (SynLongIdent ([int], [], [None])))], + (4,17--4,26)), (4,9--4,26)), + App + (Atomic, false, Ident asyncInt, + Const (Unit, (4,37--4,39)), (4,29--4,39)), + [SynExprAndBang + (Yes (5,4--5,39), false, true, + Typed + (Paren + (Tuple + (false, + [Named + (SynIdent (x, None), false, None, + (5,10--5,11)); + Named + (SynIdent (y, None), false, None, + (5,13--5,14))], [(5,11--5,12)], + (5,10--5,14)), (5,9--5,15)), + Tuple + (false, + [Type + (LongIdent + (SynLongIdent ([int], [], [None]))); + Star (5,21--5,22); + Type + (LongIdent + (SynLongIdent ([int], [], [None])))], + (5,17--5,26)), (5,9--5,26)), + App + (Atomic, false, Ident asyncInt, + Const (Unit, (5,37--5,39)), (5,29--5,39)), + (5,4--5,39), { AndBangKeyword = (5,4--5,8) + EqualsRange = (5,27--5,28) + InKeyword = None })], + YieldOrReturn + ((false, true), Const (Unit, (6,11--6,13)), (6,4--6,13), + { YieldOrReturnKeyword = (6,4--6,10) }), (4,4--6,13), + { LetOrUseBangKeyword = (4,4--4,8) + EqualsRange = Some (4,27--4,28) }), (3,6--7,1)), + (3,0--7,1)), (3,0--7,1))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--7,1), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 18.fs b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 18.fs new file mode 100644 index 00000000000..d4e86eafa48 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 18.fs @@ -0,0 +1,7 @@ +module Module + +async { + let! (x as y): int = asyncInt() + and! (a as b): = asyncString() + return x + b +} \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 18.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 18.fs.bsl new file mode 100644 index 00000000000..037d6651228 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 18.fs.bsl @@ -0,0 +1,69 @@ +ImplFile + (ParsedImplFileInput + ("/root/SynType/Typed LetBang AndBang 18.fs", false, + QualifiedNameOfFile Module, [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + LetOrUseBang + (Yes (4,4--4,35), false, true, + Typed + (Paren + (As + (Named + (SynIdent (x, None), false, None, (4,10--4,11)), + Named + (SynIdent (y, None), false, None, (4,15--4,16)), + (4,10--4,16)), (4,9--4,17)), + LongIdent (SynLongIdent ([int], [], [None])), + (4,9--4,22)), + App + (Atomic, false, Ident asyncInt, + Const (Unit, (4,33--4,35)), (4,25--4,35)), + [SynExprAndBang + (Yes (5,4--5,34), false, true, + Typed + (Paren + (As + (Named + (SynIdent (a, None), false, None, + (5,10--5,11)), + Named + (SynIdent (b, None), false, None, + (5,15--5,16)), (5,10--5,16)), (5,9--5,17)), + FromParseError (5,18--5,18), (5,9--5,18)), + App + (Atomic, false, Ident asyncString, + Const (Unit, (5,32--5,34)), (5,21--5,34)), + (5,4--5,34), { AndBangKeyword = (5,4--5,8) + EqualsRange = (5,19--5,20) + InKeyword = None })], + YieldOrReturn + ((false, true), + App + (NonAtomic, false, + App + (NonAtomic, true, + LongIdent + (false, + SynLongIdent + ([op_Addition], [], + [Some (OriginalNotation "+")]), None, + (6,13--6,14)), Ident x, (6,11--6,14)), + Ident b, (6,11--6,16)), (6,4--6,16), + { YieldOrReturnKeyword = (6,4--6,10) }), (4,4--6,16), + { LetOrUseBangKeyword = (4,4--4,8) + EqualsRange = Some (4,23--4,24) }), (3,6--7,1)), + (3,0--7,1)), (3,0--7,1))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--7,1), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) + +(5,19)-(5,20) parse error Unexpected symbol '=' in expression +(5,18)-(5,18) parse error Expecting type diff --git a/tests/service/data/SyntaxTree/SynType/Typed UseBang 05.fs b/tests/service/data/SyntaxTree/SynType/Typed UseBang 05.fs new file mode 100644 index 00000000000..4fd5d1f25ef --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed UseBang 05.fs @@ -0,0 +1,6 @@ +module Module + +async { + use! res: = async { return 1 } + return res +} diff --git a/tests/service/data/SyntaxTree/SynType/Typed UseBang 05.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed UseBang 05.fs.bsl new file mode 100644 index 00000000000..9042c097425 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed UseBang 05.fs.bsl @@ -0,0 +1,38 @@ +ImplFile + (ParsedImplFileInput + ("/root/SynType/Typed UseBang 05.fs", false, QualifiedNameOfFile Module, [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + LetOrUseBang + (Yes (4,4--4,34), true, true, + Typed + (Named (SynIdent (res, None), false, None, (4,9--4,12)), + FromParseError (4,13--4,13), (4,9--4,13)), + App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + YieldOrReturn + ((false, true), Const (Int32 1, (4,31--4,32)), + (4,24--4,32), + { YieldOrReturnKeyword = (4,24--4,30) }), + (4,22--4,34)), (4,16--4,34)), [], + YieldOrReturn + ((false, true), Ident res, (5,4--5,14), + { YieldOrReturnKeyword = (5,4--5,10) }), (4,4--5,14), + { LetOrUseBangKeyword = (4,4--4,8) + EqualsRange = Some (4,14--4,15) }), (3,6--6,1)), + (3,0--6,1)), (3,0--6,1))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--6,1), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) + +(4,14)-(4,15) parse error Unexpected symbol '=' in expression +(4,13)-(4,13) parse error Expecting type diff --git a/tests/service/data/SyntaxTree/SynType/Typed UseBang 06.fs b/tests/service/data/SyntaxTree/SynType/Typed UseBang 06.fs new file mode 100644 index 00000000000..66bc6a8e4b7 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed UseBang 06.fs @@ -0,0 +1,6 @@ +module Module + +async { + use! res: + return res +} diff --git a/tests/service/data/SyntaxTree/SynType/Typed UseBang 06.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed UseBang 06.fs.bsl new file mode 100644 index 00000000000..dd99b50a61a --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed UseBang 06.fs.bsl @@ -0,0 +1,13 @@ +ImplFile + (ParsedImplFileInput + ("/root/SynType/Typed UseBang 06.fs", false, + QualifiedNameOfFile Typed UseBang 06, [], + [SynModuleOrNamespace + ([Typed UseBang 06], false, AnonModule, [], PreXmlDocEmpty, [], None, + (7,0--7,0), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) + +(5,4)-(5,10) parse error Incomplete structured construct at or before this point in expression +(4,13)-(4,13) parse error Expecting type