diff --git a/src/Compiler/Driver/CompilerOptions.fs b/src/Compiler/Driver/CompilerOptions.fs index cdeda6b6566..4dd36dec6bd 100644 --- a/src/Compiler/Driver/CompilerOptions.fs +++ b/src/Compiler/Driver/CompilerOptions.fs @@ -1308,6 +1308,13 @@ let advancedFlagsFsi tcConfigB = None, Some(FSComp.SR.optsClearResultsCache ()) ) + CompilerOption( + "typecheck-only", + tagNone, + OptionUnit(fun () -> tcConfigB.typeCheckOnly <- true), + None, + Some(FSComp.SR.optsTypecheckOnly ()) + ) ] let advancedFlagsFsc tcConfigB = diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index f259f06cac0..6a243373521 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -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)" diff --git a/src/Compiler/Interactive/fsi.fs b/src/Compiler/Interactive/fsi.fs index 662ba9752e7..cbe606b648c 100644 --- a/src/Compiler/Interactive/fsi.fs +++ b/src/Compiler/Interactive/fsi.fs @@ -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, diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index bb56261f125..1b8318e124e 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -1057,6 +1057,11 @@ Podporované jazykové verze: + + Perform type checking only, do not execute code + Perform type checking only, do not execute code + + Invalid value '{0}' for --optimizationdata, valid value are: none, file, compress. Neplatná hodnota '{0}' pro --optimizationdata, platná hodnota: none, file, compress. diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index 7b8d6567c1c..b1045b18823 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -1057,6 +1057,11 @@ Unterstützte Sprachversionen: + + Perform type checking only, do not execute code + Perform type checking only, do not execute code + + Invalid value '{0}' for --optimizationdata, valid value are: none, file, compress. Ungültiger Wert „{0}“ für --optimizationdata. Gültige Werte sind: none, file, compress. diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index 8a0ac83a342..c76e6d0bcac 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -1057,6 +1057,11 @@ Versiones de lenguaje admitidas: + + Perform type checking only, do not execute code + Perform type checking only, do not execute code + + Invalid value '{0}' for --optimizationdata, valid value are: none, file, compress. Valor no válido '{0}' para --optimizationdata; los valores válidos son: none, file, compress. diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index 621813988a3..aa49f56b951 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -1057,6 +1057,11 @@ Versions linguistiques prises en charge : + + Perform type checking only, do not execute code + Perform type checking only, do not execute code + + Invalid value '{0}' for --optimizationdata, valid value are: none, file, compress. Valeur non valide '{0}' pour --optimizationdata. Les valeurs valides sont : none, file, compress. diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index 76294e7ac7f..89dacdf42ac 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -1057,6 +1057,11 @@ Versioni del linguaggio supportate: + + Perform type checking only, do not execute code + Perform type checking only, do not execute code + + Invalid value '{0}' for --optimizationdata, valid value are: none, file, compress. Valore non valido '{0}' per --optimizationdata. Valori validi sono: none, file, compress. diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index cf31f12757e..42955cb462b 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -1057,6 +1057,11 @@ サポートされる言語バージョン: + + Perform type checking only, do not execute code + Perform type checking only, do not execute code + + Invalid value '{0}' for --optimizationdata, valid value are: none, file, compress. --optimizationdata の値 '{0}' が無効です。有効な値は none、file、compress です。 diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index 70f312b88cd..56628072e04 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -1057,6 +1057,11 @@ 지원되는 언어 버전: + + Perform type checking only, do not execute code + Perform type checking only, do not execute code + + Invalid value '{0}' for --optimizationdata, valid value are: none, file, compress. --optimizationdata에 대한 '{0}' 값이 잘못되었습니다. 올바른 값은 none, file, compress입니다. diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index 5cb379287e1..4cee71af6e0 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -1057,6 +1057,11 @@ Obsługiwane wersje językowe: + + Perform type checking only, do not execute code + Perform type checking only, do not execute code + + Invalid value '{0}' for --optimizationdata, valid value are: none, file, compress. Nieprawidłowa wartość „{0}” dla parametru --optimizationdata, prawidłowa wartość to: none, file, compress. diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index 8f67095285e..44685a5bf83 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -1057,6 +1057,11 @@ Versões de linguagens com suporte: + + Perform type checking only, do not execute code + Perform type checking only, do not execute code + + Invalid value '{0}' for --optimizationdata, valid value are: none, file, compress. Valor inválido '{0}' para --optimizationdata, o valor válido é: none, file, compact. diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index 19de2b0d1a9..c9056c01054 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -1057,6 +1057,11 @@ Поддерживаемые языковые версии: + + Perform type checking only, do not execute code + Perform type checking only, do not execute code + + Invalid value '{0}' for --optimizationdata, valid value are: none, file, compress. Недопустимое значение "{0}" для --optimizationdata. Допустимые значения: none, file, compress. diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index eb357aaa843..e39ae57407c 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -1057,6 +1057,11 @@ Desteklenen dil sürümleri: + + Perform type checking only, do not execute code + Perform type checking only, do not execute code + + Invalid value '{0}' for --optimizationdata, valid value are: none, file, compress. --optimizationdata için geçersiz '{0}' değeri, geçerli değerler: none, file, compress. diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index 256302b235e..08d5772f30d 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -1057,6 +1057,11 @@ 支持的语言版本: + + Perform type checking only, do not execute code + Perform type checking only, do not execute code + + Invalid value '{0}' for --optimizationdata, valid value are: none, file, compress. --optimizationdata 的值 "{0}" 无效,有效值为: none、file、compress。 diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index 674e3ee9c45..4e6690ce1fe 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -1057,6 +1057,11 @@ 支援的語言版本: + + Perform type checking only, do not execute code + Perform type checking only, do not execute code + + Invalid value '{0}' for --optimizationdata, valid value are: none, file, compress. --optimizationdata 的 '{0}' 值無效,有效值為: none、file、compress。 diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj index f0cb13ea71e..9618f9cbcee 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj +++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj @@ -273,6 +273,7 @@ + diff --git a/tests/FSharp.Compiler.ComponentTests/Scripting/TypeCheckOnlyTests.fs b/tests/FSharp.Compiler.ComponentTests/Scripting/TypeCheckOnlyTests.fs new file mode 100644 index 00000000000..db02316bb94 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Scripting/TypeCheckOnlyTests.fs @@ -0,0 +1,48 @@ +module FSharp.Compiler.ComponentTests.Scripting.TypeCheckOnlyTests + +open Xunit +open FSharp.Test +open FSharp.Test.Compiler + +[] +let ``typecheck-only flag works for valid script``() = + Fsx """ +let x = 42 +printfn "This should not execute" +""" + |> withOptions ["--typecheck-only"] + |> compile + |> shouldSucceed + +[] +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'") + ] + +[] +let ``typecheck-only flag prevents execution side effects``() = + Fsx """ +printfn "MyCrazyString" +let x = 42 +""" + |> withOptions ["--typecheck-only"] + |> runFsi + |> shouldSucceed + |> verifyNotInOutput "MyCrazyString" + +[] +let ``script executes without typecheck-only flag``() = + Fsx """ +printfn "MyCrazyString" +let x = 42 +""" + |> runFsi + |> shouldSucceed + |> verifyOutput "MyCrazyString" \ No newline at end of file diff --git a/tests/FSharp.Test.Utilities/Compiler.fs b/tests/FSharp.Test.Utilities/Compiler.fs index d3ee5394866..dc7c75bc819 100644 --- a/tests/FSharp.Test.Utilities/Compiler.fs +++ b/tests/FSharp.Test.Utilities/Compiler.fs @@ -1425,6 +1425,15 @@ Actual: failwith $"""Output does not match expected:{Environment.NewLine}{item}{Environment.NewLine}Actual:{Environment.NewLine}{actual}{Environment.NewLine}""" cResult + 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 + type ImportScope = { Kind: ImportDefinitionKind; Name: string } type PdbVerificationOption =