Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/Compiler/Driver/CompilerOptions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1308,6 +1308,13 @@ let advancedFlagsFsi tcConfigB =
None,
Some(FSComp.SR.optsClearResultsCache ())
)
CompilerOption(
Comment thread
T-Gro marked this conversation as resolved.
"typecheck-only",
tagNone,
OptionUnit(fun () -> tcConfigB.typeCheckOnly <- true),
None,
Some(FSComp.SR.optsTypecheckOnly ())
)
]

let advancedFlagsFsc tcConfigB =
Expand Down
1 change: 1 addition & 0 deletions src/Compiler/FSComp.txt
Original file line number Diff line number Diff line change
Expand Up @@ -902,6 +902,7 @@ optsVersion,"Display compiler version banner and exit"
optsResponseFile,"Read response file for more options"
optsCodepage,"Specify the codepage used to read source files"
optsClearResultsCache,"Clear the package manager results cache"
optsTypecheckOnly,"Perform type checking only, do not execute code"
optsUtf8output,"Output messages in UTF-8 encoding"
optsFullpaths,"Output messages with fully qualified paths"
optsLib,"Specify a directory for the include path which is used to resolve source files and assemblies (Short form: -I)"
Expand Down
4 changes: 4 additions & 0 deletions src/Compiler/Interactive/fsi.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2217,6 +2217,10 @@ type internal FsiDynamicCompiler
inputs
))

// Add this check after CheckClosedInputSet
if tcConfig.typeCheckOnly then
raise StopProcessing

let codegenResults, optEnv, fragName =
ProcessTypedImpl(
diagnosticsLogger,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@
<Compile Include="Interop\ParamArray.fs" />
<Compile Include="Interop\Literals.fs" />
<Compile Include="Scripting\Interactive.fs" />
<Compile Include="Scripting\TypeCheckOnlyTests.fs" />
<Compile Include="TypeChecks\SeqTypeCheckTests.fs" />
<Compile Include="TypeChecks\CheckDeclarationsTests.fs" />
<Compile Include="TypeChecks\Graph\Utils.fs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
module FSharp.Compiler.ComponentTests.Scripting.TypeCheckOnlyTests

open Xunit
open FSharp.Test
open FSharp.Test.Compiler

[<Fact>]
let ``typecheck-only flag works for valid script``() =
Fsx """
let x = 42
printfn "This should not execute"
"""
|> withOptions ["--typecheck-only"]
|> compile
|> shouldSucceed

[<Fact>]
let ``typecheck-only flag catches type errors``() =
Fsx """
let x: int = "string" // Type error
"""
|> withOptions ["--typecheck-only"]
|> compile
|> shouldFail
|> withDiagnostics [
(Error 1, Line 2, Col 14, Line 2, Col 22, "This expression was expected to have type\n 'int' \nbut here has type\n 'string'")
]

[<Fact>]
let ``typecheck-only flag prevents execution side effects``() =
Fsx """
printfn "MyCrazyString"
let x = 42
"""
|> withOptions ["--typecheck-only"]
|> runFsi
|> shouldSucceed
|> VerifyNotInOutput "MyCrazyString"

[<Fact>]
let ``script executes without typecheck-only flag``() =
Fsx """
printfn "MyCrazyString"
let x = 42
"""
|> runFsi
|> shouldSucceed
|> verifyOutput "MyCrazyString"
19 changes: 19 additions & 0 deletions tests/FSharp.Test.Utilities/Compiler.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1425,6 +1425,18 @@
failwith $"""Output does not match expected:{Environment.NewLine}{item}{Environment.NewLine}Actual:{Environment.NewLine}{actual}{Environment.NewLine}"""
cResult
Comment thread
T-Gro marked this conversation as resolved.

let verifyNotInOutput (expected: string) (cResult: CompilationResult) : CompilationResult =
match getOutput cResult with
| None -> cResult
| Some actual ->
if actual.Contains(expected) then
failwith $"""Output should not contain:{Environment.NewLine}{expected}{Environment.NewLine}Actual:{Environment.NewLine}{actual}{Environment.NewLine}"""
else
cResult

let VerifyNotInOutput (expected: string) (cResult: CompilationResult) : CompilationResult =
verifyNotInOutput expected cResult

type ImportScope = { Kind: ImportDefinitionKind; Name: string }

type PdbVerificationOption =
Expand Down Expand Up @@ -1910,6 +1922,13 @@
let withStdOutContains (substring: string) (result: CompilationResult) : CompilationResult =
checkOutputInOrder "STDOUT" [substring] (fun o -> o.StdOut) result

let withStdOutNotContains (substring: string) (result: CompilationResult) : CompilationResult =
let checkOutput = fun o -> o.StdOut
let output = checkOutput result.Output

Check failure on line 1927 in tests/FSharp.Test.Utilities/Compiler.fs

View workflow job for this annotation

GitHub Actions / copilot

Type constraint mismatch. The type � 'CompilationOutput' �is not compatible with type� 'EvalOutput'

Check failure on line 1927 in tests/FSharp.Test.Utilities/Compiler.fs

View workflow job for this annotation

GitHub Actions / copilot

Type constraint mismatch. The type � 'CompilationOutput' �is not compatible with type� 'EvalOutput'
if output.Contains(substring) then
failwith $"""STDOUT should not contain:{Environment.NewLine}{substring}{Environment.NewLine}Actual:{Environment.NewLine}{output}{Environment.NewLine}"""
result

let withStdOutContainsAllInOrder (substrings: string list) (result: CompilationResult) : CompilationResult =
checkOutputInOrder "STDOUT" substrings (fun o -> o.StdOut) result

Expand Down
Loading