diff --git a/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md b/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md index 28f20ca2be2..fe3cde0444a 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md +++ b/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md @@ -18,5 +18,6 @@ * Better ranges for CE `do!` error reporting. ([PR #17779](https://github.com/dotnet/fsharp/pull/17779)) * Better ranges for CE `return, yield, return! and yield!` error reporting. ([PR #17792](https://github.com/dotnet/fsharp/pull/17792)) * Better ranges for CE `match!`. ([PR #17789](https://github.com/dotnet/fsharp/pull/17789)) +* Better ranges for CE `use` error reporting. ([PR #17811](https://github.com/dotnet/fsharp/pull/17811)) ### Breaking Changes diff --git a/src/Compiler/Checking/Expressions/CheckComputationExpressions.fs b/src/Compiler/Checking/Expressions/CheckComputationExpressions.fs index c1aa4dafc5d..645897a6793 100644 --- a/src/Compiler/Checking/Expressions/CheckComputationExpressions.fs +++ b/src/Compiler/Checking/Expressions/CheckComputationExpressions.fs @@ -1805,11 +1805,8 @@ let rec TryTranslateComputationExpression | SynExpr.LetOrUse( isUse = true bindings = [ SynBinding(kind = SynBindingKind.Normal; headPat = pat; expr = rhsExpr; debugPoint = spBind) ] - body = innerComp) -> - let mBind = - match spBind with - | DebugPointAtBinding.Yes m -> m - | _ -> rhsExpr.Range + body = innerComp + trivia = { LetOrUseKeyword = mBind }) -> if ceenv.isQuery then error (Error(FSComp.SR.tcUseMayNotBeUsedInQueries (), mBind)) diff --git a/src/Compiler/Checking/Expressions/CheckSequenceExpressions.fs b/src/Compiler/Checking/Expressions/CheckSequenceExpressions.fs index 781060c8af4..3154d3e1e74 100644 --- a/src/Compiler/Checking/Expressions/CheckSequenceExpressions.fs +++ b/src/Compiler/Checking/Expressions/CheckSequenceExpressions.fs @@ -232,9 +232,10 @@ let TcSequenceExpression (cenv: TcFileState) env tpenv comp (overallTy: OverallT // 'use x = expr in expr' | SynExpr.LetOrUse( isUse = true - bindings = [ SynBinding(kind = SynBindingKind.Normal; headPat = pat; expr = rhsExpr; debugPoint = spBind) ] + bindings = [ SynBinding(kind = SynBindingKind.Normal; headPat = pat; expr = rhsExpr) ] body = innerComp - range = wholeExprMark) -> + range = wholeExprMark + trivia = { LetOrUseKeyword = mBind }) -> let bindPatTy = NewInferenceType g let inputExprTy = NewInferenceType g @@ -252,11 +253,6 @@ let TcSequenceExpression (cenv: TcFileState) env tpenv comp (overallTy: OverallT let envinner = { envinner with eIsControlFlow = true } tcSequenceExprBody envinner genOuterTy tpenv innerComp - let mBind = - match spBind with - | DebugPointAtBinding.Yes m -> m.NoteSourceConstruct(NotedSourceConstruct.Binding) - | _ -> inputExpr.Range - let inputExprMark = inputExpr.Range let matchv, matchExpr = diff --git a/src/Compiler/Service/service.fs b/src/Compiler/Service/service.fs index 525faf3be3d..5f6588bd770 100644 --- a/src/Compiler/Service/service.fs +++ b/src/Compiler/Service/service.fs @@ -72,10 +72,10 @@ module CompileHelpers = try f exiter - 0 + None with e -> stopProcessingRecovery e range0 - 1 + Some e /// Compile using the given flags. Source files names are resolved via the FileSystem API. The output file must be given by a -o flag. let compileFromArgs (ctok, argv: string[], legacyReferenceResolver, tcImportsCapture, dynamicAssemblyCreator) = diff --git a/src/Compiler/Service/service.fsi b/src/Compiler/Service/service.fsi index 0e48a0d6360..3e4fde2229c 100644 --- a/src/Compiler/Service/service.fsi +++ b/src/Compiler/Service/service.fsi @@ -400,11 +400,12 @@ type public FSharpChecker = /// Compile using the given flags. Source files names are resolved via the FileSystem API. /// The output file must be given by a -o flag. /// The first argument is ignored and can just be "fsc.exe". + /// The method returns the collected diagnostics, and (possibly) a terminating exception. /// /// /// The command line arguments for the project build. /// An optional string used for tracing compiler operations associated with this request. - member Compile: argv: string[] * ?userOpName: string -> Async + member Compile: argv: string[] * ?userOpName: string -> Async /// /// Try to get type check results for a file. This looks up the results of recent type checks of the diff --git a/src/Compiler/SyntaxTree/ParseHelpers.fs b/src/Compiler/SyntaxTree/ParseHelpers.fs index 8d62a724972..1d26a1b2ba9 100644 --- a/src/Compiler/SyntaxTree/ParseHelpers.fs +++ b/src/Compiler/SyntaxTree/ParseHelpers.fs @@ -1049,7 +1049,22 @@ let mkLocalBindings (mWhole, BindingSetPreAttrs(_, isRec, isUse, declsPreAttrs, else Some mIn) - SynExpr.LetOrUse(isRec, isUse, decls, body, mWhole, { InKeyword = mIn }) + let mLetOrUse = + match decls with + | SynBinding(trivia = trivia) :: _ -> trivia.LeadingKeyword.Range + | _ -> Range.Zero + + SynExpr.LetOrUse( + isRec, + isUse, + decls, + body, + mWhole, + { + LetOrUseKeyword = mLetOrUse + InKeyword = mIn + } + ) let mkDefnBindings (mWhole, BindingSetPreAttrs(_, isRec, isUse, declsPreAttrs, _bindingSetRange), attrs, vis, attrsm) = if isUse then diff --git a/src/Compiler/SyntaxTree/SyntaxTrivia.fs b/src/Compiler/SyntaxTree/SyntaxTrivia.fs index 10aee262292..6a550c3b1a8 100644 --- a/src/Compiler/SyntaxTree/SyntaxTrivia.fs +++ b/src/Compiler/SyntaxTree/SyntaxTrivia.fs @@ -85,10 +85,15 @@ type SynExprDotLambdaTrivia = [] type SynExprLetOrUseTrivia = { + LetOrUseKeyword: range InKeyword: range option } - static member Zero: SynExprLetOrUseTrivia = { InKeyword = None } + static member Zero: SynExprLetOrUseTrivia = + { + InKeyword = None + LetOrUseKeyword = Range.Zero + } [] type SynExprLetOrUseBangTrivia = diff --git a/src/Compiler/SyntaxTree/SyntaxTrivia.fsi b/src/Compiler/SyntaxTree/SyntaxTrivia.fsi index fff834beb41..f16294b0a1d 100644 --- a/src/Compiler/SyntaxTree/SyntaxTrivia.fsi +++ b/src/Compiler/SyntaxTree/SyntaxTrivia.fsi @@ -129,6 +129,8 @@ type SynExprDotLambdaTrivia = [] type SynExprLetOrUseTrivia = { + /// The syntax range of the `let` or `use` keyword. + LetOrUseKeyword: range /// The syntax range of the `in` keyword. InKeyword: range option } diff --git a/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/Ifdef.fs b/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/Ifdef.fs new file mode 100644 index 00000000000..99d019504d6 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/Ifdef.fs @@ -0,0 +1,57 @@ +namespace CompilerDirectives + +open Xunit +open FSharp.Test.Compiler + +module Ifdef = + + let ifdefSource = """ +[] +let main _ = + #if MYDEFINE1 + 1 + #else + 2 + #endif +""" + + [] + [] + [] + let ifdefTest (mydefine, expectedExitCode) = + + FSharp ifdefSource + |> withDefines [mydefine] + |> compileExeAndRun + |> withExitCode expectedExitCode + + + let sourceExtraEndif = """ +#if MYDEFINE1 +printf "1" +#endif +(**)#endif(**) +0 +""" + + [] + let extraEndif () = + + FSharp sourceExtraEndif + |> withDefines ["MYDEFINE1"] + |> asExe + |> compile + |> withDiagnosticMessage "#endif has no matching #if in implementation file" + + let sourceUnknownHash = """ +module A +#ifxx +#abc +""" + + [] + let unknownHashDirectiveIsIgnored () = + + FSharp sourceUnknownHash + |> compile + |> shouldSucceed \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/ConstraintSolver/MemberConstraints.fs b/tests/FSharp.Compiler.ComponentTests/ConstraintSolver/MemberConstraints.fs index b3c33031acb..c560008da0c 100644 --- a/tests/FSharp.Compiler.ComponentTests/ConstraintSolver/MemberConstraints.fs +++ b/tests/FSharp.Compiler.ComponentTests/ConstraintSolver/MemberConstraints.fs @@ -45,7 +45,6 @@ else () |> compile |> run |> shouldSucceed - |> withExitCode 0 [] let ``Respect nowarn 957 for extension method`` () = diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Literals.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Literals.fs index d2dc41a3235..1477db7754c 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Literals.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Literals.fs @@ -176,37 +176,118 @@ let [] x = System.Int32.MaxValue + 1 } [] - let ``Arithmetic can be used for constructing decimal literals``() = + let ``Decimal literals are properly initialized``() = FSharp """ -module LiteralArithmetic +module DecimalInit [] -let x = 1m + 2m +let x = 5.5m """ |> withLangVersion80 |> compile |> shouldSucceed |> verifyIL [ - """.field public static initonly valuetype [runtime]System.Decimal x""" - """.custom instance void [runtime]System.Runtime.CompilerServices.DecimalConstantAttribute::.ctor(uint8, + """ +.class public abstract auto ansi sealed DecimalInit + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .field public static initonly valuetype [runtime]System.Decimal x + .custom instance void [runtime]System.Runtime.CompilerServices.DecimalConstantAttribute::.ctor(uint8, uint8, int32, int32, - int32) = ( 01 00 00 00 00 00 00 00 00 00 00 00 03 00 00 00 - 00 00 )""" - """.maxstack 8""" - """IL_0000: ldc.i4.3""" - """IL_0001: ldc.i4.0""" - """IL_0002: ldc.i4.0""" - """IL_0003: ldc.i4.0""" - """IL_0004: ldc.i4.0""" - """IL_0005: newobj instance void [runtime]System.Decimal::.ctor(int32, + int32) = ( 01 00 01 00 00 00 00 00 00 00 00 00 37 00 00 00 + 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .method private specialname rtspecialname static void .cctor() cil managed + { + + .maxstack 8 + IL_0000: ldc.i4.0 + IL_0001: stsfld int32 ''.$DecimalInit::init@ + IL_0006: ldsfld int32 ''.$DecimalInit::init@ + IL_000b: pop + IL_000c: ret + } + + .method assembly specialname static void staticInitialization@() cil managed + { + + .maxstack 8 + IL_0000: ldc.i4.s 55 + IL_0002: ldc.i4.0 + IL_0003: ldc.i4.0 + IL_0004: ldc.i4.0 + IL_0005: ldc.i4.1 + IL_0006: newobj instance void [runtime]System.Decimal::.ctor(int32, int32, int32, bool, - uint8)""" - """IL_000a: stsfld valuetype [runtime]System.Decimal LiteralArithmetic::x""" - """IL_000f: ret""" + uint8) + IL_000b: stsfld valuetype [runtime]System.Decimal DecimalInit::x + IL_0010: ret + } + +} + +.class private abstract auto ansi sealed ''.$DecimalInit + extends [runtime]System.Object +{ + .field static assembly int32 init@ + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method private specialname rtspecialname static void .cctor() cil managed + { + + .maxstack 8 + IL_0000: call void DecimalInit::staticInitialization@() + IL_0005: ret + } + +} +""" + ] + + [] + let ``Arithmetic can be used for constructing decimal literals``() = + FSharp """ +module LiteralArithmetic + +[] +let x = 1m + 2m + """ + |> withLangVersion80 + |> compile + |> shouldSucceed + |> verifyIL [ + """.field public static initonly valuetype [runtime]System.Decimal x +.custom instance void [runtime]System.Runtime.CompilerServices.DecimalConstantAttribute::.ctor(uint8, + uint8, + int32, + int32, + int32) = ( 01 00 00 00 00 00 00 00 00 00 00 00 03 00 00 00 + 00 00 )""" + """ +.method assembly specialname static void staticInitialization@() cil managed +{ + +.maxstack 8 +IL_0000: ldc.i4.3 +IL_0001: ldc.i4.0 +IL_0002: ldc.i4.0 +IL_0003: ldc.i4.0 +IL_0004: ldc.i4.0 +IL_0005: newobj instance void [runtime]System.Decimal::.ctor(int32, + int32, + int32, + bool, + uint8) +IL_000a: stsfld valuetype [runtime]System.Decimal LiteralArithmetic::x +IL_000f: ret +} +""" ] [] @@ -226,28 +307,45 @@ let test () = |> compile |> shouldSucceed |> verifyIL [ - """.field public static initonly valuetype [runtime]System.Decimal x""" - """ .custom instance void [runtime]System.Runtime.CompilerServices.DecimalConstantAttribute::.ctor(uint8, - uint8, - int32, - int32, - int32) = ( 01 00 00 00 00 00 00 00 00 00 00 00 05 00 00 00 - 00 00 )""" - """IL_0016: call bool [netstandard]System.Decimal::op_Equality(valuetype [netstandard]System.Decimal, - valuetype [netstandard]System.Decimal)""" - """.maxstack 8""" - """IL_0000: ldc.i4.5""" - """IL_0001: ldc.i4.0""" - """IL_0002: ldc.i4.0""" - """IL_0003: ldc.i4.0""" - """IL_0004: ldc.i4.0""" - """IL_0005: newobj instance void [runtime]System.Decimal::.ctor(int32, - int32, - int32, - bool, - uint8)""" - """IL_000a: stsfld valuetype [runtime]System.Decimal PatternMatch::x""" - """IL_000f: ret""" + """ +.field public static initonly valuetype [runtime]System.Decimal x +.custom instance void [runtime]System.Runtime.CompilerServices.DecimalConstantAttribute::.ctor(uint8, + uint8, + int32, + int32, + int32) = ( 01 00 00 00 00 00 00 00 00 00 00 00 05 00 00 00 + 00 00 )""" + """ +.method public static int32 test() cil managed + { + +.maxstack 8 +.locals init (valuetype [runtime]System.Decimal V_0) +IL_0000: ldc.i4.5 +IL_0001: ldc.i4.0 +IL_0002: ldc.i4.0 +IL_0003: ldc.i4.0 +IL_0004: ldc.i4.0 +IL_0005: newobj instance void [netstandard]System.Decimal::.ctor(int32, + int32, + int32, + bool, + uint8) +IL_000a: stloc.0 +IL_000b: ldloc.0 +IL_000c: ldc.i4.5 +IL_000d: ldc.i4.0 +IL_000e: ldc.i4.0 +IL_000f: ldc.i4.0 +IL_0010: ldc.i4.0 +IL_0011: newobj instance void [netstandard]System.Decimal::.ctor(int32, + int32, + int32, + bool, + uint8) +IL_0016: call bool [netstandard]System.Decimal::op_Equality(valuetype [netstandard]System.Decimal, + valuetype [netstandard]System.Decimal) + """ ] [] @@ -264,6 +362,56 @@ let y = 42m |> withLangVersion80 |> compile |> shouldSucceed + |> verifyIL [ + """ +.field public static initonly valuetype [runtime]System.Decimal x +.custom instance void [runtime]System.Runtime.CompilerServices.DecimalConstantAttribute::.ctor(uint8, + uint8, + int32, + int32, + int32) = ( 01 00 00 00 00 00 00 00 00 00 00 00 29 00 00 00 + 00 00 ) +""" + """ +.field public static initonly valuetype [runtime]System.Decimal y +.custom instance void [runtime]System.Runtime.CompilerServices.DecimalConstantAttribute::.ctor(uint8, + uint8, + int32, + int32, + int32) = ( 01 00 00 00 00 00 00 00 00 00 00 00 2A 00 00 00 + 00 00 ) +""" + """ +.method assembly specialname static void staticInitialization@() cil managed +{ + +.maxstack 8 +IL_0000: ldc.i4.s 41 +IL_0002: ldc.i4.0 +IL_0003: ldc.i4.0 +IL_0004: ldc.i4.0 +IL_0005: ldc.i4.0 +IL_0006: newobj instance void [runtime]System.Decimal::.ctor(int32, + int32, + int32, + bool, + uint8) +IL_000b: stsfld valuetype [runtime]System.Decimal DecimalLiterals::x +IL_0010: ldc.i4.s 42 +IL_0012: ldc.i4.0 +IL_0013: ldc.i4.0 +IL_0014: ldc.i4.0 +IL_0015: ldc.i4.0 +IL_0016: newobj instance void [runtime]System.Decimal::.ctor(int32, + int32, + int32, + bool, + uint8) +IL_001b: stsfld valuetype [runtime]System.Decimal DecimalLiterals::y +IL_0020: ret +} +""" + ] [] let ``Compilation fails when using arithmetic with a non-literal in literal``() = diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/TryCatch/TryCatch.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/TryCatch/TryCatch.fs index 9a43d34d429..1e5187167a7 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/TryCatch/TryCatch.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/TryCatch/TryCatch.fs @@ -56,9 +56,9 @@ let ``Stackoverflow reproduction`` compilation = | CompilationResult.Success ({OutputPath = Some dllFile} as s) -> let fsharpCoreFile = typeof>.Assembly.Location File.Copy(fsharpCoreFile, Path.Combine(Path.GetDirectoryName(dllFile), Path.GetFileName(fsharpCoreFile)), true) - let exitCode, _stdout, _stderr = CompilerAssert.ExecuteAndReturnResult (dllFile, isFsx=false, deps = s.Dependencies, newProcess=true) + let _exitCode, _stdout, stderr, _exn = CompilerAssert.ExecuteAndReturnResult (dllFile, isFsx=false, deps = s.Dependencies, newProcess=true) - Assert.NotEqual(0,exitCode) + Assert.True(stderr.Contains "stack overflow" || stderr.Contains "StackOverflow") | _ -> failwith (sprintf "%A" compilationResult) diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj index 4b50b28aa12..4ddec1e3405 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj +++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj @@ -33,6 +33,7 @@ + diff --git a/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs index 9d276c13629..3555e97fd2d 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs @@ -644,4 +644,85 @@ let indexHandler (): Task = 'string' but here has type 'Task' ") + ] + + [] + let ``use expressions may not be used in queries(SynExpr.Sequential)`` () = + Fsx """ +let x11 = + query { for c in [1..10] do + use x = { new System.IDisposable with __.Dispose() = () } + yield 1 } + """ + |> ignoreWarnings + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 3142, Line 4, Col 13, Line 4, Col 16, "'use' expressions may not be used in queries") + ] + + [] + let ``use, This control construct may only be used if the computation expression builder defines a 'Using' method`` () = + Fsx """ +module Result = + let zip x1 x2 = + match x1,x2 with + | Ok x1res, Ok x2res -> Ok (x1res, x2res) + | Error e, _ -> Error e + | _, Error e -> Error e + +type ResultBuilder() = + member _.MergeSources(t1: Result<'T,'U>, t2: Result<'T1,'U>) = Result.zip t1 t2 + member _.BindReturn(x: Result<'T,'U>, f) = Result.map f x + + member _.YieldReturn(x: Result<'T,'U>) = x + member _.Return(x: 'T) = Ok x + +let result = ResultBuilder() + +let run r2 r3 = + result { + use b = r2 + return Ok 0 + } + """ + |> ignoreWarnings + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 708, Line 20, Col 9, Line 20, Col 12, "This control construct may only be used if the computation expression builder defines a 'Using' method") + ] + + [] + let ``This 'let' definition may not be used in a query. Only simple value definitions may be used in queries.`` () = + Fsx """ +let x18rec2 = + query { + for d in [1..10] do + let rec f x = x + 1 // error expected here - no recursive functions + and g x = f x + 2 + select (f d) + } + +let x18inline = + query { + for d in [1..10] do + let inline f x = x + 1 // error expected here - no inline functions + select (f d) + } + +let x18mutable = + query { + for d in [1..10] do + let mutable v = 1 // error expected here - no mutable values + select (f d) + } + + """ + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 3147, Line 5, Col 17, Line 5, Col 20, "This 'let' definition may not be used in a query. Only simple value definitions may be used in queries.") + (Error 3147, Line 13, Col 20, Line 13, Col 23, "This 'let' definition may not be used in a query. Only simple value definitions may be used in queries.") + (Error 3147, Line 20, Col 21, Line 20, Col 22, "This 'let' definition may not be used in a query. Only simple value definitions may be used in queries.") ] \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/Graph/CompilationFromCmdlineArgsTests.fs b/tests/FSharp.Compiler.ComponentTests/TypeChecks/Graph/CompilationFromCmdlineArgsTests.fs index 9cfbbb9df80..294db344223 100644 --- a/tests/FSharp.Compiler.ComponentTests/TypeChecks/Graph/CompilationFromCmdlineArgsTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/Graph/CompilationFromCmdlineArgsTests.fs @@ -38,12 +38,12 @@ module CompilationFromCmdlineArgsTests = yield! methodOptions method |] - let diagnostics, exitCode = checker.Compile(args) |> Async.RunSynchronously + let diagnostics, exn = checker.Compile(args) |> Async.RunSynchronously for diag in diagnostics do printfn "%A" diag - Assert.Equal(exitCode, 0) + Assert.Equal(exn, None) finally Environment.CurrentDirectory <- oldWorkDir diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl index 42ec38ee366..15e1dd848e6 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl @@ -2166,7 +2166,7 @@ FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.CodeAnalysis.FSharpParseFileResults,FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults]] GetBackgroundCheckResultsForFileInProject(System.String, FSharp.Compiler.CodeAnalysis.FSharpProjectOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String]) FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.CodeAnalysis.FSharpProjectOptions,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Diagnostics.FSharpDiagnostic]]] GetProjectOptionsFromScript(System.String, FSharp.Compiler.Text.ISourceText, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.DateTime], Microsoft.FSharp.Core.FSharpOption`1[System.String[]], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.Int64], Microsoft.FSharp.Core.FSharpOption`1[System.String]) FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.CodeAnalysis.ProjectSnapshot+FSharpProjectSnapshot,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Diagnostics.FSharpDiagnostic]]] GetProjectSnapshotFromScript(System.String, FSharp.Compiler.Text.ISourceTextNew, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.CodeAnalysis.DocumentSource], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.DateTime], Microsoft.FSharp.Core.FSharpOption`1[System.String[]], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.Int64], Microsoft.FSharp.Core.FSharpOption`1[System.String]) -FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.Diagnostics.FSharpDiagnostic[],System.Int32]] Compile(System.String[], Microsoft.FSharp.Core.FSharpOption`1[System.String]) +FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.Diagnostics.FSharpDiagnostic[],Microsoft.FSharp.Core.FSharpOption`1[System.Exception]]] Compile(System.String[], Microsoft.FSharp.Core.FSharpOption`1[System.String]) FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.Text.Range,FSharp.Compiler.Text.Range][]] MatchBraces(System.String, FSharp.Compiler.Text.ISourceText, FSharp.Compiler.CodeAnalysis.FSharpParsingOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String]) FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.Text.Range,FSharp.Compiler.Text.Range][]] MatchBraces(System.String, System.String, FSharp.Compiler.CodeAnalysis.FSharpProjectOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String]) FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[FSharp.Compiler.CodeAnalysis.FSharpProjectOptions],FSharp.Compiler.CodeAnalysis.FSharpProjectOptions] ProjectChecked @@ -10231,7 +10231,9 @@ FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: FSharp.Compiler.SyntaxTrivia FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] InKeyword FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] get_InKeyword() FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: System.String ToString() -FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: Void .ctor(Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range]) +FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: FSharp.Compiler.Text.Range LetOrUseKeyword +FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: FSharp.Compiler.Text.Range get_LetOrUseKeyword() +FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: Void .ctor(FSharp.Compiler.Text.Range, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range]) FSharp.Compiler.SyntaxTrivia.SynExprMatchBangTrivia: FSharp.Compiler.Text.Range MatchBangKeyword FSharp.Compiler.SyntaxTrivia.SynExprMatchBangTrivia: FSharp.Compiler.Text.Range WithKeyword FSharp.Compiler.SyntaxTrivia.SynExprMatchBangTrivia: FSharp.Compiler.Text.Range get_MatchBangKeyword() diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl index 42ec38ee366..15e1dd848e6 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl @@ -2166,7 +2166,7 @@ FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.CodeAnalysis.FSharpParseFileResults,FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults]] GetBackgroundCheckResultsForFileInProject(System.String, FSharp.Compiler.CodeAnalysis.FSharpProjectOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String]) FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.CodeAnalysis.FSharpProjectOptions,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Diagnostics.FSharpDiagnostic]]] GetProjectOptionsFromScript(System.String, FSharp.Compiler.Text.ISourceText, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.DateTime], Microsoft.FSharp.Core.FSharpOption`1[System.String[]], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.Int64], Microsoft.FSharp.Core.FSharpOption`1[System.String]) FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.CodeAnalysis.ProjectSnapshot+FSharpProjectSnapshot,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Diagnostics.FSharpDiagnostic]]] GetProjectSnapshotFromScript(System.String, FSharp.Compiler.Text.ISourceTextNew, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.CodeAnalysis.DocumentSource], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.DateTime], Microsoft.FSharp.Core.FSharpOption`1[System.String[]], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.Int64], Microsoft.FSharp.Core.FSharpOption`1[System.String]) -FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.Diagnostics.FSharpDiagnostic[],System.Int32]] Compile(System.String[], Microsoft.FSharp.Core.FSharpOption`1[System.String]) +FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.Diagnostics.FSharpDiagnostic[],Microsoft.FSharp.Core.FSharpOption`1[System.Exception]]] Compile(System.String[], Microsoft.FSharp.Core.FSharpOption`1[System.String]) FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.Text.Range,FSharp.Compiler.Text.Range][]] MatchBraces(System.String, FSharp.Compiler.Text.ISourceText, FSharp.Compiler.CodeAnalysis.FSharpParsingOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String]) FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.Text.Range,FSharp.Compiler.Text.Range][]] MatchBraces(System.String, System.String, FSharp.Compiler.CodeAnalysis.FSharpProjectOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String]) FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[FSharp.Compiler.CodeAnalysis.FSharpProjectOptions],FSharp.Compiler.CodeAnalysis.FSharpProjectOptions] ProjectChecked @@ -10231,7 +10231,9 @@ FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: FSharp.Compiler.SyntaxTrivia FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] InKeyword FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] get_InKeyword() FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: System.String ToString() -FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: Void .ctor(Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range]) +FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: FSharp.Compiler.Text.Range LetOrUseKeyword +FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: FSharp.Compiler.Text.Range get_LetOrUseKeyword() +FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: Void .ctor(FSharp.Compiler.Text.Range, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range]) FSharp.Compiler.SyntaxTrivia.SynExprMatchBangTrivia: FSharp.Compiler.Text.Range MatchBangKeyword FSharp.Compiler.SyntaxTrivia.SynExprMatchBangTrivia: FSharp.Compiler.Text.Range WithKeyword FSharp.Compiler.SyntaxTrivia.SynExprMatchBangTrivia: FSharp.Compiler.Text.Range get_MatchBangKeyword() diff --git a/tests/FSharp.Test.Utilities/Compiler.fs b/tests/FSharp.Test.Utilities/Compiler.fs index f535bc21c5a..5e5629b089f 100644 --- a/tests/FSharp.Test.Utilities/Compiler.fs +++ b/tests/FSharp.Test.Utilities/Compiler.fs @@ -170,10 +170,13 @@ module rec Compiler = Message: string SubCategory: string } + // This type is used either for the output of the compiler (typically in CompilationResult coming from 'compile') + // or for the output of the code generated by the compiler (in CompilationResult coming from 'run') type ExecutionOutput = - { ExitCode: int + { ExitCode: int option StdOut: string - StdErr: string } + StdErr: string + Exn: exn option } type RunOutput = | EvalOutput of Result @@ -699,7 +702,7 @@ module rec Compiler = let private compileFSharpCompilation compilation ignoreWarnings (cUnit: CompilationUnit) : CompilationResult = use redirect = new RedirectConsole() - let ((err: FSharpDiagnostic[], rc: int, outputFilePath: string), deps) = + let ((err: FSharpDiagnostic[], exn, outputFilePath: string), deps) = CompilerAssert.CompileRaw(compilation, ignoreWarnings) // Create and stash the console output @@ -711,7 +714,7 @@ module rec Compiler = Adjust = 0 PerFileErrors = diagnostics Diagnostics = diagnostics |> List.map snd - Output = Some (RunOutput.ExecutionOutput { ExitCode = rc; StdOut = redirect.Output(); StdErr = redirect.ErrorOutput() }) + Output = Some (RunOutput.ExecutionOutput { ExitCode = None; StdOut = redirect.Output(); StdErr = redirect.ErrorOutput(); Exn = exn }) Compilation = cUnit } @@ -978,14 +981,13 @@ module rec Compiler = | SourceCodeFileKind.Fsx _ -> true | _ -> false | _ -> false - let exitCode, output, errors = CompilerAssert.ExecuteAndReturnResult (p, isFsx, s.Dependencies, false) + let exitCode, output, errors, exn = CompilerAssert.ExecuteAndReturnResult (p, isFsx, s.Dependencies, false) printfn "---------output-------\n%s\n-------" output printfn "---------errors-------\n%s\n-------" errors - let executionResult = { s with Output = Some (ExecutionOutput { ExitCode = exitCode; StdOut = output; StdErr = errors }) } - if exitCode = 0 then - CompilationResult.Success executionResult - else - CompilationResult.Failure executionResult + let executionResult = { s with Output = Some (ExecutionOutput { ExitCode = exitCode; StdOut = output; StdErr = errors; Exn = exn }) } + match exn with + | None -> CompilationResult.Success executionResult + | Some _ -> CompilationResult.Failure executionResult let compileAndRun = compile >> run @@ -1080,27 +1082,25 @@ module rec Compiler = opts.ToArray() let errors, stdOut = CompilerAssert.RunScriptWithOptionsAndReturnResult options source - let executionOutputwithStdOut: RunOutput option = - ExecutionOutput { StdOut = stdOut; ExitCode = 0; StdErr = "" } - |> Some - let result = + let mkResult output = { OutputPath = None Dependencies = [] Adjust = 0 Diagnostics = [] PerFileErrors= [] - Output = executionOutputwithStdOut + Output = Some output Compilation = cUnit } - - if errors.Count > 0 then - let output = ExecutionOutput { - ExitCode = -1 - StdOut = String.Empty - StdErr = ((errors |> String.concat "\n").Replace("\r\n","\n")) } - CompilationResult.Failure { result with Output = Some output } + + if errors.Count = 0 then + let output = + ExecutionOutput { ExitCode = None; StdOut = stdOut; StdErr = ""; Exn = None } + CompilationResult.Success (mkResult output) else - CompilationResult.Success result - + let err = (errors |> String.concat "\n").Replace("\r\n","\n") + let output = + ExecutionOutput {ExitCode = None; StdOut = String.Empty; StdErr = err; Exn = None } + CompilationResult.Failure (mkResult output) + finally disposals |> Seq.iter (fun x -> x.Dispose()) @@ -1190,7 +1190,7 @@ Actual: | Some p -> match ILChecker.verifyILAndReturnActual [] p expected with | true, _, _ -> result - | false, errorMsg, _actualIL -> CompilationResult.Failure( {s with Output = Some (ExecutionOutput { StdOut = errorMsg; ExitCode = 0; StdErr = "" })} ) + | false, errorMsg, _actualIL -> CompilationResult.Failure( {s with Output = Some (ExecutionOutput {ExitCode = None; StdOut = errorMsg; StdErr = ""; Exn = None })} ) | CompilationResult.Failure f -> failwith $"Result should be \"Success\" in order to get IL. Failure: {Environment.NewLine}{f}" @@ -1706,7 +1706,7 @@ Actual: | None -> failwith "Execution output is missing, cannot check exit code." | Some o -> match o with - | ExecutionOutput e -> Assert.Equal(expectedExitCode, e.ExitCode) + | ExecutionOutput {ExitCode = Some exitCode} -> Assert.Equal(expectedExitCode, exitCode) | _ -> failwith "Cannot check exit code on this run result." result diff --git a/tests/FSharp.Test.Utilities/CompilerAssert.fs b/tests/FSharp.Test.Utilities/CompilerAssert.fs index fc2875d8955..37a8e25e164 100644 --- a/tests/FSharp.Test.Utilities/CompilerAssert.fs +++ b/tests/FSharp.Test.Utilities/CompilerAssert.fs @@ -322,7 +322,7 @@ module rec CompilerAssertHelpers = else entryPoint let args = mkDefaultArgs entryPoint - captureConsoleOutputs (fun () -> entryPoint.Invoke(Unchecked.defaultof, args) |> ignore) + captureConsoleOutputs (fun () -> entryPoint.Invoke(Unchecked.defaultof, args)) #if NETCOREAPP let executeBuiltApp assembly deps isFsx = @@ -409,8 +409,8 @@ module rec CompilerAssertHelpers = // Generate a response file, purely for diagnostic reasons. File.WriteAllLines(Path.ChangeExtension(outputFilePath, ".rsp"), args) - let errors, rc = checker.Compile args |> Async.RunImmediate - errors, rc, outputFilePath + let errors, ex = checker.Compile args |> Async.RunImmediate + errors, ex, outputFilePath let compileDisposable (outputDirectory:DirectoryInfo) isExe options targetFramework nameOpt (sources:SourceCodeFileKind list) = let disposeFile path = @@ -537,7 +537,7 @@ module rec CompilerAssertHelpers = let tmp = Path.Combine(outputPath.FullName, Path.ChangeExtension(fileName, ".dll")) disposals.Add({ new IDisposable with member _.Dispose() = File.Delete tmp }) cmpl.EmitAsFile tmp - (([||], 0, tmp), []), false) + (([||], None, tmp), []), false) let compilationRefs = compiledRefs @@ -559,7 +559,7 @@ module rec CompilerAssertHelpers = compilationRefs, deps - let compileCompilationAux outputDirectory (disposals: ResizeArray) ignoreWarnings (cmpl: Compilation) : (FSharpDiagnostic[] * int * string) * string list = + let compileCompilationAux outputDirectory (disposals: ResizeArray) ignoreWarnings (cmpl: Compilation) : (FSharpDiagnostic[] * exn option * string) * string list = let compilationRefs, deps = evaluateReferences outputDirectory disposals ignoreWarnings cmpl let isExe, sources, options, targetFramework, name = @@ -604,7 +604,7 @@ module rec CompilerAssertHelpers = outputDirectory.Create() compileCompilationAux outputDirectory (ResizeArray()) ignoreWarnings cmpl - let captureConsoleOutputs (func: unit -> unit) = + let captureConsoleOutputs (func: unit -> obj) = let out = Console.Out let err = Console.Error @@ -614,29 +614,30 @@ module rec CompilerAssertHelpers = use outWriter = new StringWriter (stdout) use errWriter = new StringWriter (stderr) - let succeeded, exn = + let rc, exn = try try Console.SetOut outWriter Console.SetError errWriter - func () - true, None + let rc = func() + match rc with + | :? int as rc -> Some rc, None + | _ -> None, None with e -> let errorMessage = if e.InnerException <> null then e.InnerException.ToString() else e.ToString() stderr.Append errorMessage |> ignore - false, Some e + None, Some e finally Console.SetOut out Console.SetError err outWriter.Close() errWriter.Close() - succeeded, stdout.ToString(), stderr.ToString(), exn + rc, stdout.ToString(), stderr.ToString(), exn - let executeBuiltAppAndReturnResult (outputFilePath: string) (deps: string list) isFsx : (int * string * string) = - let succeeded, stdout, stderr, _ = executeBuiltApp outputFilePath deps isFsx - let exitCode = if succeeded then 0 else -1 - exitCode, stdout, stderr + let executeBuiltAppAndReturnResult (outputFilePath: string) (deps: string list) isFsx : (int option * string * string * exn option) = + let rc, stdout, stderr, exn = executeBuiltApp outputFilePath deps isFsx + rc, stdout, stderr, exn let executeBuiltAppNewProcessAndReturnResult (outputFilePath: string) : (int * string * string) = #if !NETCOREAPP @@ -663,7 +664,7 @@ module rec CompilerAssertHelpers = member _.Dispose() = try File.Delete runtimeconfigPath with | _ -> () } #endif let timeout = 30000 - let exitCode, output, errors = Commands.executeProcess (Some fileName) arguments (Path.GetDirectoryName(outputFilePath)) timeout + let exitCode, output, errors = Commands.executeProcess fileName arguments (Path.GetDirectoryName(outputFilePath)) timeout (exitCode, output |> String.concat "\n", errors |> String.concat "\n") open CompilerAssertHelpers @@ -677,7 +678,7 @@ type CompilerAssert private () = if errors.Length > 0 then Assert.Fail (sprintf "Compile had warnings and/or errors: %A" errors) - executeBuiltApp outputExe [] false |> ignore + executeBuiltApp outputExe [] false |> ignore ) static let compileLibraryAndVerifyILWithOptions options (source: SourceCodeFileKind) (f: ILVerifier -> unit) = @@ -739,11 +740,13 @@ Updated automatically, please check diffs in your pull request, changes must be returnCompilation cmpl (defaultArg ignoreWarnings false) static member ExecuteAndReturnResult (outputFilePath: string, isFsx: bool, deps: string list, newProcess: bool) = - // If we execute in-process (true by default), then the only way of getting STDOUT is to redirect it to SB, and STDERR is from catching an exception. if not newProcess then - executeBuiltAppAndReturnResult outputFilePath deps isFsx + let entryPointReturnCode, deps, isFsx, exn = executeBuiltAppAndReturnResult outputFilePath deps isFsx + entryPointReturnCode, deps, isFsx, exn else - executeBuiltAppNewProcessAndReturnResult outputFilePath + let processExitCode, deps, isFsx = executeBuiltAppNewProcessAndReturnResult outputFilePath + Some processExitCode, deps, isFsx, None + static member Execute(cmpl: Compilation, ?ignoreWarnings, ?beforeExecute, ?newProcess, ?onOutput) = @@ -767,7 +770,7 @@ Updated automatically, please check diffs in your pull request, changes must be Assert.Fail errors onOutput output else - let _succeeded, _stdout, _stderr, exn = executeBuiltApp outputFilePath deps false + let _rc, _stdout, _stderr, exn = executeBuiltApp outputFilePath deps false exn |> Option.iter raise) static member ExecutionHasOutput(cmpl: Compilation, expectedOutput: string) = diff --git a/tests/FSharp.Test.Utilities/ILChecker.fs b/tests/FSharp.Test.Utilities/ILChecker.fs index 4474ef01c10..de0fbd8050b 100644 --- a/tests/FSharp.Test.Utilities/ILChecker.fs +++ b/tests/FSharp.Test.Utilities/ILChecker.fs @@ -16,7 +16,7 @@ module ILChecker = let private exec exe args = let arguments = args |> String.concat " " let timeout = 30000 - let exitCode, _output, errors = Commands.executeProcess (Some exe) arguments "" timeout + let exitCode, _output, errors = Commands.executeProcess exe arguments "" timeout let errors = errors |> String.concat Environment.NewLine errors, exitCode diff --git a/tests/FSharp.Test.Utilities/Peverifier.fs b/tests/FSharp.Test.Utilities/Peverifier.fs index 35db5b208fb..f3ccc7de2b1 100644 --- a/tests/FSharp.Test.Utilities/Peverifier.fs +++ b/tests/FSharp.Test.Utilities/Peverifier.fs @@ -25,7 +25,7 @@ module PEVerifier = let private exec exe args = let arguments = args |> String.concat " " let timeout = 30000 - let exitCode, _output, errors = Commands.executeProcess (Some exe) arguments "" timeout + let exitCode, _output, errors = Commands.executeProcess exe arguments "" timeout let errors = errors |> String.concat Environment.NewLine errors, exitCode diff --git a/tests/FSharp.Test.Utilities/ProjectGeneration.fs b/tests/FSharp.Test.Utilities/ProjectGeneration.fs index 78feb049435..a75784240dd 100644 --- a/tests/FSharp.Test.Utilities/ProjectGeneration.fs +++ b/tests/FSharp.Test.Utilities/ProjectGeneration.fs @@ -1360,9 +1360,8 @@ type ProjectWorkflowBuilder yield! projectOptions.OtherOptions yield! projectOptions.SourceFiles |] - let! _diagnostics, exitCode = checker.Compile(arguments) - if exitCode <> 0 then - exn $"Compilation failed with exit code {exitCode}" |> raise + let! _diagnostics, ex = checker.Compile(arguments) + if ex.IsSome then raise ex.Value return ctx } diff --git a/tests/FSharp.Test.Utilities/TestFramework.fs b/tests/FSharp.Test.Utilities/TestFramework.fs index 6e1611beb5c..dfde63f2352 100644 --- a/tests/FSharp.Test.Utilities/TestFramework.fs +++ b/tests/FSharp.Test.Utilities/TestFramework.fs @@ -63,69 +63,66 @@ module Commands = // Execute the process pathToExe passing the arguments: arguments with the working directory: workingDir timeout after timeout milliseconds -1 = wait forever // returns exit code, stdio and stderr as string arrays let executeProcess pathToExe arguments workingDir (timeout:int) = - match pathToExe with - | Some path -> - let commandLine = ResizeArray() - let errorsList = ResizeArray() - let outputList = ResizeArray() - let errorslock = obj() - let outputlock = obj() - let outputDataReceived (message: string) = - if not (isNull message) then - lock outputlock (fun () -> outputList.Add(message)) - - let errorDataReceived (message: string) = - if not (isNull message) then - lock errorslock (fun () -> errorsList.Add(message)) - - commandLine.Add $"cd {workingDir}" - commandLine.Add $"{path} {arguments} /bl" - - let psi = ProcessStartInfo() - psi.FileName <- path - psi.WorkingDirectory <- workingDir - psi.RedirectStandardOutput <- true - psi.RedirectStandardError <- true - psi.Arguments <- arguments - psi.CreateNoWindow <- true - // When running tests, we want to roll forward to minor versions (including previews). - psi.EnvironmentVariables["DOTNET_ROLL_FORWARD"] <- "LatestMajor" - psi.EnvironmentVariables["DOTNET_ROLL_FORWARD_TO_PRERELEASE"] <- "1" - psi.EnvironmentVariables.Remove("MSBuildSDKsPath") // Host can sometimes add this, and it can break things - psi.UseShellExecute <- false - - use p = new Process() - p.StartInfo <- psi - - p.OutputDataReceived.Add(fun a -> outputDataReceived a.Data) - p.ErrorDataReceived.Add(fun a -> errorDataReceived a.Data) - - if p.Start() then - p.BeginOutputReadLine() - p.BeginErrorReadLine() - if not(p.WaitForExit(timeout)) then - // Timed out resolving throw a diagnostic. - raise (new TimeoutException(sprintf "Timeout executing command '%s' '%s'" (psi.FileName) (psi.Arguments))) - else - p.WaitForExit() - #if DEBUG - let workingDir' = - if workingDir = "" - then - // Assign working dir to prevent default to C:\Windows\System32 - let executionLocation = Assembly.GetExecutingAssembly().Location - Path.GetDirectoryName executionLocation - else - workingDir - - lock gate (fun () -> - File.WriteAllLines(Path.Combine(workingDir', "commandline.txt"), commandLine) - File.WriteAllLines(Path.Combine(workingDir', "StandardOutput.txt"), outputList) - File.WriteAllLines(Path.Combine(workingDir', "StandardError.txt"), errorsList) - ) - #endif - p.ExitCode, outputList.ToArray(), errorsList.ToArray() - | None -> -1, Array.empty, Array.empty + let commandLine = ResizeArray() + let errorsList = ResizeArray() + let outputList = ResizeArray() + let errorslock = obj() + let outputlock = obj() + let outputDataReceived (message: string) = + if not (isNull message) then + lock outputlock (fun () -> outputList.Add(message)) + + let errorDataReceived (message: string) = + if not (isNull message) then + lock errorslock (fun () -> errorsList.Add(message)) + + commandLine.Add $"cd {workingDir}" + commandLine.Add $"{pathToExe} {arguments} /bl" + + let psi = ProcessStartInfo() + psi.FileName <- pathToExe + psi.WorkingDirectory <- workingDir + psi.RedirectStandardOutput <- true + psi.RedirectStandardError <- true + psi.Arguments <- arguments + psi.CreateNoWindow <- true + // When running tests, we want to roll forward to minor versions (including previews). + psi.EnvironmentVariables["DOTNET_ROLL_FORWARD"] <- "LatestMajor" + psi.EnvironmentVariables["DOTNET_ROLL_FORWARD_TO_PRERELEASE"] <- "1" + psi.EnvironmentVariables.Remove("MSBuildSDKsPath") // Host can sometimes add this, and it can break things + psi.UseShellExecute <- false + + use p = new Process() + p.StartInfo <- psi + + p.OutputDataReceived.Add(fun a -> outputDataReceived a.Data) + p.ErrorDataReceived.Add(fun a -> errorDataReceived a.Data) + + if p.Start() then + p.BeginOutputReadLine() + p.BeginErrorReadLine() + if not(p.WaitForExit(timeout)) then + // Timed out resolving throw a diagnostic. + raise (new TimeoutException(sprintf "Timeout executing command '%s' '%s'" (psi.FileName) (psi.Arguments))) + else + p.WaitForExit() +#if DEBUG + let workingDir' = + if workingDir = "" + then + // Assign working dir to prevent default to C:\Windows\System32 + let executionLocation = Assembly.GetExecutingAssembly().Location + Path.GetDirectoryName executionLocation + else + workingDir + + lock gate (fun () -> + File.WriteAllLines(Path.Combine(workingDir', "commandline.txt"), commandLine) + File.WriteAllLines(Path.Combine(workingDir', "StandardOutput.txt"), outputList) + File.WriteAllLines(Path.Combine(workingDir', "StandardError.txt"), errorsList) + ) +#endif + p.ExitCode, outputList.ToArray(), errorsList.ToArray() let getfullpath workDir (path:string) = let rooted = diff --git a/tests/FSharp.Test.Utilities/Utilities.fs b/tests/FSharp.Test.Utilities/Utilities.fs index 6ed885d4e44..1a6d0ff60f8 100644 --- a/tests/FSharp.Test.Utilities/Utilities.fs +++ b/tests/FSharp.Test.Utilities/Utilities.fs @@ -245,7 +245,7 @@ let main argv = 0""" File.WriteAllText(directoryBuildTargetsFileName, directoryBuildTargets) let timeout = 120000 - let exitCode, dotnetoutput, dotneterrors = Commands.executeProcess (Some config.DotNetExe) "build" projectDirectory timeout + let exitCode, dotnetoutput, dotneterrors = Commands.executeProcess config.DotNetExe "build" projectDirectory timeout if exitCode <> 0 || errors.Length > 0 then errors <- dotneterrors diff --git a/tests/fsharp/typecheck/sigs/neg59.bsl b/tests/fsharp/typecheck/sigs/neg59.bsl index a938f0d271c..77a9c8caf46 100644 --- a/tests/fsharp/typecheck/sigs/neg59.bsl +++ b/tests/fsharp/typecheck/sigs/neg59.bsl @@ -33,9 +33,9 @@ neg59.fs(89,15,89,18): typecheck error FS3141: 'try/finally' expressions may not neg59.fs(95,15,95,18): typecheck error FS3141: 'try/finally' expressions may not be used in queries -neg59.fs(102,15,102,64): typecheck error FS3142: 'use' expressions may not be used in queries +neg59.fs(102,15,102,18): typecheck error FS3142: 'use' expressions may not be used in queries -neg59.fs(108,15,108,64): typecheck error FS3142: 'use' expressions may not be used in queries +neg59.fs(108,15,108,18): typecheck error FS3142: 'use' expressions may not be used in queries neg59.fs(113,15,113,25): typecheck error FS3140: 'while' expressions may not be used in queries diff --git a/tests/fsharp/typecheck/sigs/neg61.bsl b/tests/fsharp/typecheck/sigs/neg61.bsl index b0e6b151a2c..d7011cef5ef 100644 --- a/tests/fsharp/typecheck/sigs/neg61.bsl +++ b/tests/fsharp/typecheck/sigs/neg61.bsl @@ -57,7 +57,7 @@ neg61.fs(79,13,79,16): typecheck error FS3146: 'try/with' expressions may not be neg61.fs(86,13,86,16): typecheck error FS3141: 'try/finally' expressions may not be used in queries -neg61.fs(92,13,92,70): typecheck error FS3142: 'use' expressions may not be used in queries +neg61.fs(92,13,92,16): typecheck error FS3142: 'use' expressions may not be used in queries neg61.fs(97,13,97,17): typecheck error FS3143: 'let!', 'use!' and 'do!' expressions may not be used in queries diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingUsing.fs b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingUsing.fs index 90018a3a6a5..e83604cfdf9 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingUsing.fs +++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingUsing.fs @@ -1,6 +1,6 @@ // #Regression #Conformance #DataExpressions #ComputationExpressions // Regression test for FSHARP1.0:6149 -//This control construct may only be used if the computation expression builder defines a 'Using' method$ +//This control construct may only be used if the computation expression builder defines a 'Using' method$ type R = S of string diff --git a/tests/service/data/SyntaxTree/Binding/InlineKeywordInBinding.fs.bsl b/tests/service/data/SyntaxTree/Binding/InlineKeywordInBinding.fs.bsl index 5a7bf976186..596eb100812 100644 --- a/tests/service/data/SyntaxTree/Binding/InlineKeywordInBinding.fs.bsl +++ b/tests/service/data/SyntaxTree/Binding/InlineKeywordInBinding.fs.bsl @@ -44,11 +44,12 @@ ImplFile { LeadingKeyword = Let (3,4--3,7) InlineKeyword = Some (3,8--3,14) EqualsRange = Some (3,21--3,22) })], - Const (Unit, (4,4--4,6)), (3,4--4,6), { InKeyword = None }), - (2,11--2,16), NoneAtLet, { LeadingKeyword = Let (2,0--2,3) - InlineKeyword = Some (2,4--2,10) - EqualsRange = Some (2,17--2,18) })], - (2,0--4,6))], PreXmlDocEmpty, [], None, (2,0--5,0), - { LeadingKeyword = None })], (true, true), - { ConditionalDirectives = [] - CodeComments = [] }, set [])) + Const (Unit, (4,4--4,6)), (3,4--4,6), + { LetOrUseKeyword = (3,4--3,7) + InKeyword = None }), (2,11--2,16), NoneAtLet, + { LeadingKeyword = Let (2,0--2,3) + InlineKeyword = Some (2,4--2,10) + EqualsRange = Some (2,17--2,18) })], (2,0--4,6))], + PreXmlDocEmpty, [], None, (2,0--5,0), { LeadingKeyword = None })], + (true, true), { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Binding/RangeOfEqualSignShouldBePresentInLocalLetBinding.fs.bsl b/tests/service/data/SyntaxTree/Binding/RangeOfEqualSignShouldBePresentInLocalLetBinding.fs.bsl index 844946e66c3..e3156b5c3b5 100644 --- a/tests/service/data/SyntaxTree/Binding/RangeOfEqualSignShouldBePresentInLocalLetBinding.fs.bsl +++ b/tests/service/data/SyntaxTree/Binding/RangeOfEqualSignShouldBePresentInLocalLetBinding.fs.bsl @@ -20,8 +20,9 @@ ImplFile Yes (3,4--3,13), { LeadingKeyword = Let (3,4--3,7) InlineKeyword = None EqualsRange = Some (3,10--3,11) })], - Const (Unit, (4,4--4,6)), (3,4--4,6), { InKeyword = None }), - (2,0--4,6)), (2,0--4,6))], PreXmlDocEmpty, [], None, (2,0--5,0), - { LeadingKeyword = None })], (true, true), - { ConditionalDirectives = [] - CodeComments = [] }, set [])) + Const (Unit, (4,4--4,6)), (3,4--4,6), + { LetOrUseKeyword = (3,4--3,7) + InKeyword = None }), (2,0--4,6)), (2,0--4,6))], + PreXmlDocEmpty, [], None, (2,0--5,0), { LeadingKeyword = None })], + (true, true), { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Binding/RangeOfEqualSignShouldBePresentInLocalLetBindingTyped.fs.bsl b/tests/service/data/SyntaxTree/Binding/RangeOfEqualSignShouldBePresentInLocalLetBindingTyped.fs.bsl index b0e567ed3bd..93dabea4c82 100644 --- a/tests/service/data/SyntaxTree/Binding/RangeOfEqualSignShouldBePresentInLocalLetBindingTyped.fs.bsl +++ b/tests/service/data/SyntaxTree/Binding/RangeOfEqualSignShouldBePresentInLocalLetBindingTyped.fs.bsl @@ -30,8 +30,9 @@ ImplFile { LeadingKeyword = Let (3,4--3,7) InlineKeyword = None EqualsRange = Some (3,15--3,16) })], - Const (Unit, (4,4--4,6)), (3,4--4,6), { InKeyword = None }), - (2,0--4,6)), (2,0--4,6))], PreXmlDocEmpty, [], None, (2,0--5,0), - { LeadingKeyword = None })], (true, true), - { ConditionalDirectives = [] - CodeComments = [] }, set [])) + Const (Unit, (4,4--4,6)), (3,4--4,6), + { LetOrUseKeyword = (3,4--3,7) + InKeyword = None }), (2,0--4,6)), (2,0--4,6))], + PreXmlDocEmpty, [], None, (2,0--5,0), { LeadingKeyword = None })], + (true, true), { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Binding/RangeOfLetKeywordShouldBePresentInSynExprLetOrUseBinding.fs.bsl b/tests/service/data/SyntaxTree/Binding/RangeOfLetKeywordShouldBePresentInSynExprLetOrUseBinding.fs.bsl index 31febede5b6..86775dec80c 100644 --- a/tests/service/data/SyntaxTree/Binding/RangeOfLetKeywordShouldBePresentInSynExprLetOrUseBinding.fs.bsl +++ b/tests/service/data/SyntaxTree/Binding/RangeOfLetKeywordShouldBePresentInSynExprLetOrUseBinding.fs.bsl @@ -34,11 +34,12 @@ ImplFile NoneAtLet, { LeadingKeyword = Let (3,4--3,7) InlineKeyword = None EqualsRange = Some (3,12--3,13) })], - Const (Unit, (4,4--4,6)), (3,4--4,6), { InKeyword = None }), - (2,4--2,5), NoneAtLet, { LeadingKeyword = Let (2,0--2,3) - InlineKeyword = None - EqualsRange = Some (2,6--2,7) })], - (2,0--4,6))], PreXmlDocEmpty, [], None, (2,0--5,0), - { LeadingKeyword = None })], (true, true), - { ConditionalDirectives = [] - CodeComments = [] }, set [])) + Const (Unit, (4,4--4,6)), (3,4--4,6), + { LetOrUseKeyword = (3,4--3,7) + InKeyword = None }), (2,4--2,5), NoneAtLet, + { LeadingKeyword = Let (2,0--2,3) + InlineKeyword = None + EqualsRange = Some (2,6--2,7) })], (2,0--4,6))], + PreXmlDocEmpty, [], None, (2,0--5,0), { LeadingKeyword = None })], + (true, true), { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Expression/NestedSynExprLetOrUseContainsTheRangeOfInKeyword.fs.bsl b/tests/service/data/SyntaxTree/Expression/NestedSynExprLetOrUseContainsTheRangeOfInKeyword.fs.bsl index 132e7030303..791f6099b9e 100644 --- a/tests/service/data/SyntaxTree/Expression/NestedSynExprLetOrUseContainsTheRangeOfInKeyword.fs.bsl +++ b/tests/service/data/SyntaxTree/Expression/NestedSynExprLetOrUseContainsTheRangeOfInKeyword.fs.bsl @@ -55,8 +55,10 @@ ImplFile [Some (OriginalNotation "+")]), None, (5,6--5,7)), Ident x, (5,4--5,7)), Ident y, (5,4--5,9)), (4,4--5,9), - { InKeyword = Some (4,14--4,16) }), (3,4--5,9), - { InKeyword = Some (3,14--3,16) }), (2,4--2,8), NoneAtLet, + { LetOrUseKeyword = (4,4--4,7) + InKeyword = Some (4,14--4,16) }), (3,4--5,9), + { LetOrUseKeyword = (3,4--3,7) + InKeyword = Some (3,14--3,16) }), (2,4--2,8), NoneAtLet, { LeadingKeyword = Let (2,0--2,3) InlineKeyword = None EqualsRange = Some (2,9--2,10) })], (2,0--5,9))], diff --git a/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseContainsTheRangeOfInKeyword.fs.bsl b/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseContainsTheRangeOfInKeyword.fs.bsl index f9ce333429a..5408f5d71d1 100644 --- a/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseContainsTheRangeOfInKeyword.fs.bsl +++ b/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseContainsTheRangeOfInKeyword.fs.bsl @@ -19,7 +19,8 @@ ImplFile InlineKeyword = None EqualsRange = Some (2,6--2,7) })], Const (Unit, (2,13--2,15)), (2,0--2,15), - { InKeyword = Some (2,10--2,12) }), (2,0--2,15))], + { LetOrUseKeyword = (2,0--2,3) + InKeyword = Some (2,10--2,12) }), (2,0--2,15))], PreXmlDocEmpty, [], None, (2,0--2,15), { LeadingKeyword = None })], (true, true), { ConditionalDirectives = [] CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseDoesNotContainTheRangeOfInKeyword.fs.bsl b/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseDoesNotContainTheRangeOfInKeyword.fs.bsl index 54c3f8180e4..bb9dcafe15f 100644 --- a/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseDoesNotContainTheRangeOfInKeyword.fs.bsl +++ b/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseDoesNotContainTheRangeOfInKeyword.fs.bsl @@ -21,8 +21,9 @@ ImplFile Yes (3,0--3,9), { LeadingKeyword = Let (3,0--3,3) InlineKeyword = None EqualsRange = Some (3,6--3,7) })], - Const (Unit, (4,0--4,2)), (3,0--4,2), { InKeyword = None }), - (2,0--4,2)), (2,0--4,2))], PreXmlDocEmpty, [], None, (2,0--5,0), - { LeadingKeyword = None })], (true, true), - { ConditionalDirectives = [] - CodeComments = [] }, set [])) + Const (Unit, (4,0--4,2)), (3,0--4,2), + { LetOrUseKeyword = (3,0--3,3) + InKeyword = None }), (2,0--4,2)), (2,0--4,2))], + PreXmlDocEmpty, [], None, (2,0--5,0), { LeadingKeyword = None })], + (true, true), { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseWhereBodyExprStartsWithTokenOfTwoCharactersDoesNotContainTheRangeOfInKeyword.fs.bsl b/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseWhereBodyExprStartsWithTokenOfTwoCharactersDoesNotContainTheRangeOfInKeyword.fs.bsl index a5d102356f1..554f4eb21ef 100644 --- a/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseWhereBodyExprStartsWithTokenOfTwoCharactersDoesNotContainTheRangeOfInKeyword.fs.bsl +++ b/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseWhereBodyExprStartsWithTokenOfTwoCharactersDoesNotContainTheRangeOfInKeyword.fs.bsl @@ -40,7 +40,8 @@ ImplFile SynLongIdent ([e1; Value], [(4,10--4,11)], [None; None]), None, (4,8--4,16))], [(4,6--4,7)], (4,0--4,16)), - (3,0--4,16), { InKeyword = None }), (2,0--4,16)), + (3,0--4,16), { LetOrUseKeyword = (3,0--3,3) + InKeyword = None }), (2,0--4,16)), (2,0--4,16))], PreXmlDocEmpty, [], None, (2,0--5,0), { LeadingKeyword = None })], (true, true), { ConditionalDirectives = [] diff --git a/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseWithRecursiveBindingContainsTheRangeOfInKeyword.fs.bsl b/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseWithRecursiveBindingContainsTheRangeOfInKeyword.fs.bsl index 72352706810..8b57f33b953 100644 --- a/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseWithRecursiveBindingContainsTheRangeOfInKeyword.fs.bsl +++ b/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseWithRecursiveBindingContainsTheRangeOfInKeyword.fs.bsl @@ -35,7 +35,8 @@ ImplFile InlineKeyword = None EqualsRange = Some (4,10--4,11) })], Const (Unit, (5,4--5,6)), (3,4--5,6), - { InKeyword = Some (4,15--4,17) }), (2,0--5,6)), (2,0--5,6))], + { LetOrUseKeyword = (3,4--3,11) + InKeyword = Some (4,15--4,17) }), (2,0--5,6)), (2,0--5,6))], PreXmlDocEmpty, [], None, (2,0--6,0), { LeadingKeyword = None })], (true, true), { ConditionalDirectives = [] CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Expression/Try with - Missing expr 04.fs.bsl b/tests/service/data/SyntaxTree/Expression/Try with - Missing expr 04.fs.bsl index 94ee31ce8d1..74221e70a5f 100644 --- a/tests/service/data/SyntaxTree/Expression/Try with - Missing expr 04.fs.bsl +++ b/tests/service/data/SyntaxTree/Expression/Try with - Missing expr 04.fs.bsl @@ -19,7 +19,8 @@ ImplFile InlineKeyword = None EqualsRange = Some (5,6--5,7) })], ArbitraryAfterError ("seqExpr", (5,10--5,10)), (5,0--5,10), - { InKeyword = None }), [], (3,0--5,10), Yes (3,0--3,3), + { LetOrUseKeyword = (5,0--5,3) + InKeyword = None }), [], (3,0--5,10), Yes (3,0--3,3), Yes (5,10--5,10), { TryKeyword = (3,0--3,3) TryToWithRange = (3,0--5,10) WithKeyword = (5,10--5,10) diff --git a/tests/service/data/SyntaxTree/LeadingKeyword/UseKeyword.fs.bsl b/tests/service/data/SyntaxTree/LeadingKeyword/UseKeyword.fs.bsl index b2b3420c806..4571189344f 100644 --- a/tests/service/data/SyntaxTree/LeadingKeyword/UseKeyword.fs.bsl +++ b/tests/service/data/SyntaxTree/LeadingKeyword/UseKeyword.fs.bsl @@ -22,8 +22,9 @@ ImplFile { LeadingKeyword = Use (3,4--3,7) InlineKeyword = None EqualsRange = Some (3,10--3,11) })], - Const (Unit, (4,4--4,6)), (3,4--4,6), { InKeyword = None }), - (2,0--4,6)), (2,0--4,6))], PreXmlDocEmpty, [], None, (2,0--5,0), - { LeadingKeyword = None })], (true, true), - { ConditionalDirectives = [] - CodeComments = [] }, set [])) + Const (Unit, (4,4--4,6)), (3,4--4,6), + { LetOrUseKeyword = (3,4--3,7) + InKeyword = None }), (2,0--4,6)), (2,0--4,6))], + PreXmlDocEmpty, [], None, (2,0--5,0), { LeadingKeyword = None })], + (true, true), { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/LeadingKeyword/UseRecKeyword.fs.bsl b/tests/service/data/SyntaxTree/LeadingKeyword/UseRecKeyword.fs.bsl index 7dbbc35edd7..ac1d1ce9819 100644 --- a/tests/service/data/SyntaxTree/LeadingKeyword/UseRecKeyword.fs.bsl +++ b/tests/service/data/SyntaxTree/LeadingKeyword/UseRecKeyword.fs.bsl @@ -22,8 +22,9 @@ ImplFile { LeadingKeyword = UseRec ((3,4--3,7), (3,8--3,11)) InlineKeyword = None EqualsRange = Some (3,14--3,15) })], - Const (Unit, (4,4--4,6)), (3,4--4,6), { InKeyword = None }), - (2,0--4,6)), (2,0--4,6))], PreXmlDocEmpty, [], None, (2,0--5,0), - { LeadingKeyword = None })], (true, true), - { ConditionalDirectives = [] - CodeComments = [] }, set [])) + Const (Unit, (4,4--4,6)), (3,4--4,6), + { LetOrUseKeyword = (3,4--3,11) + InKeyword = None }), (2,0--4,6)), (2,0--4,6))], + PreXmlDocEmpty, [], None, (2,0--5,0), { LeadingKeyword = None })], + (true, true), { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/MatchClause/RangeOfMultipleSynMatchClause.fs.bsl b/tests/service/data/SyntaxTree/MatchClause/RangeOfMultipleSynMatchClause.fs.bsl index 84ce5019498..f4b3b9f7a39 100644 --- a/tests/service/data/SyntaxTree/MatchClause/RangeOfMultipleSynMatchClause.fs.bsl +++ b/tests/service/data/SyntaxTree/MatchClause/RangeOfMultipleSynMatchClause.fs.bsl @@ -25,7 +25,8 @@ ImplFile EqualsRange = Some (3,16--3,17) })], App (NonAtomic, false, Ident Some, Ident content, (4,4--4,16)), - (3,4--4,16), { InKeyword = None }), + (3,4--4,16), { LetOrUseKeyword = (3,4--3,7) + InKeyword = None }), [SynMatchClause (Named (SynIdent (ex, None), false, None, (6,2--6,4)), None, Sequential diff --git a/tests/service/data/SyntaxTree/MatchClause/RangeOfSingleSynMatchClause.fs.bsl b/tests/service/data/SyntaxTree/MatchClause/RangeOfSingleSynMatchClause.fs.bsl index dfa2ad58587..324463e7b2e 100644 --- a/tests/service/data/SyntaxTree/MatchClause/RangeOfSingleSynMatchClause.fs.bsl +++ b/tests/service/data/SyntaxTree/MatchClause/RangeOfSingleSynMatchClause.fs.bsl @@ -25,7 +25,8 @@ ImplFile EqualsRange = Some (3,16--3,17) })], App (NonAtomic, false, Ident Some, Ident content, (4,4--4,16)), - (3,4--4,16), { InKeyword = None }), + (3,4--4,16), { LetOrUseKeyword = (3,4--3,7) + InKeyword = None }), [SynMatchClause (Named (SynIdent (ex, None), false, None, (5,5--5,7)), None, Sequential diff --git a/tests/service/data/SyntaxTree/MatchClause/RangeOfSingleSynMatchClauseFollowedByBar.fs.bsl b/tests/service/data/SyntaxTree/MatchClause/RangeOfSingleSynMatchClauseFollowedByBar.fs.bsl index ea10cf70558..132cbd01cc0 100644 --- a/tests/service/data/SyntaxTree/MatchClause/RangeOfSingleSynMatchClauseFollowedByBar.fs.bsl +++ b/tests/service/data/SyntaxTree/MatchClause/RangeOfSingleSynMatchClauseFollowedByBar.fs.bsl @@ -25,7 +25,8 @@ ImplFile EqualsRange = Some (3,16--3,17) })], App (NonAtomic, false, Ident Some, Ident content, (4,4--4,16)), - (3,4--4,16), { InKeyword = None }), + (3,4--4,16), { LetOrUseKeyword = (3,4--3,7) + InKeyword = None }), [SynMatchClause (Named (SynIdent (ex, None), false, None, (6,2--6,4)), None, Const (Unit, (7,4--7,6)), (6,2--7,6), Yes, 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 54749497087..7bd27b958c6 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 @@ -30,7 +30,8 @@ ImplFile InlineKeyword = None EqualsRange = None })], ArbitraryAfterError ("seqExpr", (4,10--4,10)), - (4,4--4,10), { InKeyword = None }), (4,4--4,10)), + (4,4--4,10), { LetOrUseKeyword = (4,4--4,7) + InKeyword = None }), (4,4--4,10)), (3,0--4,10)), (3,0--4,10))], PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, (1,0--4,10), { LeadingKeyword = Module (1,0--1,6) })], (true, true), 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 55a07b60288..6120ff4f5fd 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 @@ -26,8 +26,9 @@ ImplFile { LeadingKeyword = Let (4,4--4,7) InlineKeyword = None EqualsRange = Some (4,11--4,12) })], - Const (Unit, (6,4--6,6)), (4,4--6,6), { InKeyword = None }), - (3,0--6,6)), (3,0--6,6))], + Const (Unit, (6,4--6,6)), (4,4--6,6), + { LetOrUseKeyword = (4,4--4,7) + InKeyword = None }), (3,0--6,6)), (3,0--6,6))], PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, (1,0--6,6), { LeadingKeyword = Module (1,0--1,6) })], (true, true), { ConditionalDirectives = [] diff --git a/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 09.fs.bsl b/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 09.fs.bsl index 89a4af5ce5c..0f2e4604d2b 100644 --- a/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 09.fs.bsl +++ b/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 09.fs.bsl @@ -25,7 +25,8 @@ ImplFile { LeadingKeyword = Let (4,4--4,7) InlineKeyword = None EqualsRange = None })], Const (Unit, (6,4--6,6)), - (4,4--6,6), { InKeyword = None }), (3,0--6,6)), (3,0--6,6))], + (4,4--6,6), { LetOrUseKeyword = (4,4--4,7) + InKeyword = None }), (3,0--6,6)), (3,0--6,6))], PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, (1,0--6,6), { LeadingKeyword = Module (1,0--1,6) })], (true, true), { ConditionalDirectives = [] diff --git a/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 10.fs.bsl b/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 10.fs.bsl index f3fa83db96a..5e8ab0f26fd 100644 --- a/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 10.fs.bsl +++ b/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 10.fs.bsl @@ -24,8 +24,9 @@ ImplFile { LeadingKeyword = Let (4,4--4,7) InlineKeyword = None EqualsRange = Some (4,13--4,14) })], - Const (Unit, (6,4--6,6)), (4,4--6,6), { InKeyword = None }), - (3,0--6,6)), (3,0--6,6))], + Const (Unit, (6,4--6,6)), (4,4--6,6), + { LetOrUseKeyword = (4,4--4,7) + InKeyword = None }), (3,0--6,6)), (3,0--6,6))], PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, (1,0--6,6), { LeadingKeyword = Module (1,0--1,6) })], (true, true), { ConditionalDirectives = [] diff --git a/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 11.fs.bsl b/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 11.fs.bsl index e89431a48e0..dbf43bcf3b1 100644 --- a/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 11.fs.bsl +++ b/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 11.fs.bsl @@ -30,8 +30,9 @@ ImplFile { LeadingKeyword = Let (4,4--4,7) InlineKeyword = None EqualsRange = Some (4,15--4,16) })], - Const (Unit, (6,4--6,6)), (4,4--6,6), { InKeyword = None }), - (3,0--6,6)), (3,0--6,6))], + Const (Unit, (6,4--6,6)), (4,4--6,6), + { LetOrUseKeyword = (4,4--4,7) + InKeyword = None }), (3,0--6,6)), (3,0--6,6))], PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, (1,0--6,6), { LeadingKeyword = Module (1,0--1,6) })], (true, true), { ConditionalDirectives = [] diff --git a/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 12.fs.bsl b/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 12.fs.bsl index 97ad7191e25..416dc67c859 100644 --- a/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 12.fs.bsl +++ b/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 12.fs.bsl @@ -38,8 +38,9 @@ ImplFile { LeadingKeyword = Let (4,4--4,7) InlineKeyword = None EqualsRange = Some (4,18--4,19) })], - Const (Unit, (6,4--6,6)), (4,4--6,6), { InKeyword = None }), - (3,0--6,6)), (3,0--6,6))], + Const (Unit, (6,4--6,6)), (4,4--6,6), + { LetOrUseKeyword = (4,4--4,7) + InKeyword = None }), (3,0--6,6)), (3,0--6,6))], PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, (1,0--6,6), { LeadingKeyword = Module (1,0--1,6) })], (true, true), { ConditionalDirectives = [] diff --git a/tests/service/data/SyntaxTree/String/InterpolatedStringOffsideInNestedLet.fs.bsl b/tests/service/data/SyntaxTree/String/InterpolatedStringOffsideInNestedLet.fs.bsl index d91bffd331d..1dfe5586b56 100644 --- a/tests/service/data/SyntaxTree/String/InterpolatedStringOffsideInNestedLet.fs.bsl +++ b/tests/service/data/SyntaxTree/String/InterpolatedStringOffsideInNestedLet.fs.bsl @@ -31,7 +31,8 @@ ImplFile { LeadingKeyword = Let (2,4--2,7) InlineKeyword = None EqualsRange = Some (2,10--2,11) })], Ident b, - (2,4--5,5), { InKeyword = None }), (1,4--1,5), NoneAtLet, + (2,4--5,5), { LetOrUseKeyword = (2,4--2,7) + InKeyword = None }), (1,4--1,5), NoneAtLet, { LeadingKeyword = Let (1,0--1,3) InlineKeyword = None EqualsRange = Some (1,6--1,7) })], (1,0--5,5))],