diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index 118e6891389..93003652a8e 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -353,21 +353,18 @@ stages:
- script: .\tests\EndToEndBuildTests\EndToEndBuildTests.cmd -c Release
displayName: End to end build tests
- # Determinism
+ # Determinism, we want to run it only in PR builds
- job: Determinism_Debug
+ condition: eq(variables['Build.Reason'], 'PullRequest')
+ variables:
+ - name: _SignType
+ value: Test
pool:
- name: NetCore1ESPool-Public
- demands: ImageOverride -equals Build.Windows.Amd64.VS2022.Pre.Open
+ vmImage: windows-latest
timeoutInMinutes: 90
steps:
- - checkout: none
- - script: |
- @echo on
- git init
- git remote add origin "$(Build.Repository.Uri)"
- git fetch --progress --no-tags --depth=1 origin "$(Build.SourceVersion)"
- git checkout "$(Build.SourceVersion)"
- displayName: Shallow checkout
+ - checkout: self
+ clean: true
- script: .\eng\test-determinism.cmd -configuration Debug
displayName: Determinism tests with Debug configuration
- task: PublishPipelineArtifact@1
diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index 929f04667ef..08bcbebd47d 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -8,9 +8,9 @@
-
+ https://github.com/dotnet/arcade
- 97463777ee9a8445d4a4c5911ede0f0cd71fa8aa
+ 5d969787afb2fd87f642458687e3ad41094ac3ab
diff --git a/eng/build-utils.ps1 b/eng/build-utils.ps1
index ffc4498fb85..055ddb7a5b6 100644
--- a/eng/build-utils.ps1
+++ b/eng/build-utils.ps1
@@ -247,7 +247,7 @@ function Make-BootstrapBuild() {
$args = "build $buildToolsProject -c $bootstrapConfiguration -v $verbosity" + $argNoRestore + $argNoIncremental
if ($binaryLog) {
$logFilePath = Join-Path $LogDir "toolsBootstrapLog.binlog"
- $args += " /bl:$logFilePath"
+ $args += " /bl:`"$logFilePath`""
}
Exec-Console $dotnetExe $args
@@ -260,7 +260,7 @@ function Make-BootstrapBuild() {
$args = "build $protoProject -c $bootstrapConfiguration -v $verbosity -f $bootstrapTfm" + $argNoRestore + $argNoIncremental
if ($binaryLog) {
$logFilePath = Join-Path $LogDir "protoBootstrapLog.binlog"
- $args += " /bl:$logFilePath"
+ $args += " /bl:`"$logFilePath`""
}
Exec-Console $dotnetExe $args
diff --git a/eng/common/build.sh b/eng/common/build.sh
index bc07a1c6848..55b298f16cc 100755
--- a/eng/common/build.sh
+++ b/eng/common/build.sh
@@ -187,10 +187,6 @@ function InitializeCustomToolset {
}
function Build {
-
- if [[ "$ci" == true ]]; then
- TryLogClientIpAddress
- fi
InitializeToolset
InitializeCustomToolset
diff --git a/eng/common/native/init-compiler.sh b/eng/common/native/init-compiler.sh
index 8c944f30b28..e361e03fabd 100644
--- a/eng/common/native/init-compiler.sh
+++ b/eng/common/native/init-compiler.sh
@@ -2,6 +2,7 @@
#
# This file detects the C/C++ compiler and exports it to the CC/CXX environment variables
#
+# NOTE: some scripts source this file and rely on stdout being empty, make sure to not output anything here!
if [[ "$#" -lt 3 ]]; then
echo "Usage..."
@@ -111,12 +112,10 @@ if [[ -z "$CC" ]]; then
exit 1
fi
-if [[ "$compiler" == "clang" ]]; then
- if command -v "lld$desired_version" > /dev/null; then
- # Only lld version >= 9 can be considered stable
- if [[ "$majorVersion" -ge 9 ]]; then
- LDFLAGS="-fuse-ld=lld"
- fi
+# Only lld version >= 9 can be considered stable
+if [[ "$compiler" == "clang" && "$majorVersion" -ge 9 ]]; then
+ if "$CC" -fuse-ld=lld -Wl,--version >/dev/null 2>&1; then
+ LDFLAGS="-fuse-ld=lld"
fi
fi
diff --git a/eng/common/sdk-task.ps1 b/eng/common/sdk-task.ps1
index 7ab9baac5c8..b1bca63ab1d 100644
--- a/eng/common/sdk-task.ps1
+++ b/eng/common/sdk-task.ps1
@@ -83,9 +83,6 @@ try {
}
if ($restore) {
- if ($ci) {
- Try-LogClientIpAddress
- }
Build 'Restore'
}
diff --git a/eng/common/sdl/packages.config b/eng/common/sdl/packages.config
index 3bd8b29ebd7..4585cfd6bba 100644
--- a/eng/common/sdl/packages.config
+++ b/eng/common/sdl/packages.config
@@ -1,4 +1,4 @@
-
+
diff --git a/eng/common/templates/job/execute-sdl.yml b/eng/common/templates/job/execute-sdl.yml
index 3aafc82e417..8128f2c3570 100644
--- a/eng/common/templates/job/execute-sdl.yml
+++ b/eng/common/templates/job/execute-sdl.yml
@@ -54,7 +54,7 @@ jobs:
# The Guardian version specified in 'eng/common/sdl/packages.config'. This value must be kept in
# sync with the packages.config file.
- name: DefaultGuardianVersion
- value: 0.53.3
+ value: 0.109.0
- name: GuardianVersion
value: ${{ coalesce(parameters.overrideGuardianVersion, '$(DefaultGuardianVersion)') }}
- name: GuardianPackagesConfigFile
diff --git a/eng/common/templates/job/job.yml b/eng/common/templates/job/job.yml
index 37dceb1bab0..7678b94ce74 100644
--- a/eng/common/templates/job/job.yml
+++ b/eng/common/templates/job/job.yml
@@ -114,6 +114,7 @@ jobs:
continueOnError: ${{ parameters.continueOnError }}
condition: and(succeeded(), in(variables['_SignType'], 'real', 'test'), eq(variables['Agent.Os'], 'Windows_NT'))
+ - ${{ if and(eq(parameters.runAsPublic, 'false'), eq(variables['System.TeamProject'], 'internal')) }}:
- task: NuGetAuthenticate@0
- ${{ if or(eq(parameters.artifacts.download, 'true'), ne(parameters.artifacts.download, '')) }}:
diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1
index 90b1f9fdcdb..f1e1cb53953 100644
--- a/eng/common/tools.ps1
+++ b/eng/common/tools.ps1
@@ -163,9 +163,6 @@ function InitializeDotNetCli([bool]$install, [bool]$createSdkLocationFile) {
# Disable telemetry on CI.
if ($ci) {
$env:DOTNET_CLI_TELEMETRY_OPTOUT=1
-
- # In case of network error, try to log the current IP for reference
- Try-LogClientIpAddress
}
# Source Build uses DotNetCoreSdkDir variable
@@ -895,24 +892,6 @@ if (!$disableConfigureToolsetImport) {
}
}
-function Try-LogClientIpAddress()
-{
- Write-Host "Attempting to log this client's IP for Azure Package feed telemetry purposes"
- try
- {
- $result = Invoke-WebRequest -Uri "http://co1r5a.msedge.net/fdv2/diagnostics.aspx" -UseBasicParsing
- $lines = $result.Content.Split([Environment]::NewLine)
- $socketIp = $lines | Select-String -Pattern "^Socket IP:.*"
- Write-Host $socketIp
- $clientIp = $lines | Select-String -Pattern "^Client IP:.*"
- Write-Host $clientIp
- }
- catch
- {
- Write-Host "Unable to get this machine's effective IP address for logging: $_"
- }
-}
-
#
# If $ci flag is set, turn on (and log that we did) special environment variables for improved Nuget client retry logic.
#
diff --git a/eng/common/tools.sh b/eng/common/tools.sh
index dd7030ff538..17f0a365805 100755
--- a/eng/common/tools.sh
+++ b/eng/common/tools.sh
@@ -178,7 +178,7 @@ function InstallDotNetSdk {
if [[ $# -ge 3 ]]; then
architecture=$3
fi
- InstallDotNet "$root" "$version" $architecture 'sdk' 'false' $runtime_source_feed $runtime_source_feed_key
+ InstallDotNet "$root" "$version" $architecture 'sdk' 'true' $runtime_source_feed $runtime_source_feed_key
}
function InstallDotNet {
@@ -405,13 +405,6 @@ function StopProcesses {
return 0
}
-function TryLogClientIpAddress () {
- echo 'Attempting to log this client''s IP for Azure Package feed telemetry purposes'
- if command -v curl > /dev/null; then
- curl -s 'http://co1r5a.msedge.net/fdv2/diagnostics.aspx' | grep ' IP: ' || true
- fi
-}
-
function MSBuild {
local args=$@
if [[ "$pipelines_log" == true ]]; then
diff --git a/eng/pipelines/checkout-windows-task.yml b/eng/pipelines/checkout-windows-task.yml
new file mode 100644
index 00000000000..76a97eb381e
--- /dev/null
+++ b/eng/pipelines/checkout-windows-task.yml
@@ -0,0 +1,11 @@
+# Shallow checkout sources on Windows
+steps:
+ - checkout: none
+
+ - script: |
+ @echo on
+ git init
+ git remote add origin "$(Build.Repository.Uri)"
+ git fetch --progress --no-tags --depth=1 origin "$(Build.SourceVersion)"
+ git checkout "$(Build.SourceVersion)"
+ displayName: Shallow Checkout
diff --git a/eng/pipelines/publish-logs.yml b/eng/pipelines/publish-logs.yml
new file mode 100644
index 00000000000..79835baea3f
--- /dev/null
+++ b/eng/pipelines/publish-logs.yml
@@ -0,0 +1,17 @@
+# Build on windows desktop
+parameters:
+- name: jobName
+ type: string
+ default: ''
+- name: configuration
+ type: string
+ default: 'Debug'
+
+steps:
+ - task: PublishPipelineArtifact@1
+ displayName: Publish Logs
+ inputs:
+ targetPath: '$(Build.SourcesDirectory)/artifacts/log/${{ parameters.configuration }}'
+ artifactName: '${{ parameters.jobName }} Attempt $(System.JobAttempt) Logs'
+ continueOnError: true
+ condition: not(succeeded())
diff --git a/eng/test-determinism.cmd b/eng/test-determinism.cmd
index 863e8bd5ca3..972f85371e6 100644
--- a/eng/test-determinism.cmd
+++ b/eng/test-determinism.cmd
@@ -1,2 +1,2 @@
@echo off
-powershell -noprofile -executionPolicy RemoteSigned -file "%~dp0\test-determinism.ps1" %*
\ No newline at end of file
+powershell -noprofile -executionPolicy RemoteSigned -file "%~dp0\test-determinism.ps1" %*
diff --git a/eng/test-determinism.ps1 b/eng/test-determinism.ps1
index 45b0cc396fb..0356303cd01 100644
--- a/eng/test-determinism.ps1
+++ b/eng/test-determinism.ps1
@@ -39,7 +39,7 @@ function Run-Build([string]$rootDir, [string]$logFileName) {
$stopWatch.Stop()
Write-Host "Cleaning took $($stopWatch.Elapsed)"
- $solution = Join-Path $rootDir "FSharp.sln"
+ $solution = Join-Path $rootDir (Join-Path "service" "FSharp.Compiler.Service.sln")
if ($logFileName -eq "") {
$logFileName = [IO.Path]::GetFileNameWithoutExtension($projectFilePath)
@@ -59,6 +59,9 @@ function Run-Build([string]$rootDir, [string]$logFileName) {
/p:Rebuild=false `
/p:Pack=false `
/p:Sign=false `
+ /p:SignType=Test `
+ /p:DotNetSignType=Test `
+ /p:MicroBuild_SigningEnabled=false `
/p:Publish=false `
/p:ContinuousIntegrationBuild=false `
/p:OfficialBuildId="" `
@@ -194,10 +197,12 @@ function Test-Build([string]$rootDir, $dataMap, [string]$logFileName) {
}
$oldfileData = $datamap[$fileId]
- if ($fileData.Hash -ne $oldFileData.Hash) {
- Write-Host "`tERROR! $relativeDir\$fileName contents don't match"
+ $oldHash = $oldfileData.Hash
+ $newHash = $fileData.Hash
+ if ($newHash -ne $oldHash) {
+ Write-Host "`tERROR! $relativeDir\$fileName hashes don't match"
$allGood = $false
- $errorList += $fileName
+ $errorList += "$fileName (old hash: $oldHash; new hash: $newHash)"
$errorCurrentDirLeft = Join-Path $errorDirLeft $relativeDir
Create-Directory $errorCurrentDirLeft
diff --git a/global.json b/global.json
index be8025025fe..8b3f7ea6468 100644
--- a/global.json
+++ b/global.json
@@ -14,7 +14,7 @@
}
},
"msbuild-sdks": {
- "Microsoft.DotNet.Arcade.Sdk": "7.0.0-beta.21569.2",
+ "Microsoft.DotNet.Arcade.Sdk": "7.0.0-beta.21606.6",
"Microsoft.DotNet.Helix.Sdk": "2.0.0-beta.19069.2"
}
}
diff --git a/src/fsharp/AugmentWithHashCompare.fs b/src/fsharp/AugmentWithHashCompare.fs
index aa69ea08050..eb723a014a3 100644
--- a/src/fsharp/AugmentWithHashCompare.fs
+++ b/src/fsharp/AugmentWithHashCompare.fs
@@ -823,7 +823,7 @@ let TyconIsCandidateForAugmentationWithCompare (g: TcGlobals) (tycon: Tycon) =
// This type gets defined in prim-types, before we can add attributes to F# type definitions
let isUnit = g.compilingFslib && tycon.DisplayName = "Unit"
not isUnit &&
- not (TyconRefHasAttribute g tycon.Range g.attrib_IsByRefLikeAttribute (mkLocalTyconRef tycon)) &&
+ not (isByrefLikeTyconRef g tycon.Range (mkLocalTyconRef tycon)) &&
match getAugmentationAttribs g tycon with
// [< >]
| true, true, None, None, None, None, None, None, None
@@ -838,7 +838,7 @@ let TyconIsCandidateForAugmentationWithEquals (g: TcGlobals) (tycon: Tycon) =
// This type gets defined in prim-types, before we can add attributes to F# type definitions
let isUnit = g.compilingFslib && tycon.DisplayName = "Unit"
not isUnit &&
- not (TyconRefHasAttribute g tycon.Range g.attrib_IsByRefLikeAttribute (mkLocalTyconRef tycon)) &&
+ not (isByrefLikeTyconRef g tycon.Range (mkLocalTyconRef tycon)) &&
match getAugmentationAttribs g tycon with
// [< >]
diff --git a/src/fsharp/CompilerConfig.fs b/src/fsharp/CompilerConfig.fs
index dae491a9d44..838075f689b 100644
--- a/src/fsharp/CompilerConfig.fs
+++ b/src/fsharp/CompilerConfig.fs
@@ -325,6 +325,12 @@ type PackageManagerLine =
static member StripDependencyManagerKey (packageKey: string) (line: string): string =
line.Substring(packageKey.Length + 1).Trim()
+[]
+type MetadataAssemblyGeneration =
+ | None
+ | ReferenceOut of outputPath: string
+ | ReferenceOnly
+
[]
type TcConfigBuilder =
{
@@ -437,6 +443,7 @@ type TcConfigBuilder =
mutable emitTailcalls: bool
mutable deterministic: bool
mutable concurrentBuild: bool
+ mutable emitMetadataAssembly: MetadataAssemblyGeneration
mutable preferredUiLang: string option
mutable lcid: int option
mutable productNameForBannerText: string
@@ -642,6 +649,7 @@ type TcConfigBuilder =
emitTailcalls = true
deterministic = false
concurrentBuild = true
+ emitMetadataAssembly = MetadataAssemblyGeneration.None
preferredUiLang = None
lcid = None
productNameForBannerText = FSharpProductName
@@ -1022,6 +1030,7 @@ type TcConfig private (data: TcConfigBuilder, validate: bool) =
member x.emitTailcalls = data.emitTailcalls
member x.deterministic = data.deterministic
member x.concurrentBuild = data.concurrentBuild
+ member x.emitMetadataAssembly = data.emitMetadataAssembly
member x.pathMap = data.pathMap
member x.langVersion = data.langVersion
member x.preferredUiLang = data.preferredUiLang
diff --git a/src/fsharp/CompilerConfig.fsi b/src/fsharp/CompilerConfig.fsi
index 4a80fea97d1..2e186149325 100644
--- a/src/fsharp/CompilerConfig.fsi
+++ b/src/fsharp/CompilerConfig.fsi
@@ -143,6 +143,16 @@ type PackageManagerLine =
static member SetLinesAsProcessed: string -> Map -> Map
static member StripDependencyManagerKey: string -> string -> string
+[]
+type MetadataAssemblyGeneration =
+ | None
+ /// Includes F# signature and optimization metadata as resources in the emitting assembly.
+ /// Implementation assembly will still be emitted normally, but will emit the reference assembly with the specified output path.
+ | ReferenceOut of outputPath: string
+ /// Includes F# signature and optimization metadata as resources in the emitting assembly.
+ /// Only emits the assembly as a reference assembly.
+ | ReferenceOnly
+
[]
type TcConfigBuilder =
{ mutable primaryAssembly: PrimaryAssembly
@@ -249,6 +259,7 @@ type TcConfigBuilder =
mutable emitTailcalls: bool
mutable deterministic: bool
mutable concurrentBuild: bool
+ mutable emitMetadataAssembly: MetadataAssemblyGeneration
mutable preferredUiLang: string option
mutable lcid : int option
mutable productNameForBannerText: string
@@ -439,6 +450,7 @@ type TcConfig =
member emitTailcalls: bool
member deterministic: bool
member concurrentBuild: bool
+ member emitMetadataAssembly: MetadataAssemblyGeneration
member pathMap: PathMap
member preferredUiLang: string option
member optsOn : bool
diff --git a/src/fsharp/CompilerOptions.fs b/src/fsharp/CompilerOptions.fs
index 0cf6ece074f..74d8147a8bb 100644
--- a/src/fsharp/CompilerOptions.fs
+++ b/src/fsharp/CompilerOptions.fs
@@ -406,6 +406,23 @@ let SetTailcallSwitch (tcConfigB: TcConfigBuilder) switch =
let SetDeterministicSwitch (tcConfigB: TcConfigBuilder) switch =
tcConfigB.deterministic <- (switch = OptionSwitch.On)
+let SetReferenceAssemblyOnlySwitch (tcConfigB: TcConfigBuilder) switch =
+ match tcConfigB.emitMetadataAssembly with
+ | MetadataAssemblyGeneration.None ->
+ tcConfigB.emitMetadataAssembly <- if (switch = OptionSwitch.On) then MetadataAssemblyGeneration.ReferenceOnly else MetadataAssemblyGeneration.None
+ | _ ->
+ error(Error(FSComp.SR.optsInvalidRefAssembly(), rangeCmdArgs))
+
+let SetReferenceAssemblyOutSwitch (tcConfigB: TcConfigBuilder) outputPath =
+ match tcConfigB.emitMetadataAssembly with
+ | MetadataAssemblyGeneration.None ->
+ if FileSystem.IsInvalidPathShim outputPath then
+ error(Error(FSComp.SR.optsInvalidRefOut(), rangeCmdArgs))
+ else
+ tcConfigB.emitMetadataAssembly <- MetadataAssemblyGeneration.ReferenceOut outputPath
+ | _ ->
+ error(Error(FSComp.SR.optsInvalidRefAssembly(), rangeCmdArgs))
+
let AddPathMapping (tcConfigB: TcConfigBuilder) (pathPair: string) =
match pathPair.Split([|'='|], 2) with
| [| oldPrefix; newPrefix |] ->
@@ -723,6 +740,16 @@ let outputFileFlagsFsc (tcConfigB: TcConfigBuilder) =
("nocopyfsharpcore", tagNone,
OptionUnit (fun () -> tcConfigB.copyFSharpCore <- CopyFSharpCoreFlag.No), None,
Some (FSComp.SR.optsNoCopyFsharpCore()))
+
+ CompilerOption
+ ("refonly", tagNone,
+ OptionSwitch (SetReferenceAssemblyOnlySwitch tcConfigB), None,
+ Some (FSComp.SR.optsRefOnly()))
+
+ CompilerOption
+ ("refout", tagFile,
+ OptionString (SetReferenceAssemblyOutSwitch tcConfigB), None,
+ Some (FSComp.SR.optsRefOut()))
]
diff --git a/src/fsharp/FSComp.txt b/src/fsharp/FSComp.txt
index 057bc042c17..ded871675d1 100644
--- a/src/fsharp/FSComp.txt
+++ b/src/fsharp/FSComp.txt
@@ -874,6 +874,8 @@ optsDebug,"Specify debugging type: full, portable, embedded, pdbonly. ('%s' is t
optsOptimize,"Enable optimizations (Short form: -O)"
optsTailcalls,"Enable or disable tailcalls"
optsDeterministic,"Produce a deterministic assembly (including module version GUID and timestamp)"
+optsRefOnly,"Produce a reference assembly, instead of a full assembly, as the primary output"
+optsRefOut,"Produce a reference assembly with the specified file path."
optsPathMap,"Maps physical paths to source path names output by the compiler"
optsCrossoptimize,"Enable or disable cross-module optimizations"
optsWarnaserrorPM,"Report all warnings as errors"
@@ -1168,6 +1170,8 @@ fscTooManyErrors,"Exiting - too many errors"
2026,fscDeterministicDebugRequiresPortablePdb,"Deterministic builds only support portable PDBs (--debug:portable or --debug:embedded)"
2027,fscPathMapDebugRequiresPortablePdb,"--pathmap can only be used with portable PDBs (--debug:portable or --debug:embedded)"
2028,optsInvalidPathMapFormat,"Invalid path map. Mappings must be comma separated and of the format 'path=sourcePath'"
+2029,optsInvalidRefOut,"Invalid reference assembly path'"
+2030,optsInvalidRefAssembly,"Invalid use of emitting a reference assembly. Check the compiler options to not specify static linking, or using '--refonly' and '--refout' together."
3000,etIllegalCharactersInNamespaceName,"Character '%s' is not allowed in provided namespace name '%s'"
3001,etNullOrEmptyMemberName,"The provided type '%s' returned a member with a null or empty member name"
3002,etNullMember,"The provided type '%s' returned a null member"
diff --git a/src/fsharp/FSharp.Build/Microsoft.FSharp.Targets b/src/fsharp/FSharp.Build/Microsoft.FSharp.Targets
index 6965a546cc7..72c9527cad8 100644
--- a/src/fsharp/FSharp.Build/Microsoft.FSharp.Targets
+++ b/src/fsharp/FSharp.Build/Microsoft.FSharp.Targets
@@ -364,6 +364,7 @@ this file.
VisualStudioStyleErrors="$(VisualStudioStyleErrors)"
WarningLevel="$(WarningLevel)"
WarningsAsErrors="$(WarningsAsErrors)"
+ WarningsNotAsErrors="$(WarningsNotAsErrors)"
WarnOn="$(WarnOn)"
Win32IconFile="$(ApplicationIcon)"
Win32ManifestFile="$(Win32Manifest)"
diff --git a/src/fsharp/FSharp.Core/FSharp.Core.fsproj b/src/fsharp/FSharp.Core/FSharp.Core.fsproj
index 7da0f5ed97a..0fe4422cc23 100644
--- a/src/fsharp/FSharp.Core/FSharp.Core.fsproj
+++ b/src/fsharp/FSharp.Core/FSharp.Core.fsproj
@@ -255,12 +255,6 @@
-
-
-
-
-
-
$(BaseOutputPath)\$(Configuration)\$(TargetFramework)
diff --git a/src/fsharp/FSharp.DependencyManager.Nuget/FSharp.DependencyManager.ProjectFile.fs b/src/fsharp/FSharp.DependencyManager.Nuget/FSharp.DependencyManager.ProjectFile.fs
index b5aba3ad10f..497c42c2c47 100644
--- a/src/fsharp/FSharp.DependencyManager.Nuget/FSharp.DependencyManager.ProjectFile.fs
+++ b/src/fsharp/FSharp.DependencyManager.Nuget/FSharp.DependencyManager.ProjectFile.fs
@@ -130,7 +130,6 @@ $(POUND_R)
$(TARGETFRAMEWORK)$(RUNTIMEIDENTIFIER)false
- <_NETCoreSdkIsPreview>false
true
diff --git a/src/fsharp/IlxGen.fs b/src/fsharp/IlxGen.fs
index 22266e786e5..2d708e0bd57 100644
--- a/src/fsharp/IlxGen.fs
+++ b/src/fsharp/IlxGen.fs
@@ -8901,4 +8901,4 @@ type IlxAssemblyGenerator(amap: ImportMap, tcGlobals: TcGlobals, tcVal: Constrai
member _.ForceSetGeneratedValue (ctxt, v, value: obj) = SetGeneratedValue ctxt tcGlobals ilxGenEnv true v value
/// Invert the compilation of the given value and return its current dynamic value and its compiled System.Type
- member _.LookupGeneratedValue (ctxt, v) = LookupGeneratedValue amap ctxt ilxGenEnv v
+ member _.LookupGeneratedValue (ctxt, v) = LookupGeneratedValue amap ctxt ilxGenEnv v
\ No newline at end of file
diff --git a/src/fsharp/ParseAndCheckInputs.fs b/src/fsharp/ParseAndCheckInputs.fs
index 5ad43a53542..833af64d19c 100644
--- a/src/fsharp/ParseAndCheckInputs.fs
+++ b/src/fsharp/ParseAndCheckInputs.fs
@@ -35,6 +35,7 @@ open FSharp.Compiler.Text.Range
open FSharp.Compiler.Xml
open FSharp.Compiler.TypedTree
open FSharp.Compiler.TypedTreeOps
+open FSharp.Compiler.TypedTreeBasics
open FSharp.Compiler.TcGlobals
let CanonicalizeFilename filename =
@@ -814,6 +815,11 @@ let GetInitialTcState(m, ccuName, tcConfig: TcConfig, tcGlobals, tcImports: TcIm
tcsImplicitOpenDeclarations = openDecls0
}
+/// Dummy typed impl file that contains no definitions and is not used for emitting any kind of assembly.
+let CreateEmptyDummyTypedImplFile qualNameOfFile sigTy =
+ let dummyExpr = ModuleOrNamespaceExprWithSig.ModuleOrNamespaceExprWithSig(sigTy, ModuleOrNamespaceExpr.TMDefs [], range0)
+ TypedImplFile.TImplFile(qualNameOfFile, [], dummyExpr, false, false, StampMap.Empty)
+
/// Typecheck a single file (or interactive entry into F# Interactive)
let TypeCheckOneInput(checkForErrors,
tcConfig: TcConfig,
@@ -890,10 +896,7 @@ let TypeCheckOneInput(checkForErrors,
// Typecheck the implementation file
let typeCheckOne =
if skipImplIfSigExists && hadSig then
- let dummyExpr = ModuleOrNamespaceExprWithSig.ModuleOrNamespaceExprWithSig(rootSigOpt.Value, ModuleOrNamespaceExpr.TMDefs [], range.Zero)
- let dummyImplFile = TypedImplFile.TImplFile(qualNameOfFile, [], dummyExpr, false, false, StampMap [])
-
- (EmptyTopAttrs, dummyImplFile, Unchecked.defaultof<_>, tcImplEnv, false)
+ (EmptyTopAttrs, CreateEmptyDummyTypedImplFile qualNameOfFile rootSigOpt.Value, Unchecked.defaultof<_>, tcImplEnv, false)
|> Cancellable.ret
else
TypeCheckOneImplFile (tcGlobals, tcState.tcsNiceNameGen, amap, tcState.tcsCcu, tcState.tcsImplicitOpenDeclarations, checkForErrors, conditionalDefines, tcSink, tcConfig.internalTestSpanStackReferring, tcImplEnv, rootSigOpt, file)
diff --git a/src/fsharp/PostInferenceChecks.fs b/src/fsharp/PostInferenceChecks.fs
index 21f98a518f4..6fe439b04ef 100644
--- a/src/fsharp/PostInferenceChecks.fs
+++ b/src/fsharp/PostInferenceChecks.fs
@@ -2218,7 +2218,7 @@ let CheckRecdField isUnion cenv env (tycon: Tycon) (rfield: RecdField) =
let access = AdjustAccess isHidden (fun () -> tycon.CompilationPath) rfield.Accessibility
CheckTypeForAccess cenv env (fun () -> rfield.LogicalName) access m fieldTy
- if TyconRefHasAttribute g m g.attrib_IsByRefLikeAttribute tcref then
+ if isByrefLikeTyconRef g m tcref then
// Permit Span fields in IsByRefLike types
CheckTypePermitSpanLike cenv env m fieldTy
if cenv.reportErrors then
@@ -2441,7 +2441,8 @@ let CheckEntityDefn cenv env (tycon: Entity) =
else
errorR(Error(FSComp.SR.chkDuplicateMethodInheritedTypeWithSuffix nm, m))
- if TyconRefHasAttribute g m g.attrib_IsByRefLikeAttribute tcref && not tycon.IsStructOrEnumTycon then
+
+ if TyconRefHasAttributeByName m tname_IsByRefLikeAttribute tcref && not tycon.IsStructOrEnumTycon then
errorR(Error(FSComp.SR.tcByRefLikeNotStruct(), tycon.Range))
if TyconRefHasAttribute g m g.attrib_IsReadOnlyAttribute tcref && not tycon.IsStructOrEnumTycon then
diff --git a/src/fsharp/StaticLinking.fs b/src/fsharp/StaticLinking.fs
index c2a1e9c25ce..e8e3ce7e00c 100644
--- a/src/fsharp/StaticLinking.fs
+++ b/src/fsharp/StaticLinking.fs
@@ -354,6 +354,11 @@ let StaticLink (ctok, tcConfig: TcConfig, tcImports: TcImports, ilGlobals: ILGlo
id
else
(fun ilxMainModule ->
+ match tcConfig.emitMetadataAssembly with
+ | MetadataAssemblyGeneration.None -> ()
+ | _ ->
+ error(Error(FSComp.SR.optsInvalidRefAssembly(), rangeCmdArgs))
+
ReportTime tcConfig "Find assembly references"
let dependentILModules = FindDependentILModulesForStaticLinking (ctok, tcConfig, tcImports, ilGlobals, ilxMainModule)
diff --git a/src/fsharp/TcGlobals.fs b/src/fsharp/TcGlobals.fs
index e6b819f448e..5eabf378880 100755
--- a/src/fsharp/TcGlobals.fs
+++ b/src/fsharp/TcGlobals.fs
@@ -165,11 +165,15 @@ let tname_RuntimeFieldHandle = "System.RuntimeFieldHandle"
[]
let tname_CompilerGeneratedAttribute = "System.Runtime.CompilerServices.CompilerGeneratedAttribute"
[]
+let tname_ReferenceAssemblyAttribute = "System.Runtime.CompilerServices.ReferenceAssemblyAttribute"
+[]
let tname_DebuggableAttribute = "System.Diagnostics.DebuggableAttribute"
[]
let tname_AsyncCallback = "System.AsyncCallback"
[]
let tname_IAsyncResult = "System.IAsyncResult"
+[]
+let tname_IsByRefLikeAttribute = "System.Runtime.CompilerServices.IsByRefLikeAttribute"
//-------------------------------------------------------------------------
// Table of all these "globals"
@@ -1190,6 +1194,7 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d
member val iltyp_RuntimeFieldHandle = findSysILTypeRef tname_RuntimeFieldHandle |> mkILNonGenericValueTy
member val iltyp_RuntimeMethodHandle = findSysILTypeRef tname_RuntimeMethodHandle |> mkILNonGenericValueTy
member val iltyp_RuntimeTypeHandle = findSysILTypeRef tname_RuntimeTypeHandle |> mkILNonGenericValueTy
+ member val iltyp_ReferenceAssemblyAttributeOpt = tryFindSysILTypeRef tname_ReferenceAssemblyAttribute |> Option.map mkILNonGenericBoxedTy
member val attrib_AttributeUsageAttribute = findSysAttrib "System.AttributeUsageAttribute"
@@ -1199,7 +1204,6 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d
// We use 'findSysAttrib' here because lookup on attribute is done by name comparison, and can proceed
// even if the type is not found in a system assembly.
- member val attrib_IsByRefLikeAttribute = findSysAttrib "System.Runtime.CompilerServices.IsByRefLikeAttribute"
member val attrib_IsReadOnlyAttribute = findSysAttrib "System.Runtime.CompilerServices.IsReadOnlyAttribute"
member val attrib_SystemObsolete = findSysAttrib "System.ObsoleteAttribute"
@@ -1229,6 +1233,7 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d
member val attrib_CallerLineNumberAttribute = findSysAttrib "System.Runtime.CompilerServices.CallerLineNumberAttribute"
member val attrib_CallerFilePathAttribute = findSysAttrib "System.Runtime.CompilerServices.CallerFilePathAttribute"
member val attrib_CallerMemberNameAttribute = findSysAttrib "System.Runtime.CompilerServices.CallerMemberNameAttribute"
+ member val attrib_ReferenceAssemblyAttribute = findSysAttrib "System.Runtime.CompilerServices.ReferenceAssemblyAttribute"
member val attrib_SkipLocalsInitAttribute = findSysAttrib "System.Runtime.CompilerServices.SkipLocalsInitAttribute"
member val attribs_Unsupported = v_attribs_Unsupported
diff --git a/src/fsharp/TypedTreeOps.fs b/src/fsharp/TypedTreeOps.fs
index 1dedf910ac6..9a5e25f9bff 100644
--- a/src/fsharp/TypedTreeOps.fs
+++ b/src/fsharp/TypedTreeOps.fs
@@ -1982,7 +1982,7 @@ let emptyFreeTyvars =
{ FreeTycons = emptyFreeTycons
// The summary of values used as trait solutions
FreeTraitSolutions = emptyFreeLocals
- FreeTypars = emptyFreeTypars}
+ FreeTypars = emptyFreeTypars }
let isEmptyFreeTyvars ftyvs =
Zset.isEmpty ftyvs.FreeTypars &&
@@ -3201,6 +3201,28 @@ let TyconRefHasAttribute g m attribSpec tcref =
(fun _ -> Some ())
|> Option.isSome
+/// Check if a type definition has an attribute with a specific full name
+let TyconRefHasAttributeByName (m: range) attrFullName (tcref: TyconRef) =
+ ignore m
+ match metadataOfTycon tcref.Deref with
+#if !NO_EXTENSIONTYPING
+ | ProvidedTypeMetadata info ->
+ let provAttribs = info.ProvidedType.PApply((fun a -> (a :> IProvidedCustomAttributeProvider)), m)
+ provAttribs.PUntaint((fun a ->
+ a.GetAttributeConstructorArgs(provAttribs.TypeProvider.PUntaintNoFailure id, attrFullName)), m).IsSome
+#endif
+ | ILTypeMetadata (TILObjectReprData(_, _, tdef)) ->
+ tdef.CustomAttrs.AsArray
+ |> Array.exists (fun attr -> isILAttribByName ([], attrFullName) attr)
+ | FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata ->
+ tcref.Attribs
+ |> List.exists (fun attr ->
+ match attr.TyconRef.CompiledRepresentation with
+ | CompiledTypeRepr.ILAsmNamed(typeRef, _, _) ->
+ typeRef.Enclosing.IsEmpty
+ && typeRef.Name = attrFullName
+ | CompiledTypeRepr.ILAsmOpen _ -> false)
+
let isByrefTyconRef (g: TcGlobals) (tcref: TyconRef) =
(g.byref_tcr.CanDeref && tyconRefEq g g.byref_tcr tcref) ||
(g.byref2_tcr.CanDeref && tyconRefEq g g.byref2_tcr tcref) ||
@@ -3218,7 +3240,7 @@ let isByrefLikeTyconRef (g: TcGlobals) m (tcref: TyconRef) =
| _ ->
let res =
isByrefTyconRef g tcref ||
- (isStructTyconRef tcref && TyconRefHasAttribute g m g.attrib_IsByRefLikeAttribute tcref)
+ (isStructTyconRef tcref && TyconRefHasAttributeByName m tname_IsByRefLikeAttribute tcref)
tcref.SetIsByRefLike res
res
diff --git a/src/fsharp/TypedTreeOps.fsi b/src/fsharp/TypedTreeOps.fsi
index 2b9fbb8c049..f6c84a6d2db 100755
--- a/src/fsharp/TypedTreeOps.fsi
+++ b/src/fsharp/TypedTreeOps.fsi
@@ -760,7 +760,7 @@ val emptyFreeLocals: FreeLocals
val unionFreeLocals: FreeLocals -> FreeLocals -> FreeLocals
-type FreeVarOptions
+type FreeVarOptions
val CollectLocalsNoCaching: FreeVarOptions
@@ -2155,6 +2155,9 @@ val TryFindTyconRefBoolAttribute: TcGlobals -> range -> BuiltinAttribInfo -> Tyc
/// Try to find a specific attribute on a type definition
val TyconRefHasAttribute: TcGlobals -> range -> BuiltinAttribInfo -> TyconRef -> bool
+/// Try to find an attribute with a specific full name on a type definition
+val TyconRefHasAttributeByName: range -> string -> TyconRef -> bool
+
/// Try to find the AttributeUsage attribute, looking for the value of the AllowMultiple named parameter
val TryFindAttributeUsageAttribute: TcGlobals -> range -> TyconRef -> bool option
diff --git a/src/fsharp/absil/ilwrite.fs b/src/fsharp/absil/ilwrite.fs
index 7ddd68e404c..b8a8c4d3415 100644
--- a/src/fsharp/absil/ilwrite.fs
+++ b/src/fsharp/absil/ilwrite.fs
@@ -564,6 +564,12 @@ type cenv =
normalizeAssemblyRefs: ILAssemblyRef -> ILAssemblyRef
+ /// Indicates that the writing assembly will have an assembly-level attribute, System.Runtime.CompilerServices.InternalsVisibleToAttribute.
+ hasInternalsVisibleToAttrib: bool
+
+ /// Indicates that the writing assembly will be a reference assembly. Method bodies will be replaced with a `throw null` if there are any.
+ referenceAssemblyOnly: bool
+
pdbImports: Dictionary
}
member cenv.GetTable (tab: TableName) = cenv.tables.[tab.Index]
@@ -1076,6 +1082,14 @@ let GetTypeAccessFlags access =
| ILTypeDefAccess.Nested ILMemberAccess.FamilyOrAssembly -> 0x00000007
| ILTypeDefAccess.Nested ILMemberAccess.Assembly -> 0x00000005
+let canGenMethodDef cenv (md: ILMethodDef) =
+ // When emitting a reference assembly, do not emit methods that are private unless they are virtual/abstract or provide an explicit interface implementation.
+ // Internal methods can be omitted only if the assembly does not contain a System.Runtime.CompilerServices.InternalsVisibleToAttribute.
+ if cenv.referenceAssemblyOnly &&
+ (match md.Access with ILMemberAccess.Private -> true | ILMemberAccess.Assembly | ILMemberAccess.FamilyAndAssembly -> not cenv.hasInternalsVisibleToAttrib | _ -> false) &&
+ not (md.IsVirtual || md.IsAbstract || md.IsNewSlot || md.IsFinal) then false
+ else true
+
let rec GetTypeDefAsRow cenv env _enc (td: ILTypeDef) =
let nselem, nelem = GetTypeNameAsElemPair cenv td.Name
let flags =
@@ -1117,19 +1131,20 @@ and GetKeyForMethodDef cenv tidx (md: ILMethodDef) =
MethodDefKey (cenv.ilg, tidx, md.GenericParams.Length, md.Name, md.Return.Type, md.ParameterTypes, md.CallingConv.IsStatic)
and GenMethodDefPass2 cenv tidx md =
- let idx =
- cenv.methodDefIdxsByKey.AddUniqueEntry
- "method"
- (fun (key: MethodDefKey) ->
- dprintn "Duplicate in method table is:"
- dprintn (" Type index: "+string key.TypeIdx)
- dprintn (" Method name: "+key.Name)
- dprintn (" Method arity (num generic params): "+string key.GenericArity)
- key.Name
- )
- (GetKeyForMethodDef cenv tidx md)
-
- cenv.methodDefIdxs.[md] <- idx
+ if canGenMethodDef cenv md then
+ let idx =
+ cenv.methodDefIdxsByKey.AddUniqueEntry
+ "method"
+ (fun (key: MethodDefKey) ->
+ dprintn "Duplicate in method table is:"
+ dprintn (" Type index: "+string key.TypeIdx)
+ dprintn (" Method name: "+key.Name)
+ dprintn (" Method arity (num generic params): "+string key.GenericArity)
+ key.Name
+ )
+ (GetKeyForMethodDef cenv tidx md)
+
+ cenv.methodDefIdxs.[md] <- idx
and GetKeyForPropertyDef tidx (x: ILPropertyDef) =
PropKey (tidx, x.Name, x.PropertyType, x.Args)
@@ -2507,6 +2522,10 @@ let GetMethodDefSigAsBytes cenv env (mdef: ILMethodDef) =
let GenMethodDefSigAsBlobIdx cenv env mdef =
GetBytesAsBlobIdx cenv (GetMethodDefSigAsBytes cenv env mdef)
+let ilMethodBodyThrowNull =
+ let ilCode = IL.buildILCode "" (Dictionary()) [|ILInstr.AI_ldnull; ILInstr.I_throw|] [] []
+ mkILMethodBody(false, ILLocals.Empty, 0, ilCode, None, None)
+
let GenMethodDefAsRow cenv env midx (md: ILMethodDef) =
let flags = md.Attributes
@@ -2518,7 +2537,11 @@ let GenMethodDefAsRow cenv env midx (md: ILMethodDef) =
let codeAddr =
(match md.Body with
| MethodBody.IL ilmbodyLazy ->
- let ilmbody = ilmbodyLazy.Value
+ let ilmbody =
+ if cenv.referenceAssemblyOnly then
+ ilMethodBodyThrowNull
+ else
+ ilmbodyLazy.Value
let addr = cenv.nextCodeAddr
let localToken, code, seqpoints, rootScope = GenILMethodBody md.Name cenv env ilmbody
@@ -2581,55 +2604,57 @@ let GenMethodImplPass3 cenv env _tgparams tidx mimpl =
MethodDefOrRef (midx2Tag, midx2Row) |]) |> ignore
let GenMethodDefPass3 cenv env (md: ILMethodDef) =
- let midx = GetMethodDefIdx cenv md
- let idx2 = AddUnsharedRow cenv TableNames.Method (GenMethodDefAsRow cenv env midx md)
- if midx <> idx2 then failwith "index of method def on pass 3 does not match index on pass 2"
- GenReturnPass3 cenv md.Return
- md.Parameters |> List.iteri (fun n param -> GenParamPass3 cenv env (n+1) param)
- md.CustomAttrs |> GenCustomAttrsPass3Or4 cenv (hca_MethodDef, midx)
- md.SecurityDecls.AsList |> GenSecurityDeclsPass3 cenv (hds_MethodDef, midx)
- md.GenericParams |> List.iteri (fun n gp -> GenGenericParamPass3 cenv env n (tomd_MethodDef, midx) gp)
- match md.Body with
- | MethodBody.PInvoke attrLazy ->
- let attr = attrLazy.Value
- let flags =
- begin match attr.CallingConv with
- | PInvokeCallingConvention.None -> 0x0000
- | PInvokeCallingConvention.Cdecl -> 0x0200
- | PInvokeCallingConvention.Stdcall -> 0x0300
- | PInvokeCallingConvention.Thiscall -> 0x0400
- | PInvokeCallingConvention.Fastcall -> 0x0500
- | PInvokeCallingConvention.WinApi -> 0x0100
- end |||
- begin match attr.CharEncoding with
- | PInvokeCharEncoding.None -> 0x0000
- | PInvokeCharEncoding.Ansi -> 0x0002
- | PInvokeCharEncoding.Unicode -> 0x0004
- | PInvokeCharEncoding.Auto -> 0x0006
- end |||
- begin match attr.CharBestFit with
- | PInvokeCharBestFit.UseAssembly -> 0x0000
- | PInvokeCharBestFit.Enabled -> 0x0010
- | PInvokeCharBestFit.Disabled -> 0x0020
- end |||
- begin match attr.ThrowOnUnmappableChar with
- | PInvokeThrowOnUnmappableChar.UseAssembly -> 0x0000
- | PInvokeThrowOnUnmappableChar.Enabled -> 0x1000
- | PInvokeThrowOnUnmappableChar.Disabled -> 0x2000
- end |||
- (if attr.NoMangle then 0x0001 else 0x0000) |||
- (if attr.LastError then 0x0040 else 0x0000)
- AddUnsharedRow cenv TableNames.ImplMap
- (UnsharedRow
- [| UShort (uint16 flags)
- MemberForwarded (mf_MethodDef, midx)
- StringE (GetStringHeapIdx cenv attr.Name)
- SimpleIndex (TableNames.ModuleRef, GetModuleRefAsIdx cenv attr.Where) |]) |> ignore
- | _ -> ()
+ if canGenMethodDef cenv md then
+ let midx = GetMethodDefIdx cenv md
+ let idx2 = AddUnsharedRow cenv TableNames.Method (GenMethodDefAsRow cenv env midx md)
+ if midx <> idx2 then failwith "index of method def on pass 3 does not match index on pass 2"
+ GenReturnPass3 cenv md.Return
+ md.Parameters |> List.iteri (fun n param -> GenParamPass3 cenv env (n+1) param)
+ md.CustomAttrs |> GenCustomAttrsPass3Or4 cenv (hca_MethodDef, midx)
+ md.SecurityDecls.AsList |> GenSecurityDeclsPass3 cenv (hds_MethodDef, midx)
+ md.GenericParams |> List.iteri (fun n gp -> GenGenericParamPass3 cenv env n (tomd_MethodDef, midx) gp)
+ match md.Body with
+ | MethodBody.PInvoke attrLazy ->
+ let attr = attrLazy.Value
+ let flags =
+ begin match attr.CallingConv with
+ | PInvokeCallingConvention.None -> 0x0000
+ | PInvokeCallingConvention.Cdecl -> 0x0200
+ | PInvokeCallingConvention.Stdcall -> 0x0300
+ | PInvokeCallingConvention.Thiscall -> 0x0400
+ | PInvokeCallingConvention.Fastcall -> 0x0500
+ | PInvokeCallingConvention.WinApi -> 0x0100
+ end |||
+ begin match attr.CharEncoding with
+ | PInvokeCharEncoding.None -> 0x0000
+ | PInvokeCharEncoding.Ansi -> 0x0002
+ | PInvokeCharEncoding.Unicode -> 0x0004
+ | PInvokeCharEncoding.Auto -> 0x0006
+ end |||
+ begin match attr.CharBestFit with
+ | PInvokeCharBestFit.UseAssembly -> 0x0000
+ | PInvokeCharBestFit.Enabled -> 0x0010
+ | PInvokeCharBestFit.Disabled -> 0x0020
+ end |||
+ begin match attr.ThrowOnUnmappableChar with
+ | PInvokeThrowOnUnmappableChar.UseAssembly -> 0x0000
+ | PInvokeThrowOnUnmappableChar.Enabled -> 0x1000
+ | PInvokeThrowOnUnmappableChar.Disabled -> 0x2000
+ end |||
+ (if attr.NoMangle then 0x0001 else 0x0000) |||
+ (if attr.LastError then 0x0040 else 0x0000)
+ AddUnsharedRow cenv TableNames.ImplMap
+ (UnsharedRow
+ [| UShort (uint16 flags)
+ MemberForwarded (mf_MethodDef, midx)
+ StringE (GetStringHeapIdx cenv attr.Name)
+ SimpleIndex (TableNames.ModuleRef, GetModuleRefAsIdx cenv attr.Where) |]) |> ignore
+ | _ -> ()
let GenMethodDefPass4 cenv env md =
- let midx = GetMethodDefIdx cenv md
- List.iteri (fun n gp -> GenGenericParamPass4 cenv env n (tomd_MethodDef, midx) gp) md.GenericParams
+ if canGenMethodDef cenv md then
+ let midx = GetMethodDefIdx cenv md
+ List.iteri (fun n gp -> GenGenericParamPass4 cenv env n (tomd_MethodDef, midx) gp) md.GenericParams
let GenPropertyMethodSemanticsPass3 cenv pidx kind mref =
// REVIEW: why are we catching exceptions here?
@@ -2940,9 +2965,27 @@ let DataCapacity = 200
[]
let ResourceCapacity = 200
-let generateIL requiredDataFixups (desiredMetadataVersion, generatePdb, ilg : ILGlobals, emitTailcalls, deterministic, showTimes) (m : ILModuleDef) cilStartAddress normalizeAssemblyRefs =
+let generateIL requiredDataFixups (desiredMetadataVersion, generatePdb, ilg : ILGlobals, emitTailcalls, deterministic, showTimes, referenceAssemblyOnly, referenceAssemblyAttribOpt: ILAttribute option) (m : ILModuleDef) cilStartAddress normalizeAssemblyRefs =
let isDll = m.IsDLL
+ let hasInternalsVisibleToAttrib =
+ m.CustomAttrs.AsArray
+ |> Array.exists (fun x ->
+ x.Method.MethodRef.Name = "InternalsVisibleToAttribute" &&
+ x.Method.MethodRef.DeclaringTypeRef.FullName = "System.Runtime.CompilerServices"
+ )
+
+ let m =
+ // Emit System.Runtime.CompilerServices.ReferenceAssemblyAttribute as an assembly-level attribute when generating a reference assembly.
+ // Useful for the runtime to know that the assembly is a reference assembly.
+ match referenceAssemblyAttribOpt with
+ | Some referenceAssemblyAttrib when referenceAssemblyOnly ->
+ { m with
+ CustomAttrsStored =
+ mkILCustomAttrsReader (fun _ -> Array.append [|referenceAssemblyAttrib|] m.CustomAttrs.AsArray) }
+ | _ ->
+ m
+
let tables =
Array.init 64 (fun i ->
if (i = TableNames.AssemblyRef.Index ||
@@ -2989,7 +3032,9 @@ let generateIL requiredDataFixups (desiredMetadataVersion, generatePdb, ilg : IL
blobs= MetadataTable<_>.New("blobs", HashIdentity.Structural)
strings= MetadataTable<_>.New("strings", EqualityComparer.Default)
userStrings= MetadataTable<_>.New("user strings", EqualityComparer.Default)
- normalizeAssemblyRefs = normalizeAssemblyRefs
+ normalizeAssemblyRefs = normalizeAssemblyRefs
+ hasInternalsVisibleToAttrib = hasInternalsVisibleToAttrib
+ referenceAssemblyOnly = referenceAssemblyOnly
pdbImports = Dictionary<_, _>(HashIdentity.Reference) }
// Now the main compilation step
@@ -3091,7 +3136,7 @@ let TableCapacity = 20000
[]
let MetadataCapacity = 500000
-let writeILMetadataAndCode (generatePdb, desiredMetadataVersion, ilg, emitTailcalls, deterministic, showTimes) modul cilStartAddress normalizeAssemblyRefs =
+let writeILMetadataAndCode (generatePdb, desiredMetadataVersion, ilg, emitTailcalls, deterministic, showTimes, referenceAssemblyOnly, referenceAssemblyAttribOpt) modul cilStartAddress normalizeAssemblyRefs =
// When we know the real RVAs of the data section we fixup the references for the FieldRVA table.
// These references are stored as offsets into the metadata we return from this function
@@ -3100,7 +3145,7 @@ let writeILMetadataAndCode (generatePdb, desiredMetadataVersion, ilg, emitTailca
let next = cilStartAddress
let strings, userStrings, blobs, guids, tables, entryPointToken, code, requiredStringFixups, data, resources, pdbData, mappings =
- generateIL requiredDataFixups (desiredMetadataVersion, generatePdb, ilg, emitTailcalls, deterministic, showTimes) modul cilStartAddress normalizeAssemblyRefs
+ generateIL requiredDataFixups (desiredMetadataVersion, generatePdb, ilg, emitTailcalls, deterministic, showTimes, referenceAssemblyOnly, referenceAssemblyAttribOpt) modul cilStartAddress normalizeAssemblyRefs
reportTime showTimes "Generated Tables and Code"
let tableSize (tab: TableName) = tables.[tab.Index].Count
@@ -3559,7 +3604,7 @@ let rec writeBinaryAndReportMappings (outfile,
let pdbData, pdbOpt, debugDirectoryChunk, debugDataChunk, debugChecksumPdbChunk, debugEmbeddedPdbChunk, debugDeterministicPdbChunk, textV2P, mappings =
try
let res = writeBinaryAndReportMappingsAux(stream, false, ilg, pdbfile, signer, portablePDB, embeddedPDB, embedAllSource, embedSourceList, sourceLink,
- checksumAlgorithm, emitTailcalls, deterministic, showTimes, pathMap) modul normalizeAssemblyRefs
+ checksumAlgorithm, emitTailcalls, deterministic, showTimes, false, None, pathMap) modul normalizeAssemblyRefs
try
FileSystemUtilities.setExecutablePermission outfile
@@ -3578,16 +3623,16 @@ let rec writeBinaryAndReportMappings (outfile,
and writeBinaryWithNoPdb (stream: Stream,
ilg: ILGlobals, signer: ILStrongNameSigner option, portablePDB, embeddedPDB,
- embedAllSource, embedSourceList, sourceLink, checksumAlgorithm, emitTailcalls, deterministic, showTimes, pathMap)
+ embedAllSource, embedSourceList, sourceLink, checksumAlgorithm, emitTailcalls, deterministic, showTimes, referenceAssemblyOnly, referenceAssemblyAttribOpt, pathMap)
modul normalizeAssemblyRefs =
writeBinaryAndReportMappingsAux(stream, true, ilg, None, signer, portablePDB, embeddedPDB, embedAllSource, embedSourceList, sourceLink,
- checksumAlgorithm, emitTailcalls, deterministic, showTimes, pathMap) modul normalizeAssemblyRefs
+ checksumAlgorithm, emitTailcalls, deterministic, showTimes, referenceAssemblyOnly, referenceAssemblyAttribOpt, pathMap) modul normalizeAssemblyRefs
|> ignore
and writeBinaryAndReportMappingsAux (stream: Stream, leaveStreamOpen: bool,
ilg: ILGlobals, pdbfile: string option, signer: ILStrongNameSigner option, portablePDB, embeddedPDB,
- embedAllSource, embedSourceList, sourceLink, checksumAlgorithm, emitTailcalls, deterministic, showTimes, pathMap)
+ embedAllSource, embedSourceList, sourceLink, checksumAlgorithm, emitTailcalls, deterministic, showTimes, referenceAssemblyOnly, referenceAssemblyAttribOpt, pathMap)
modul normalizeAssemblyRefs =
// Store the public key from the signer into the manifest. This means it will be written
// to the binary and also acts as an indicator to leave space for delay sign
@@ -3699,7 +3744,7 @@ and writeBinaryAndReportMappingsAux (stream: Stream, leaveStreamOpen: bool,
| None -> failwith "Expected mscorlib to have a version number"
let entryPointToken, code, codePadding, metadata, data, resources, requiredDataFixups, pdbData, mappings, guidStart =
- writeILMetadataAndCode ((pdbfile <> None), desiredMetadataVersion, ilg, emitTailcalls, deterministic, showTimes) modul next normalizeAssemblyRefs
+ writeILMetadataAndCode ((pdbfile <> None), desiredMetadataVersion, ilg, emitTailcalls, deterministic, showTimes, referenceAssemblyOnly, referenceAssemblyAttribOpt) modul next normalizeAssemblyRefs
reportTime showTimes "Generated IL and metadata"
let _codeChunk, next = chunk code.Length next
@@ -4369,8 +4414,8 @@ let WriteILBinary (filename, options: options, inputModule, normalizeAssemblyRef
options.embedSourceList, options.sourceLink, options.checksumAlgorithm, options.emitTailcalls, options.deterministic, options.showTimes, options.dumpDebugInfo, options.pathMap) inputModule normalizeAssemblyRefs
|> ignore
-let WriteILBinaryStreamWithNoPDB (stream, options: options, inputModule, normalizeAssemblyRefs) =
+let WriteILBinaryStreamWithNoPDB (stream, (options: options), referenceAssemblyOnly, referenceAssemblyAttribOpt, inputModule, normalizeAssemblyRefs) =
writeBinaryWithNoPdb (stream,
options.ilg, options.signer, options.portablePDB, options.embeddedPDB, options.embedAllSource,
- options.embedSourceList, options.sourceLink, options.checksumAlgorithm, options.emitTailcalls, options.deterministic, options.showTimes, options.pathMap) inputModule normalizeAssemblyRefs
+ options.embedSourceList, options.sourceLink, options.checksumAlgorithm, options.emitTailcalls, options.deterministic, options.showTimes, referenceAssemblyOnly, referenceAssemblyAttribOpt, options.pathMap) inputModule normalizeAssemblyRefs
|> ignore
diff --git a/src/fsharp/absil/ilwrite.fsi b/src/fsharp/absil/ilwrite.fsi
index 152c9abc45f..380f94f3b27 100644
--- a/src/fsharp/absil/ilwrite.fsi
+++ b/src/fsharp/absil/ilwrite.fsi
@@ -29,4 +29,4 @@ type options =
val WriteILBinary: filename: string * options: options * inputModule: ILModuleDef * (ILAssemblyRef -> ILAssemblyRef) -> unit
/// Write a binary to the given stream. Extra configuration parameters can also be specified.
-val WriteILBinaryStreamWithNoPDB: stream: Stream * options: options * inputModule: ILModuleDef * (ILAssemblyRef -> ILAssemblyRef) -> unit
\ No newline at end of file
+val WriteILBinaryStreamWithNoPDB: stream: Stream * options: options * referenceAssemblyOnly: bool * referenceAssemblyAttribOpt: ILAttribute option * inputModule: ILModuleDef * (ILAssemblyRef -> ILAssemblyRef) -> unit
\ No newline at end of file
diff --git a/src/fsharp/fsc.fs b/src/fsharp/fsc.fs
index 54edda22d2e..e78656246f7 100644
--- a/src/fsharp/fsc.fs
+++ b/src/fsharp/fsc.fs
@@ -779,13 +779,6 @@ let main3(Args (ctok, tcConfig, tcImports, frameworkTcImports: TcImports, tcGlob
errorRecoveryNoRange e
exiter.Exit 1
- // Perform optimization
- use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Optimize
-
- let optEnv0 = GetInitialOptimizationEnv (tcImports, tcGlobals)
-
- let importMap = tcImports.GetImportMap()
-
let metadataVersion =
match tcConfig.metadataVersion with
| Some v -> v
@@ -793,18 +786,26 @@ let main3(Args (ctok, tcConfig, tcImports, frameworkTcImports: TcImports, tcGlob
match frameworkTcImports.DllTable.TryFind tcConfig.primaryAssembly.Name with
| Some ib -> ib.RawMetadata.TryGetILModuleDef().Value.MetadataVersion
| _ -> ""
+
+ let optimizedImpls, optDataResources =
+ // Perform optimization
+ use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Optimize
+
+ let optEnv0 = GetInitialOptimizationEnv (tcImports, tcGlobals)
- let optimizedImpls, optimizationData, _ =
- ApplyAllOptimizations
- (tcConfig, tcGlobals, (LightweightTcValForUsingInBuildMethodCall tcGlobals), outfile,
- importMap, false, optEnv0, generatedCcu, typedImplFiles)
+ let importMap = tcImports.GetImportMap()
- AbortOnError(errorLogger, exiter)
+ let optimizedImpls, optimizationData, _ =
+ ApplyAllOptimizations
+ (tcConfig, tcGlobals, (LightweightTcValForUsingInBuildMethodCall tcGlobals), outfile,
+ importMap, false, optEnv0, generatedCcu, typedImplFiles)
- // Encode the optimization data
- ReportTime tcConfig "Encoding OptData"
+ AbortOnError(errorLogger, exiter)
+
+ // Encode the optimization data
+ ReportTime tcConfig ("Encoding OptData")
- let optDataResources = EncodeOptimizationData(tcGlobals, tcConfig, outfile, exportRemapping, (generatedCcu, optimizationData), false)
+ optimizedImpls, EncodeOptimizationData(tcGlobals, tcConfig, outfile, exportRemapping, (generatedCcu, optimizationData), false)
// Pass on only the minimum information required for the next phase
Args (ctok, tcConfig, tcImports, tcGlobals, errorLogger,
@@ -905,28 +906,79 @@ let main6 dynamicAssemblyCreator (Args (ctok, tcConfig, tcImports: TcImports, t
match dynamicAssemblyCreator with
| None ->
try
- try
- ILBinaryWriter.WriteILBinary
- (outfile,
- { ilg = tcGlobals.ilg
- pdbfile=pdbfile
- emitTailcalls = tcConfig.emitTailcalls
- deterministic = tcConfig.deterministic
- showTimes = tcConfig.showTimes
- portablePDB = tcConfig.portablePDB
- embeddedPDB = tcConfig.embeddedPDB
- embedAllSource = tcConfig.embedAllSource
- embedSourceList = tcConfig.embedSourceList
- sourceLink = tcConfig.sourceLink
- checksumAlgorithm = tcConfig.checksumAlgorithm
- signer = GetStrongNameSigner signingInfo
- dumpDebugInfo = tcConfig.dumpDebugInfo
- pathMap = tcConfig.pathMap },
- ilxMainModule,
- normalizeAssemblyRefs
- )
- with Failure msg ->
- error(Error(FSComp.SR.fscProblemWritingBinary(outfile, msg), rangeCmdArgs))
+ match tcConfig.emitMetadataAssembly with
+ | MetadataAssemblyGeneration.None -> ()
+ | _ ->
+ let outfile =
+ match tcConfig.emitMetadataAssembly with
+ | MetadataAssemblyGeneration.ReferenceOut outputPath ->
+ outputPath
+ | _ ->
+ outfile
+ let referenceAssemblyAttribOpt =
+ tcGlobals.iltyp_ReferenceAssemblyAttributeOpt
+ |> Option.map (fun ilTy ->
+ mkILCustomAttribute (ilTy.TypeRef, [], [], [])
+ )
+ try
+ use stream =
+ try
+ // Ensure the output directory exists otherwise it will fail
+ let dir = FileSystem.GetDirectoryNameShim outfile
+ if not (FileSystem.DirectoryExistsShim dir) then FileSystem.DirectoryCreateShim dir |> ignore
+ FileSystem.OpenFileForWriteShim(outfile, FileMode.Create, FileAccess.Write, FileShare.Read)
+ with _ ->
+ failwith ("Could not open file for writing (binary mode): " + outfile)
+
+ ILBinaryWriter.WriteILBinaryStreamWithNoPDB
+ (stream,
+ { ilg = tcGlobals.ilg
+ pdbfile=pdbfile
+ emitTailcalls = tcConfig.emitTailcalls
+ deterministic = tcConfig.deterministic
+ showTimes = tcConfig.showTimes
+ portablePDB = tcConfig.portablePDB
+ embeddedPDB = tcConfig.embeddedPDB
+ embedAllSource = tcConfig.embedAllSource
+ embedSourceList = tcConfig.embedSourceList
+ sourceLink = tcConfig.sourceLink
+ checksumAlgorithm = tcConfig.checksumAlgorithm
+ signer = GetStrongNameSigner signingInfo
+ dumpDebugInfo = tcConfig.dumpDebugInfo
+ pathMap = tcConfig.pathMap },
+ true,
+ referenceAssemblyAttribOpt,
+ ilxMainModule,
+ normalizeAssemblyRefs
+ )
+ with Failure msg ->
+ error(Error(FSComp.SR.fscProblemWritingBinary(outfile, msg), rangeCmdArgs))
+
+ match tcConfig.emitMetadataAssembly with
+ | MetadataAssemblyGeneration.ReferenceOnly -> ()
+ | _ ->
+ try
+ ILBinaryWriter.WriteILBinary
+ (outfile,
+ { ilg = tcGlobals.ilg
+ pdbfile=pdbfile
+ emitTailcalls = tcConfig.emitTailcalls
+ deterministic = tcConfig.deterministic
+ showTimes = tcConfig.showTimes
+ portablePDB = tcConfig.portablePDB
+ embeddedPDB = tcConfig.embeddedPDB
+ embedAllSource = tcConfig.embedAllSource
+ embedSourceList = tcConfig.embedSourceList
+ sourceLink = tcConfig.sourceLink
+ checksumAlgorithm = tcConfig.checksumAlgorithm
+ signer = GetStrongNameSigner signingInfo
+ dumpDebugInfo = tcConfig.dumpDebugInfo
+ pathMap = tcConfig.pathMap },
+ ilxMainModule,
+ normalizeAssemblyRefs
+ )
+ with Failure msg ->
+ error(Error(FSComp.SR.fscProblemWritingBinary(outfile, msg), rangeCmdArgs))
with e ->
errorRecoveryNoRange e
exiter.Exit 1
diff --git a/src/fsharp/fscmain.fs b/src/fsharp/fscmain.fs
index d461f607afd..42458640fd6 100644
--- a/src/fsharp/fscmain.fs
+++ b/src/fsharp/fscmain.fs
@@ -48,8 +48,8 @@ let main(argv) =
// The F# compiler expects 'argv' to include the executable name, though it makes no use of it.
let argv = Array.append [| compilerName |] argv
-
- // Check for --pause as the very first step so that a compiler can be attached here.
+
+ // Check for --pause as the very first step so that a debugger can be attached here.
let pauseFlag = argv |> Array.exists (fun x -> x = "/pause" || x = "--pause")
if pauseFlag then
System.Console.WriteLine("Press return to continue...")
diff --git a/src/fsharp/pars.fsy b/src/fsharp/pars.fsy
index f9b5444a58d..213c8a5a129 100644
--- a/src/fsharp/pars.fsy
+++ b/src/fsharp/pars.fsy
@@ -827,8 +827,10 @@ moduleSpfn:
{ if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2))
let (SynExceptionSig(SynExceptionDefnRepr(cas, a, b, c, d, d2), withKeyword, members, range)) = $3
let xmlDoc = grabXmlDoc(parseState, $1, 1)
- let ec = SynExceptionSig(SynExceptionDefnRepr($1@cas, a, b, xmlDoc, d, d2), withKeyword, members, range)
- SynModuleSigDecl.Exception(ec, rhs parseState 3) }
+ let mDefnReprWithAttributes = (d2, $1) ||> unionRangeWithListBy (fun a -> a.Range)
+ let mWhole = (mDefnReprWithAttributes, members) ||> unionRangeWithListBy (fun (m: SynMemberSig) -> m.Range)
+ let ec = SynExceptionSig(SynExceptionDefnRepr($1@cas, a, b, xmlDoc, d, mDefnReprWithAttributes), withKeyword, members, mWhole)
+ SynModuleSigDecl.Exception(ec, mWhole) }
| openDecl
{ SynModuleSigDecl.Open($1, (rhs parseState 1)) }
diff --git a/src/fsharp/service/FSharpCheckerResults.fs b/src/fsharp/service/FSharpCheckerResults.fs
index ada57d64b6e..0dcad7df786 100644
--- a/src/fsharp/service/FSharpCheckerResults.fs
+++ b/src/fsharp/service/FSharpCheckerResults.fs
@@ -15,6 +15,7 @@ open Internal.Utilities.Library
open Internal.Utilities.Library.Extras
open FSharp.Core.Printf
open FSharp.Compiler
+open FSharp.Compiler.Syntax
open FSharp.Compiler.AbstractIL.IL
open FSharp.Compiler.AccessibilityLogic
open FSharp.Compiler.CheckExpressions
@@ -46,6 +47,10 @@ open FSharp.Compiler.Text.Position
open FSharp.Compiler.Text.Range
open FSharp.Compiler.TypedTree
open FSharp.Compiler.TypedTreeOps
+open FSharp.Compiler.AbstractIL
+open System.Reflection.PortableExecutable
+open FSharp.Compiler.CreateILModule
+open FSharp.Compiler.IlxGen
open FSharp.Compiler.BuildGraph
open Internal.Utilities
@@ -2206,7 +2211,7 @@ type FSharpCheckProjectResults
keepAssemblyContents: bool,
diagnostics: FSharpDiagnostic[],
details:(TcGlobals * TcImports * CcuThunk * ModuleOrNamespaceType * Choice *
- TopAttribs option * ILAssemblyRef *
+ TopAttribs option * (unit -> IRawFSharpAssemblyData option) * ILAssemblyRef *
AccessorDomain * TypedImplFile list option * string[] * FSharpProjectOptions) option) =
let getDetails() =
@@ -2224,12 +2229,12 @@ type FSharpCheckProjectResults
member _.HasCriticalErrors = details.IsNone
member _.AssemblySignature =
- let tcGlobals, tcImports, thisCcu, ccuSig, _builderOrSymbolUses, topAttribs, _ilAssemRef, _ad, _tcAssemblyExpr, _dependencyFiles, _projectOptions = getDetails()
+ let tcGlobals, tcImports, thisCcu, ccuSig, _builderOrSymbolUses, topAttribs, _tcAssemblyData, _ilAssemRef, _ad, _tcAssemblyExpr, _dependencyFiles, _projectOptions = getDetails()
FSharpAssemblySignature(tcGlobals, thisCcu, ccuSig, tcImports, topAttribs, ccuSig)
member _.TypedImplementationFiles =
if not keepAssemblyContents then invalidOp "The 'keepAssemblyContents' flag must be set to true on the FSharpChecker in order to access the checked contents of assemblies"
- let tcGlobals, tcImports, thisCcu, _ccuSig, _builderOrSymbolUses, _topAttribs, _ilAssemRef, _ad, tcAssemblyExpr, _dependencyFiles, _projectOptions = getDetails()
+ let tcGlobals, tcImports, thisCcu, _ccuSig, _builderOrSymbolUses, _topAttribs, _tcAssemblyData, _ilAssemRef, _ad, tcAssemblyExpr, _dependencyFiles, _projectOptions = getDetails()
let mimpls =
match tcAssemblyExpr with
| None -> []
@@ -2238,7 +2243,7 @@ type FSharpCheckProjectResults
member info.AssemblyContents =
if not keepAssemblyContents then invalidOp "The 'keepAssemblyContents' flag must be set to true on the FSharpChecker in order to access the checked contents of assemblies"
- let tcGlobals, tcImports, thisCcu, ccuSig, _builderOrSymbolUses, _topAttribs, _ilAssemRef, _ad, tcAssemblyExpr, _dependencyFiles, _projectOptions = getDetails()
+ let tcGlobals, tcImports, thisCcu, ccuSig, _builderOrSymbolUses, _topAttribs, _tcAssemblyData, _ilAssemRef, _ad, tcAssemblyExpr, _dependencyFiles, _projectOptions = getDetails()
let mimpls =
match tcAssemblyExpr with
| None -> []
@@ -2247,7 +2252,7 @@ type FSharpCheckProjectResults
member _.GetOptimizedAssemblyContents() =
if not keepAssemblyContents then invalidOp "The 'keepAssemblyContents' flag must be set to true on the FSharpChecker in order to access the checked contents of assemblies"
- let tcGlobals, tcImports, thisCcu, ccuSig, _builderOrSymbolUses, _topAttribs, _ilAssemRef, _ad, tcAssemblyExpr, _dependencyFiles, _projectOptions = getDetails()
+ let tcGlobals, tcImports, thisCcu, ccuSig, _builderOrSymbolUses, _topAttribs, _tcAssemblyData, _ilAssemRef, _ad, tcAssemblyExpr, _dependencyFiles, _projectOptions = getDetails()
let mimpls =
match tcAssemblyExpr with
| None -> []
@@ -2266,7 +2271,7 @@ type FSharpCheckProjectResults
// Not, this does not have to be a SyncOp, it can be called from any thread
member _.GetUsesOfSymbol(symbol:FSharpSymbol, ?cancellationToken: CancellationToken) =
- let _, _tcImports, _thisCcu, _ccuSig, builderOrSymbolUses, _topAttribs, _ilAssemRef, _ad, _tcAssemblyExpr, _dependencyFiles, _projectOptions = getDetails()
+ let _, _tcImports, _thisCcu, _ccuSig, builderOrSymbolUses, _topAttribs, _tcAssemblyData, _ilAssemRef, _ad, _tcAssemblyExpr, _dependencyFiles, _projectOptions = getDetails()
let results =
match builderOrSymbolUses with
@@ -2297,7 +2302,7 @@ type FSharpCheckProjectResults
// Not, this does not have to be a SyncOp, it can be called from any thread
member _.GetAllUsesOfAllSymbols(?cancellationToken: CancellationToken) =
- let tcGlobals, tcImports, thisCcu, ccuSig, builderOrSymbolUses, _topAttribs, _ilAssemRef, _ad, _tcAssemblyExpr, _dependencyFiles, _projectOptions = getDetails()
+ let tcGlobals, tcImports, thisCcu, ccuSig, builderOrSymbolUses, _topAttribs, _ilAssemRef, _tcAssemblyData, _ad, _tcAssemblyExpr, _dependencyFiles, _projectOptions = getDetails()
let cenv = SymbolEnv(tcGlobals, thisCcu, Some ccuSig, tcImports)
let tcSymbolUses =
@@ -2328,18 +2333,18 @@ type FSharpCheckProjectResults
yield FSharpSymbolUse(symbolUse.DisplayEnv, symbol, symbolUse.ItemWithInst.TyparInst, symbolUse.ItemOccurence, symbolUse.Range) |]
member _.ProjectContext =
- let tcGlobals, tcImports, thisCcu, _ccuSig, _tcSymbolUses, _topAttribs, _ilAssemRef, ad, _tcAssemblyExpr, _dependencyFiles, projectOptions = getDetails()
+ let tcGlobals, tcImports, thisCcu, _ccuSig, _tcSymbolUses, _topAttribs, _tcAssemblyData, _ilAssemRef, ad, _tcAssemblyExpr, _dependencyFiles, projectOptions = getDetails()
let assemblies =
tcImports.GetImportedAssemblies()
|> List.map (fun x -> FSharpAssembly(tcGlobals, tcImports, x.FSharpViewOfMetadata))
FSharpProjectContext(thisCcu, assemblies, ad, projectOptions)
member _.DependencyFiles =
- let _tcGlobals, _tcImports, _thisCcu, _ccuSig, _tcSymbolUses, _topAttribs, _ilAssemRef, _ad, _tcAssemblyExpr, dependencyFiles, _projectOptions = getDetails()
+ let _tcGlobals, _tcImports, _thisCcu, _ccuSig, _tcSymbolUses, _topAttribs, _tcAssemblyData, _ilAssemRef, _ad, _tcAssemblyExpr, dependencyFiles, _projectOptions = getDetails()
dependencyFiles
member _.AssemblyFullName =
- let _tcGlobals, _tcImports, _thisCcu, _ccuSig, _tcSymbolUses, _topAttribs, ilAssemRef, _ad, _tcAssemblyExpr, _dependencyFiles, _projectOptions = getDetails()
+ let _tcGlobals, _tcImports, _thisCcu, _ccuSig, _tcSymbolUses, _topAttribs, _tcAssemblyData, ilAssemRef, _ad, _tcAssemblyExpr, _dependencyFiles, _projectOptions = getDetails()
ilAssemRef.QualifiedName
override _.ToString() = "FSharpCheckProjectResults(" + projectFileName + ")"
@@ -2409,7 +2414,7 @@ type FsiInteractiveChecker(legacyReferenceResolver,
FSharpCheckProjectResults (filename, Some tcConfig,
keepAssemblyContents, errors,
Some(tcGlobals, tcImports, tcFileInfo.ThisCcu, tcFileInfo.CcuSigForFile,
- (Choice2Of2 tcFileInfo.ScopeSymbolUses), None, mkSimpleAssemblyRef "stdin",
+ (Choice2Of2 tcFileInfo.ScopeSymbolUses), None, (fun () -> None), mkSimpleAssemblyRef "stdin",
tcState.TcEnvFromImpls.AccessRights, None, dependencyFiles,
projectOptions))
diff --git a/src/fsharp/service/FSharpCheckerResults.fsi b/src/fsharp/service/FSharpCheckerResults.fsi
index a32176b61ee..42303125268 100644
--- a/src/fsharp/service/FSharpCheckerResults.fsi
+++ b/src/fsharp/service/FSharpCheckerResults.fsi
@@ -473,6 +473,7 @@ type public FSharpCheckProjectResults =
ModuleOrNamespaceType *
Choice *
TopAttribs option *
+ (unit -> IRawFSharpAssemblyData option) *
ILAssemblyRef *
AccessorDomain *
TypedImplFile list option *
diff --git a/src/fsharp/service/ServiceParsedInputOps.fs b/src/fsharp/service/ServiceParsedInputOps.fs
index 7e5177af5af..bb7cad8ba01 100644
--- a/src/fsharp/service/ServiceParsedInputOps.fs
+++ b/src/fsharp/service/ServiceParsedInputOps.fs
@@ -1663,7 +1663,8 @@ module ParsedInput =
if isImplicitTopLevelModule then 1 else ctx.Pos.Line
else 1
| ScopeKind.Namespace ->
- // for namespaces the start line is start line of the first nested entity
+ // For namespaces the start line is start line of the first nested entity
+ // If we are not on the first line, try to find opening namespace, and return line after it (in F# format)
if ctx.Pos.Line > 1 then
[0..ctx.Pos.Line - 1]
|> List.mapi (fun i line -> i, getLineStr line)
@@ -1674,7 +1675,14 @@ module ParsedInput =
// move to the next line below "namespace" and convert it to F# 1-based line number
| Some line -> line + 2
| None -> ctx.Pos.Line
- else 1
+ // If we are on 1st line in the namespace ctx, this line _should_ be the namespace declaration, check it and return next line.
+ // Otherwise, return first line (which theoretically should not happen).
+ else
+ let lineStr = getLineStr (ctx.Pos.Line - 1)
+ if lineStr.StartsWithOrdinal("namespace") then
+ ctx.Pos.Line + 1
+ else
+ ctx.Pos.Line
| _ -> ctx.Pos.Line
mkPos line ctx.Pos.Column
diff --git a/src/fsharp/service/service.fs b/src/fsharp/service/service.fs
index 557c94acb5f..a49e7aa3666 100644
--- a/src/fsharp/service/service.fs
+++ b/src/fsharp/service/service.fs
@@ -807,7 +807,7 @@ type BackgroundCompiler(
| None ->
return FSharpCheckProjectResults (options.ProjectFileName, None, keepAssemblyContents, creationDiags, None)
| Some builder ->
- let! tcProj, ilAssemRef, _, tcAssemblyExprOpt = builder.GetFullCheckResultsAndImplementationsForProject()
+ let! tcProj, ilAssemRef, tcAssemblyDataOpt, tcAssemblyExprOpt = builder.GetFullCheckResultsAndImplementationsForProject()
let errorOptions = tcProj.TcConfig.errorSeverityOptions
let fileName = DummyFileNameForRangesWithoutASpecificLocation
@@ -822,6 +822,12 @@ type BackgroundCompiler(
let diagnostics =
[| yield! creationDiags;
yield! DiagnosticHelpers.CreateDiagnostics (errorOptions, true, fileName, tcErrors, suggestNamesForErrors) |]
+
+ let getAssemblyData() =
+ match tcAssemblyDataOpt with
+ | ProjectAssemblyDataResult.Available data -> Some data
+ | _ -> None
+
let results =
FSharpCheckProjectResults
(options.ProjectFileName,
@@ -829,7 +835,7 @@ type BackgroundCompiler(
keepAssemblyContents,
diagnostics,
Some(tcProj.TcGlobals, tcProj.TcImports, tcState.Ccu, tcState.CcuSig,
- (Choice1Of2 builder), topAttribs, ilAssemRef,
+ (Choice1Of2 builder), topAttribs, getAssemblyData, ilAssemRef,
tcEnvAtEnd.AccessRights, tcAssemblyExprOpt,
Array.ofList tcDependencyFiles,
options))
diff --git a/src/fsharp/symbols/Symbols.fs b/src/fsharp/symbols/Symbols.fs
index ed1b773140b..ed857c0db0b 100644
--- a/src/fsharp/symbols/Symbols.fs
+++ b/src/fsharp/symbols/Symbols.fs
@@ -33,18 +33,18 @@ type FSharpAccessibility(a:Accessibility, ?isProtected) =
match x with
| CompPath(ILScopeRef.Local, []) -> true
| _ -> false
-
+
let (|Public|Internal|Private|) (TAccess p) =
match p with
| [] -> Public
- | _ when List.forall isInternalCompPath p -> Internal
+ | _ when List.forall isInternalCompPath p -> Internal
| _ -> Private
- member _.IsPublic = not isProtected && match a with TAccess [] -> true | _ -> false
+ member _.IsPublic = not isProtected && (match a with TAccess [] -> true | _ -> false)
- member _.IsPrivate = not isProtected && match a with Private -> true | _ -> false
+ member _.IsPrivate = not isProtected && (match a with Private -> true | _ -> false)
- member _.IsInternal = not isProtected && match a with Internal -> true | _ -> false
+ member _.IsInternal = not isProtected && (match a with Internal -> true | _ -> false)
member _.IsProtected = isProtected
diff --git a/src/fsharp/xlf/FSComp.txt.cs.xlf b/src/fsharp/xlf/FSComp.txt.cs.xlf
index d93fe994766..0431b2cb8a4 100644
--- a/src/fsharp/xlf/FSComp.txt.cs.xlf
+++ b/src/fsharp/xlf/FSComp.txt.cs.xlf
@@ -289,7 +289,7 @@
The 'from the end slicing' feature requires language version 'preview'.
- The 'from the end slicing' feature requires language version 'preview'.
+ Funkce vytváření průřezů od konce vyžaduje jazykovou verzi preview.
@@ -407,11 +407,31 @@
Vytiskněte odvozená rozhraní všech kompilovaných souborů do přidružených souborů podpisu.
+
+ Invalid use of emitting a reference assembly. Check the compiler options to not specify static linking, or using '--refonly' and '--refout' together.
+ Invalid use of emitting a reference assembly. Check the compiler options to not specify static linking, or using '--refonly' and '--refout' together.
+
+
+
+ Invalid reference assembly path'
+ Invalid reference assembly path'
+
+ Display the allowed values for language version, specify language version such as 'latest' or 'preview'Zobrazte si povolené hodnoty verze jazyka a pak zadejte požadovanou verzi, například latest nebo preview.
+
+ Produce a reference assembly, instead of a full assembly, as the primary output
+ Produce a reference assembly, instead of a full assembly, as the primary output
+
+
+
+ Produce a reference assembly with the specified file path.
+ Produce a reference assembly with the specified file path.
+
+ Supported language versions:Podporované jazykové verze:
@@ -434,7 +454,7 @@
The 'package management' feature requires language version 5.0 or above
- The 'package management' feature requires language version 5.0 or above
+ Funkce správy balíčků vyžaduje jazykovou verzi 5.0 nebo vyšší.
@@ -649,7 +669,7 @@
Invalid member declaration. The name of the member is missing or has parentheses.
- Invalid member declaration. The name of the member is missing or has parentheses.
+ Neplatná deklarace člena. Jeho jméno chybí nebo obsahuje závorky.
diff --git a/src/fsharp/xlf/FSComp.txt.de.xlf b/src/fsharp/xlf/FSComp.txt.de.xlf
index 638a9a8de5d..448cf3ac1b3 100644
--- a/src/fsharp/xlf/FSComp.txt.de.xlf
+++ b/src/fsharp/xlf/FSComp.txt.de.xlf
@@ -289,7 +289,7 @@
The 'from the end slicing' feature requires language version 'preview'.
- The 'from the end slicing' feature requires language version 'preview'.
+ Für das Feature „Vom Ende ausgehende Slicing“ ist Sprachversion „Vorschau“ erforderlich.
@@ -407,11 +407,31 @@
Drucken der abgeleiteten Schnittstellen aller Dateien an zugehörige Signaturdateien
+
+ Invalid use of emitting a reference assembly. Check the compiler options to not specify static linking, or using '--refonly' and '--refout' together.
+ Invalid use of emitting a reference assembly. Check the compiler options to not specify static linking, or using '--refonly' and '--refout' together.
+
+
+
+ Invalid reference assembly path'
+ Invalid reference assembly path'
+
+ Display the allowed values for language version, specify language version such as 'latest' or 'preview'Zeigen Sie die zulässigen Werte für die Sprachversion an. Geben Sie die Sprachversion als "latest" oder "preview" an.
+
+ Produce a reference assembly, instead of a full assembly, as the primary output
+ Produce a reference assembly, instead of a full assembly, as the primary output
+
+
+
+ Produce a reference assembly with the specified file path.
+ Produce a reference assembly with the specified file path.
+
+ Supported language versions:Unterstützte Sprachversionen:
@@ -434,7 +454,7 @@
The 'package management' feature requires language version 5.0 or above
- The 'package management' feature requires language version 5.0 or above
+ Für das „Paketverwaltungsfeature“ ist Sprachversion 5.0 oder höher erforderlich
@@ -649,7 +669,7 @@
Invalid member declaration. The name of the member is missing or has parentheses.
- Invalid member declaration. The name of the member is missing or has parentheses.
+ Ungültige Memberdeklaration. Der Name des Members fehlt oder ist in Klammern.
diff --git a/src/fsharp/xlf/FSComp.txt.es.xlf b/src/fsharp/xlf/FSComp.txt.es.xlf
index b7ced72c91b..3bd6b38e8a6 100644
--- a/src/fsharp/xlf/FSComp.txt.es.xlf
+++ b/src/fsharp/xlf/FSComp.txt.es.xlf
@@ -289,7 +289,7 @@
The 'from the end slicing' feature requires language version 'preview'.
- The 'from the end slicing' feature requires language version 'preview'.
+ La característica "desde el final del recorte" requiere la versión de lenguaje "preview" (vista previa).
@@ -407,11 +407,31 @@
Imprimir las interfaces deducidas de todos los archivos de compilación en los archivos de signatura asociados
+
+ Invalid use of emitting a reference assembly. Check the compiler options to not specify static linking, or using '--refonly' and '--refout' together.
+ Invalid use of emitting a reference assembly. Check the compiler options to not specify static linking, or using '--refonly' and '--refout' together.
+
+
+
+ Invalid reference assembly path'
+ Invalid reference assembly path'
+
+ Display the allowed values for language version, specify language version such as 'latest' or 'preview'Mostrar los valores permitidos para la versión de idioma, especificar la versión de idioma como "latest" "preview"
+
+ Produce a reference assembly, instead of a full assembly, as the primary output
+ Produce a reference assembly, instead of a full assembly, as the primary output
+
+
+
+ Produce a reference assembly with the specified file path.
+ Produce a reference assembly with the specified file path.
+
+ Supported language versions:Versiones de lenguaje admitidas:
@@ -434,7 +454,7 @@
The 'package management' feature requires language version 5.0 or above
- The 'package management' feature requires language version 5.0 or above
+ La característica de "administración de paquetes" requiere la versión de lenguaje 5.0 o superior
@@ -649,7 +669,7 @@
Invalid member declaration. The name of the member is missing or has parentheses.
- Invalid member declaration. The name of the member is missing or has parentheses.
+ Declaración de miembro no válida. Falta el nombre del miembro o tiene paréntesis.
diff --git a/src/fsharp/xlf/FSComp.txt.fr.xlf b/src/fsharp/xlf/FSComp.txt.fr.xlf
index 52c3fdcea86..575166ffb4c 100644
--- a/src/fsharp/xlf/FSComp.txt.fr.xlf
+++ b/src/fsharp/xlf/FSComp.txt.fr.xlf
@@ -289,7 +289,7 @@
The 'from the end slicing' feature requires language version 'preview'.
- The 'from the end slicing' feature requires language version 'preview'.
+ La fonctionnalité « from the end slicing » nécessite la version de langage « preview ».
@@ -407,11 +407,31 @@
Imprimer les interfaces inférées de tous les fichiers de compilation sur les fichiers de signature associés
+
+ Invalid use of emitting a reference assembly. Check the compiler options to not specify static linking, or using '--refonly' and '--refout' together.
+ Invalid use of emitting a reference assembly. Check the compiler options to not specify static linking, or using '--refonly' and '--refout' together.
+
+
+
+ Invalid reference assembly path'
+ Invalid reference assembly path'
+
+ Display the allowed values for language version, specify language version such as 'latest' or 'preview'Afficher les valeurs autorisées pour la version du langage, spécifier la version du langage comme 'dernière' ou 'préversion'
+
+ Produce a reference assembly, instead of a full assembly, as the primary output
+ Produce a reference assembly, instead of a full assembly, as the primary output
+
+
+
+ Produce a reference assembly with the specified file path.
+ Produce a reference assembly with the specified file path.
+
+ Supported language versions:Versions linguistiques prises en charge :
@@ -434,7 +454,7 @@
The 'package management' feature requires language version 5.0 or above
- The 'package management' feature requires language version 5.0 or above
+ La fonction « gestion des paquets » nécessite une version de langue 5.0 ou supérieure.
@@ -649,7 +669,7 @@
Invalid member declaration. The name of the member is missing or has parentheses.
- Invalid member declaration. The name of the member is missing or has parentheses.
+ Déclaration de membre non valide. Le nom du membre est manquant ou comporte des parenthèses.
diff --git a/src/fsharp/xlf/FSComp.txt.it.xlf b/src/fsharp/xlf/FSComp.txt.it.xlf
index 249887688fd..ec8fc05495c 100644
--- a/src/fsharp/xlf/FSComp.txt.it.xlf
+++ b/src/fsharp/xlf/FSComp.txt.it.xlf
@@ -289,7 +289,7 @@
The 'from the end slicing' feature requires language version 'preview'.
- The 'from the end slicing' feature requires language version 'preview'.
+ La funzionalità 'sezionamento dalla fine' richiede la versione del linguaggio 'anteprima'.
@@ -407,11 +407,31 @@
Stampare le interfacce derivate di tutti i file di compilazione nei file di firma associati
+
+ Invalid use of emitting a reference assembly. Check the compiler options to not specify static linking, or using '--refonly' and '--refout' together.
+ Invalid use of emitting a reference assembly. Check the compiler options to not specify static linking, or using '--refonly' and '--refout' together.
+
+
+
+ Invalid reference assembly path'
+ Invalid reference assembly path'
+
+ Display the allowed values for language version, specify language version such as 'latest' or 'preview'Visualizza i valori consentiti per la versione del linguaggio. Specificare la versione del linguaggio, ad esempio 'latest' o 'preview'
+
+ Produce a reference assembly, instead of a full assembly, as the primary output
+ Produce a reference assembly, instead of a full assembly, as the primary output
+
+
+
+ Produce a reference assembly with the specified file path.
+ Produce a reference assembly with the specified file path.
+
+ Supported language versions:Versioni del linguaggio supportate:
@@ -434,7 +454,7 @@
The 'package management' feature requires language version 5.0 or above
- The 'package management' feature requires language version 5.0 or above
+ La funzionalità 'gestione pacchetti' richiede la versione del linguaggio 5.0 o superiore
@@ -649,7 +669,7 @@
Invalid member declaration. The name of the member is missing or has parentheses.
- Invalid member declaration. The name of the member is missing or has parentheses.
+ Dichiarazione di membro non valida. Il nome del membro manca o contiene parentesi.
diff --git a/src/fsharp/xlf/FSComp.txt.ja.xlf b/src/fsharp/xlf/FSComp.txt.ja.xlf
index 15c5da75f0d..4f28abfabde 100644
--- a/src/fsharp/xlf/FSComp.txt.ja.xlf
+++ b/src/fsharp/xlf/FSComp.txt.ja.xlf
@@ -289,7 +289,7 @@
The 'from the end slicing' feature requires language version 'preview'.
- The 'from the end slicing' feature requires language version 'preview'.
+ 'from the end slicing' (最後からのスライス) 機能には、言語バージョン 'preview' が必要です。
@@ -407,11 +407,31 @@
すべてのコンパイル ファイルの推定されたインターフェイスを関連する署名ファイルに印刷します
+
+ Invalid use of emitting a reference assembly. Check the compiler options to not specify static linking, or using '--refonly' and '--refout' together.
+ Invalid use of emitting a reference assembly. Check the compiler options to not specify static linking, or using '--refonly' and '--refout' together.
+
+
+
+ Invalid reference assembly path'
+ Invalid reference assembly path'
+
+ Display the allowed values for language version, specify language version such as 'latest' or 'preview'言語バージョンで許可された値を表示し、'最新' や 'プレビュー' などの言語バージョンを指定する
+
+ Produce a reference assembly, instead of a full assembly, as the primary output
+ Produce a reference assembly, instead of a full assembly, as the primary output
+
+
+
+ Produce a reference assembly with the specified file path.
+ Produce a reference assembly with the specified file path.
+
+ Supported language versions:サポートされる言語バージョン:
@@ -434,7 +454,7 @@
The 'package management' feature requires language version 5.0 or above
- The 'package management' feature requires language version 5.0 or above
+ 'package management' (パッケージ管理) 機能には、言語バージョン 5.0 以降が必要です
@@ -649,7 +669,7 @@
Invalid member declaration. The name of the member is missing or has parentheses.
- Invalid member declaration. The name of the member is missing or has parentheses.
+ メンバーの宣言が無効です。メンバーの名前が見つからないか、かっこが含まれています。
diff --git a/src/fsharp/xlf/FSComp.txt.ko.xlf b/src/fsharp/xlf/FSComp.txt.ko.xlf
index 8f28ff6bc5a..ae5d5a74eef 100644
--- a/src/fsharp/xlf/FSComp.txt.ko.xlf
+++ b/src/fsharp/xlf/FSComp.txt.ko.xlf
@@ -289,7 +289,7 @@
The 'from the end slicing' feature requires language version 'preview'.
- The 'from the end slicing' feature requires language version 'preview'.
+ '끝에서부터 조각화' 기능을 사용하려면 언어 버전 '미리 보기'가 필요합니다.
@@ -407,11 +407,31 @@
모든 컴파일 파일의 유추된 인터페이스를 관련 서명 파일로 인쇄합니다.
+
+ Invalid use of emitting a reference assembly. Check the compiler options to not specify static linking, or using '--refonly' and '--refout' together.
+ Invalid use of emitting a reference assembly. Check the compiler options to not specify static linking, or using '--refonly' and '--refout' together.
+
+
+
+ Invalid reference assembly path'
+ Invalid reference assembly path'
+
+ Display the allowed values for language version, specify language version such as 'latest' or 'preview'언어 버전의 허용된 값을 표시하고 '최신' 또는 '미리 보기'와 같은 언어 버전을 지정합니다.
+
+ Produce a reference assembly, instead of a full assembly, as the primary output
+ Produce a reference assembly, instead of a full assembly, as the primary output
+
+
+
+ Produce a reference assembly with the specified file path.
+ Produce a reference assembly with the specified file path.
+
+ Supported language versions:지원되는 언어 버전:
@@ -434,7 +454,7 @@
The 'package management' feature requires language version 5.0 or above
- The 'package management' feature requires language version 5.0 or above
+ '패키지 관리' 기능을 사용하려면 언어 버전 5.0 이상이 필요합니다.
@@ -649,7 +669,7 @@
Invalid member declaration. The name of the member is missing or has parentheses.
- Invalid member declaration. The name of the member is missing or has parentheses.
+ 멤버 선언이 잘못되었습니다. 멤버 이름이 없거나 괄호가 있습니다.
diff --git a/src/fsharp/xlf/FSComp.txt.pl.xlf b/src/fsharp/xlf/FSComp.txt.pl.xlf
index 70627d2892b..aaccee27ffa 100644
--- a/src/fsharp/xlf/FSComp.txt.pl.xlf
+++ b/src/fsharp/xlf/FSComp.txt.pl.xlf
@@ -289,7 +289,7 @@
The 'from the end slicing' feature requires language version 'preview'.
- The 'from the end slicing' feature requires language version 'preview'.
+ Funkcja „Przycinanie od końca” wymaga „podglądu” wersji językowej.
@@ -407,11 +407,31 @@
Drukowanie wywnioskowanych interfejsów wszystkich plików kompilacji do skojarzonych plików sygnatur
+
+ Invalid use of emitting a reference assembly. Check the compiler options to not specify static linking, or using '--refonly' and '--refout' together.
+ Invalid use of emitting a reference assembly. Check the compiler options to not specify static linking, or using '--refonly' and '--refout' together.
+
+
+
+ Invalid reference assembly path'
+ Invalid reference assembly path'
+
+ Display the allowed values for language version, specify language version such as 'latest' or 'preview'Wyświetl dozwolone wartości dla wersji językowej; określ wersję językową, np. „latest” lub „preview”
+
+ Produce a reference assembly, instead of a full assembly, as the primary output
+ Produce a reference assembly, instead of a full assembly, as the primary output
+
+
+
+ Produce a reference assembly with the specified file path.
+ Produce a reference assembly with the specified file path.
+
+ Supported language versions:Obsługiwane wersje językowe:
@@ -434,7 +454,7 @@
The 'package management' feature requires language version 5.0 or above
- The 'package management' feature requires language version 5.0 or above
+ Funkcja „Zarządzanie pakietami” wymaga języka w wersji 5.0 lub nowszej
@@ -649,7 +669,7 @@
Invalid member declaration. The name of the member is missing or has parentheses.
- Invalid member declaration. The name of the member is missing or has parentheses.
+ Nieprawidłowa deklaracja elementu członkowskiego. Brak nazwy elementu członkowskiego lub ma ona nawiasy.
diff --git a/src/fsharp/xlf/FSComp.txt.pt-BR.xlf b/src/fsharp/xlf/FSComp.txt.pt-BR.xlf
index 26e583b87bf..16496b3d78f 100644
--- a/src/fsharp/xlf/FSComp.txt.pt-BR.xlf
+++ b/src/fsharp/xlf/FSComp.txt.pt-BR.xlf
@@ -289,7 +289,7 @@
The 'from the end slicing' feature requires language version 'preview'.
- The 'from the end slicing' feature requires language version 'preview'.
+ O recurso 'da divisão final' requer a versão de idioma 'preview'.
@@ -407,11 +407,31 @@
Imprimir as interfaces inferidas de todos os arquivos de compilação para os arquivos de assinatura associados
+
+ Invalid use of emitting a reference assembly. Check the compiler options to not specify static linking, or using '--refonly' and '--refout' together.
+ Invalid use of emitting a reference assembly. Check the compiler options to not specify static linking, or using '--refonly' and '--refout' together.
+
+
+
+ Invalid reference assembly path'
+ Invalid reference assembly path'
+
+ Display the allowed values for language version, specify language version such as 'latest' or 'preview'Exibe os valores permitidos para a versão do idioma, especifica a versão do idioma, como 'mais recente ' ou 'prévia'
+
+ Produce a reference assembly, instead of a full assembly, as the primary output
+ Produce a reference assembly, instead of a full assembly, as the primary output
+
+
+
+ Produce a reference assembly with the specified file path.
+ Produce a reference assembly with the specified file path.
+
+ Supported language versions:Versões de linguagens com suporte:
@@ -434,7 +454,7 @@
The 'package management' feature requires language version 5.0 or above
- The 'package management' feature requires language version 5.0 or above
+ O recurso 'gerenciamento de pacotes' requer a versão 5.0 ou superior do idioma
@@ -649,7 +669,7 @@
Invalid member declaration. The name of the member is missing or has parentheses.
- Invalid member declaration. The name of the member is missing or has parentheses.
+ Declaração de membro inválida. O nome do membro está ausente ou tem parênteses.
diff --git a/src/fsharp/xlf/FSComp.txt.ru.xlf b/src/fsharp/xlf/FSComp.txt.ru.xlf
index 8b2d5dcc6e3..c3e3ce97be5 100644
--- a/src/fsharp/xlf/FSComp.txt.ru.xlf
+++ b/src/fsharp/xlf/FSComp.txt.ru.xlf
@@ -289,7 +289,7 @@
The 'from the end slicing' feature requires language version 'preview'.
- The 'from the end slicing' feature requires language version 'preview'.
+ Для функции конечного среза требуется "предварительная" версия языка.
@@ -407,11 +407,31 @@
Печать определяемых интерфейсов всех файлов компиляции в связанные файлы подписей
+
+ Invalid use of emitting a reference assembly. Check the compiler options to not specify static linking, or using '--refonly' and '--refout' together.
+ Invalid use of emitting a reference assembly. Check the compiler options to not specify static linking, or using '--refonly' and '--refout' together.
+
+
+
+ Invalid reference assembly path'
+ Invalid reference assembly path'
+
+ Display the allowed values for language version, specify language version such as 'latest' or 'preview'Отображение допустимых значений для версии языка. Укажите версию языка, например, "latest" или "preview".
+
+ Produce a reference assembly, instead of a full assembly, as the primary output
+ Produce a reference assembly, instead of a full assembly, as the primary output
+
+
+
+ Produce a reference assembly with the specified file path.
+ Produce a reference assembly with the specified file path.
+
+ Supported language versions:Поддерживаемые языковые версии:
@@ -434,7 +454,7 @@
The 'package management' feature requires language version 5.0 or above
- The 'package management' feature requires language version 5.0 or above
+ Для функции управления пакетами требуется версия языка 5.0 или более поздняя
@@ -649,7 +669,7 @@
Invalid member declaration. The name of the member is missing or has parentheses.
- Invalid member declaration. The name of the member is missing or has parentheses.
+ Недопустимое объявление элемента. Имя элемента отсутствует или содержит скобки.
diff --git a/src/fsharp/xlf/FSComp.txt.tr.xlf b/src/fsharp/xlf/FSComp.txt.tr.xlf
index de3cedeb938..5ad2de1bcd7 100644
--- a/src/fsharp/xlf/FSComp.txt.tr.xlf
+++ b/src/fsharp/xlf/FSComp.txt.tr.xlf
@@ -289,7 +289,7 @@
The 'from the end slicing' feature requires language version 'preview'.
- The 'from the end slicing' feature requires language version 'preview'.
+ 'Uçtan dilimleme' özelliği, 'önizleme' dil sürümünü gerektirir.
@@ -407,11 +407,31 @@
Tüm derleme dosyalarının çıkarsanan arabirimlerini ilişkili imza dosyalarına yazdır
+
+ Invalid use of emitting a reference assembly. Check the compiler options to not specify static linking, or using '--refonly' and '--refout' together.
+ Invalid use of emitting a reference assembly. Check the compiler options to not specify static linking, or using '--refonly' and '--refout' together.
+
+
+
+ Invalid reference assembly path'
+ Invalid reference assembly path'
+
+ Display the allowed values for language version, specify language version such as 'latest' or 'preview'Dil sürümü için izin verilen değerleri görüntüleyin, dil sürümünü 'en son' veya 'önizleme' örneklerindeki gibi belirtin
+
+ Produce a reference assembly, instead of a full assembly, as the primary output
+ Produce a reference assembly, instead of a full assembly, as the primary output
+
+
+
+ Produce a reference assembly with the specified file path.
+ Produce a reference assembly with the specified file path.
+
+ Supported language versions:Desteklenen dil sürümleri:
@@ -434,7 +454,7 @@
The 'package management' feature requires language version 5.0 or above
- The 'package management' feature requires language version 5.0 or above
+ ‘Paket yönetimi’ özelliği, dil sürümü 5.0 veya üstünü gerektirir
@@ -649,7 +669,7 @@
Invalid member declaration. The name of the member is missing or has parentheses.
- Invalid member declaration. The name of the member is missing or has parentheses.
+ Geçersiz üye bildirimi. Üyenin adı eksik veya parantez içeriyor.
diff --git a/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf b/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf
index b2a5c4075fd..7fd15ff380d 100644
--- a/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf
+++ b/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf
@@ -289,7 +289,7 @@
The 'from the end slicing' feature requires language version 'preview'.
- The 'from the end slicing' feature requires language version 'preview'.
+ “从末尾切片”功能需要语言版本“预览”。
@@ -407,11 +407,31 @@
将所有编译文件的推断接口打印到关联的签名文件
+
+ Invalid use of emitting a reference assembly. Check the compiler options to not specify static linking, or using '--refonly' and '--refout' together.
+ Invalid use of emitting a reference assembly. Check the compiler options to not specify static linking, or using '--refonly' and '--refout' together.
+
+
+
+ Invalid reference assembly path'
+ Invalid reference assembly path'
+
+ Display the allowed values for language version, specify language version such as 'latest' or 'preview'显示语言版本的允许值,指定语言版本,如“最新”或“预览”
+
+ Produce a reference assembly, instead of a full assembly, as the primary output
+ Produce a reference assembly, instead of a full assembly, as the primary output
+
+
+
+ Produce a reference assembly with the specified file path.
+ Produce a reference assembly with the specified file path.
+
+ Supported language versions:支持的语言版本:
@@ -434,7 +454,7 @@
The 'package management' feature requires language version 5.0 or above
- The 'package management' feature requires language version 5.0 or above
+ “包管理”功能需要语言版本 5.0 或更高版本
@@ -649,7 +669,7 @@
Invalid member declaration. The name of the member is missing or has parentheses.
- Invalid member declaration. The name of the member is missing or has parentheses.
+ 成员声明无效。成员的名称缺失或包含括号。
diff --git a/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf b/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf
index 27dc0b27693..7070f080836 100644
--- a/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf
+++ b/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf
@@ -289,7 +289,7 @@
The 'from the end slicing' feature requires language version 'preview'.
- The 'from the end slicing' feature requires language version 'preview'.
+ 「從末端分割」功能需要語言版本「預覽」。
@@ -407,11 +407,31 @@
將所有編譯檔案的推斷介面列印至相關聯的簽章檔案
+
+ Invalid use of emitting a reference assembly. Check the compiler options to not specify static linking, or using '--refonly' and '--refout' together.
+ Invalid use of emitting a reference assembly. Check the compiler options to not specify static linking, or using '--refonly' and '--refout' together.
+
+
+
+ Invalid reference assembly path'
+ Invalid reference assembly path'
+
+ Display the allowed values for language version, specify language version such as 'latest' or 'preview'顯示語言版本允許的值,指定 'latest' 或 'preview' 等語言版本
+
+ Produce a reference assembly, instead of a full assembly, as the primary output
+ Produce a reference assembly, instead of a full assembly, as the primary output
+
+
+
+ Produce a reference assembly with the specified file path.
+ Produce a reference assembly with the specified file path.
+
+ Supported language versions:支援的語言版本:
@@ -434,7 +454,7 @@
The 'package management' feature requires language version 5.0 or above
- The 'package management' feature requires language version 5.0 or above
+ 「套件管理」功能需要語言版本 5.0 或更新版本
@@ -649,7 +669,7 @@
Invalid member declaration. The name of the member is missing or has parentheses.
- Invalid member declaration. The name of the member is missing or has parentheses.
+ 成員宣告無效。成員的名稱遺失或有括弧。
diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core.UnitTests.fsproj b/tests/FSharp.Core.UnitTests/FSharp.Core.UnitTests.fsproj
index aa39265d2a0..4602d100ff4 100644
--- a/tests/FSharp.Core.UnitTests/FSharp.Core.UnitTests.fsproj
+++ b/tests/FSharp.Core.UnitTests/FSharp.Core.UnitTests.fsproj
@@ -38,6 +38,7 @@
+
diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/RefStructs.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/RefStructs.fs
new file mode 100644
index 00000000000..8987d993bdb
--- /dev/null
+++ b/tests/FSharp.Core.UnitTests/FSharp.Core/RefStructs.fs
@@ -0,0 +1,32 @@
+// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
+
+namespace System.Runtime.CompilerServices
+
+#if NETCOREAPP
+open System
+
+[]
+type IsByRefLikeAttribute() = inherit Attribute()
+#endif
+
+namespace FSharp.Core.UnitTests
+
+#if NETCOREAPP
+open System
+open System.Runtime.CompilerServices
+open Xunit
+
+[]
+type SpanWrapper(span: Span) =
+ member _.Span = span
+
+type CustomIsByRefLikeAttributeTests() =
+ []
+ member _.TestSpanWrapper() =
+ let array = Array.init 5 id
+ let span = array.AsSpan()
+ let spanWrapper = SpanWrapper(span)
+ Assert.True(span.SequenceEqual(Span<_>.op_Implicit spanWrapper.Span))
+ Assert.Equal(array, spanWrapper.Span.ToArray())
+ ()
+#endif
diff --git a/tests/FSharp.Test.Utilities/Compiler.fs b/tests/FSharp.Test.Utilities/Compiler.fs
index 77f204b586b..50f5e9b24dc 100644
--- a/tests/FSharp.Test.Utilities/Compiler.fs
+++ b/tests/FSharp.Test.Utilities/Compiler.fs
@@ -16,6 +16,9 @@ open System.Collections.Immutable
open System.IO
open System.Text
open System.Text.RegularExpressions
+open System.Reflection
+open System.Reflection.Metadata
+open System.Reflection.PortableExecutable
module rec Compiler =
@@ -44,7 +47,8 @@ module rec Compiler =
SourceKind: SourceKind
Name: string option
IgnoreWarnings: bool
- References: CompilationUnit list }
+ References: CompilationUnit list
+ CompileDirectory: string option }
override this.ToString() = match this.Name with | Some n -> n | _ -> (sprintf "%A" this)
type CSharpCompilationSource =
@@ -110,14 +114,15 @@ module rec Compiler =
match source with
| null -> failwith "Source cannot be null"
| _ ->
- { Source = Text source
- Baseline = None
- Options = defaultOptions
- OutputType = Library
- SourceKind = kind
- Name = None
- IgnoreWarnings = false
- References = [] }
+ { Source = Text source
+ Baseline = None
+ Options = defaultOptions
+ OutputType = Library
+ SourceKind = kind
+ Name = None
+ IgnoreWarnings = false
+ References = []
+ CompileDirectory = None }
let private csFromString (source: string) : CSharpCompilationSource =
match source with
@@ -168,6 +173,20 @@ module rec Compiler =
let FSharp (source: string) : CompilationUnit =
fsFromString source SourceKind.Fs |> FS
+ let FSharpWithInputAndOutputPath (inputFilePath: string) (outputFilePath: string) : CompilationUnit =
+ let compileDirectory = Path.GetDirectoryName(outputFilePath)
+ let name = Path.GetFileName(outputFilePath)
+ { Source = Path(inputFilePath)
+ Baseline = None
+ Options = defaultOptions
+ OutputType = Library
+ SourceKind = SourceKind.Fs
+ Name = Some name
+ IgnoreWarnings = false
+ References = []
+ CompileDirectory = Some compileDirectory }
+ |> FS
+
let CSharp (source: string) : CompilationUnit =
csFromString source |> CS
@@ -309,7 +328,12 @@ module rec Compiler =
let references = processReferences fsSource.References
- let compilation = Compilation.Create(source, sourceKind, output, options, references)
+ let compilation =
+ match fsSource.CompileDirectory with
+ | Some compileDirectory ->
+ Compilation.Create(source, sourceKind, output, options, references, compileDirectory)
+ | _ ->
+ Compilation.Create(source, sourceKind, output, options, references)
compileFSharpCompilation compilation fsSource.IgnoreWarnings
@@ -369,6 +393,27 @@ module rec Compiler =
| CS cs -> compileCSharp cs
| _ -> failwith "TODO"
+ let private getAssemblyInBytes (result: TestResult) =
+ match result with
+ | Success output ->
+ match output.OutputPath with
+ | Some filePath -> File.ReadAllBytes(filePath)
+ | _ -> failwith "Output path not found."
+ | _ ->
+ failwith "Compilation has errors."
+
+ let compileGuid (cUnit: CompilationUnit) : Guid =
+ let bytes =
+ compile cUnit
+ |> shouldSucceed
+ |> getAssemblyInBytes
+
+ use reader1 = new PEReader(bytes.ToImmutableArray())
+ let reader1 = reader1.GetMetadataReader()
+
+ reader1.GetModuleDefinition().Mvid |> reader1.GetGuid
+
+
let private parseFSharp (fsSource: FSharpCompilationSource) : TestResult =
let source = getSource fsSource.Source
let fileName = if fsSource.SourceKind = SourceKind.Fsx then "test.fsx" else "test.fs"
@@ -560,6 +605,8 @@ module rec Compiler =
| Some p -> ILChecker.checkIL p il
| Failure _ -> failwith "Result should be \"Success\" in order to get IL."
+ let verifyILBinary (il: string list) (dll: string)= ILChecker.checkIL dll il
+
let private verifyFSILBaseline (baseline: Baseline option) (result: Output) : unit =
match baseline with
| None -> failwith "Baseline was not provided."
diff --git a/tests/FSharp.Test.Utilities/CompilerAssert.fs b/tests/FSharp.Test.Utilities/CompilerAssert.fs
index 261e7cd57b8..49d037c6292 100644
--- a/tests/FSharp.Test.Utilities/CompilerAssert.fs
+++ b/tests/FSharp.Test.Utilities/CompilerAssert.fs
@@ -63,12 +63,12 @@ type CompilationReference =
static member Create(cmpl: TestCompilation) =
TestCompilationReference cmpl
-and Compilation = private Compilation of source: string * SourceKind * CompileOutput * options: string[] * CompilationReference list * name: string option with
+and Compilation = private Compilation of source: string * SourceKind * CompileOutput * options: string[] * CompilationReference list * name: string option * compileDirectory: string option with
- static member Create(source, sourceKind, output, ?options, ?cmplRefs, ?name) =
+ static member Create(source, sourceKind, output, ?options, ?cmplRefs, ?name, ?compileDirectory) =
let options = defaultArg options [||]
let cmplRefs = defaultArg cmplRefs []
- Compilation(source, sourceKind, output, options, cmplRefs, name)
+ Compilation(source, sourceKind, output, options, cmplRefs, name, compileDirectory)
[]
type CompilerAssert private () =
@@ -201,7 +201,7 @@ type CompilerAssert private () =
static let rec compileCompilationAux outputPath (disposals: ResizeArray) ignoreWarnings (cmpl: Compilation) : (FSharpDiagnostic[] * string) * string list =
let compilationRefs, deps =
match cmpl with
- | Compilation(_, _, _, _, cmpls, _) ->
+ | Compilation(_, _, _, _, cmpls, _, _) ->
let compiledRefs =
cmpls
|> List.map (fun cmpl ->
@@ -242,29 +242,29 @@ type CompilerAssert private () =
let isScript =
match cmpl with
- | Compilation(_, kind, _, _, _, _) ->
+ | Compilation(_, kind, _, _, _, _, _) ->
match kind with
| Fs -> false
| Fsx -> true
let isExe =
match cmpl with
- | Compilation(_, _, output, _, _, _) ->
+ | Compilation(_, _, output, _, _, _, _) ->
match output with
| Library -> false
| Exe -> true
let source =
match cmpl with
- | Compilation(source, _, _, _, _, _) -> source
+ | Compilation(source, _, _, _, _, _, _) -> source
let options =
match cmpl with
- | Compilation(_, _, _, options, _, _) -> options
+ | Compilation(_, _, _, options, _, _, _) -> options
let nameOpt =
match cmpl with
- | Compilation(_, _, _, _, _, nameOpt) -> nameOpt
+ | Compilation(_, _, _, _, _, nameOpt, _) -> nameOpt
let disposal, res = compileDisposable outputPath isScript isExe (Array.append options compilationRefs) nameOpt source
disposals.Add disposal
@@ -278,7 +278,14 @@ type CompilerAssert private () =
res, (deps @ deps2)
static let rec compileCompilation ignoreWarnings (cmpl: Compilation) f =
- let compileDirectory = Path.Combine(Path.GetTempPath(), "CompilerAssert", Path.GetRandomFileName())
+ let compileDirectory =
+ match cmpl with
+ | Compilation(compileDirectory=compileDirectory) ->
+ match compileDirectory with
+ | None ->
+ CompilerAssert.GenerateDllOutputPath()
+ | Some compileDirectory ->
+ compileDirectory
let disposals = ResizeArray()
try
Directory.CreateDirectory(compileDirectory) |> ignore
@@ -292,7 +299,14 @@ type CompilerAssert private () =
// The reason behind is so we can compose verification of test runs easier.
// TODO: We must not rely on the filesystem when compiling
static let rec returnCompilation (cmpl: Compilation) ignoreWarnings =
- let compileDirectory = Path.Combine(Path.GetTempPath(), "CompilerAssert", Path.GetRandomFileName())
+ let compileDirectory =
+ match cmpl with
+ | Compilation(compileDirectory=compileDirectory) ->
+ match compileDirectory with
+ | None ->
+ CompilerAssert.GenerateDllOutputPath()
+ | Some compileDirectory ->
+ compileDirectory
Directory.CreateDirectory(compileDirectory) |> ignore
compileCompilationAux compileDirectory (ResizeArray()) ignoreWarnings cmpl
@@ -353,10 +367,23 @@ type CompilerAssert private () =
let exitCode, output, errors = Commands.executeProcess (Some filename) arguments (Path.GetDirectoryName(outputFilePath)) timeout
(exitCode, output |> String.concat "\n", errors |> String.concat "\n")
+ static let CompilerAssertTempPath = Path.Combine(Path.GetTempPath(), "CompilerAssert")
+ static let CreateCompilerAssertTempPath() =
+ if not (FileSystem.DirectoryExistsShim CompilerAssertTempPath) then
+ FileSystem.DirectoryCreateShim CompilerAssertTempPath |> ignore
+
static member Checker = checker
static member DefaultProjectOptions = defaultProjectOptions
+ static member GenerateFsInputPath() =
+ CreateCompilerAssertTempPath()
+ Path.Combine(CompilerAssertTempPath, Path.ChangeExtension(Path.GetRandomFileName(), ".fs"))
+
+ static member GenerateDllOutputPath() =
+ CreateCompilerAssertTempPath()
+ Path.Combine(CompilerAssertTempPath, Path.ChangeExtension(Path.GetRandomFileName(), ".dll"))
+
static member CompileWithErrors(cmpl: Compilation, expectedErrors, ?ignoreWarnings) =
let ignoreWarnings = defaultArg ignoreWarnings false
compileCompilation ignoreWarnings cmpl (fun ((errors, _), _) ->
diff --git a/tests/FSharp.Test.Utilities/ILChecker.fs b/tests/FSharp.Test.Utilities/ILChecker.fs
index 6357af6102d..a2ff9e5035d 100644
--- a/tests/FSharp.Test.Utilities/ILChecker.fs
+++ b/tests/FSharp.Test.Utilities/ILChecker.fs
@@ -48,7 +48,7 @@ module ILChecker =
let unifyRuntimeAssemblyName ilCode =
System.Text.RegularExpressions.Regex.Replace(ilCode,
- "\[System.Runtime\]|\[System.Console\]|\[System.Runtime.Extensions\]|\[mscorlib\]","[runtime]",
+ "\[System\.Runtime\]|\[System\.Console\]|\[System\.Runtime\.Extensions\]|\[mscorlib\]|\[System\.Memory\]","[runtime]",
System.Text.RegularExpressions.RegexOptions.Singleline)
let raw = File.ReadAllText(ilFilePath)
diff --git a/tests/FSharp.Test.Utilities/Xunit/Attributes/DirectoryAttribute.fs b/tests/FSharp.Test.Utilities/Xunit/Attributes/DirectoryAttribute.fs
index facf0674bd7..c44f1bd9f73 100644
--- a/tests/FSharp.Test.Utilities/Xunit/Attributes/DirectoryAttribute.fs
+++ b/tests/FSharp.Test.Utilities/Xunit/Attributes/DirectoryAttribute.fs
@@ -48,7 +48,8 @@ type DirectoryAttribute(dir: string) =
SourceKind = SourceKind.Fsx
Name = Some fs
IgnoreWarnings = false
- References = [] } |> FS
+ References = []
+ CompileDirectory = None } |> FS
member _.Includes with get() = includes and set v = includes <- v
diff --git a/tests/fsharp/Compiler/CodeGen/EmittedIL/DeterministicTests.fs b/tests/fsharp/Compiler/CodeGen/EmittedIL/DeterministicTests.fs
new file mode 100644
index 00000000000..fd8539ddab9
--- /dev/null
+++ b/tests/fsharp/Compiler/CodeGen/EmittedIL/DeterministicTests.fs
@@ -0,0 +1,530 @@
+// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
+
+namespace FSharp.Compiler.UnitTests.CodeGen.EmittedIL
+
+open System.IO
+open FSharp.Test
+open FSharp.Test.Compiler
+open NUnit.Framework
+
+[]
+module DeterministicTests =
+
+ []
+ let ``Simple assembly should be deterministic``() =
+ let inputFilePath = CompilerAssert.GenerateFsInputPath()
+ let outputFilePath = CompilerAssert.GenerateDllOutputPath()
+ let src =
+ """
+module Assembly
+
+open System
+
+let test() =
+ Console.WriteLine("Hello World!")
+ """
+
+ File.WriteAllText(inputFilePath, src)
+
+ let mvid1 =
+ FSharpWithInputAndOutputPath inputFilePath outputFilePath
+ |> withOptions ["--deterministic"]
+ |> compileGuid
+ let mvid2 =
+ FSharpWithInputAndOutputPath inputFilePath outputFilePath
+ |> withOptions ["--deterministic"]
+ |> compileGuid
+
+ // Two identical compilations should produce the same MVID
+ Assert.AreEqual(mvid1, mvid2)
+
+ []
+ let ``Simple assembly with different platform should not be deterministic``() =
+ let inputFilePath = CompilerAssert.GenerateFsInputPath()
+ let outputFilePath = CompilerAssert.GenerateDllOutputPath()
+ let src =
+ """
+module Assembly
+
+open System
+
+let test() =
+ Console.WriteLine("Hello World!")
+ """
+
+ File.WriteAllText(inputFilePath, src)
+
+ let mvid1 =
+ FSharpWithInputAndOutputPath inputFilePath outputFilePath
+ |> withOptions ["--deterministic"]
+ |> compileGuid
+ let mvid2 =
+ FSharpWithInputAndOutputPath inputFilePath outputFilePath
+ |> withOptions ["--deterministic";"--platform:Itanium"]
+ |> compileGuid
+
+ // No two platforms should produce the same MVID
+ Assert.AreNotEqual(mvid1, mvid2)
+
+ []
+ let ``Simple reference assembly should be deterministic``() =
+ let inputFilePath = CompilerAssert.GenerateFsInputPath()
+ let outputFilePath = CompilerAssert.GenerateDllOutputPath()
+ let src =
+ """
+module ReferenceAssembly
+
+open System
+
+let private privTest() =
+ Console.WriteLine("Private Hello World!")
+
+let test() =
+ privTest()
+ Console.WriteLine("Hello World!")
+ """
+
+ File.WriteAllText(inputFilePath, src)
+
+ let mvid1 =
+ FSharpWithInputAndOutputPath inputFilePath outputFilePath
+ |> withOptions ["--refonly";"--deterministic"]
+ |> compileGuid
+ let mvid2 =
+ FSharpWithInputAndOutputPath inputFilePath outputFilePath
+ |> withOptions ["--refonly";"--deterministic"]
+ |> compileGuid
+
+ // Two identical compilations should produce the same MVID
+ Assert.AreEqual(mvid1, mvid2)
+
+ []
+ let ``Simple reference assembly with different platform should not be deterministic``() =
+ let inputFilePath = CompilerAssert.GenerateFsInputPath()
+ let outputFilePath = CompilerAssert.GenerateDllOutputPath()
+ let src =
+ """
+module ReferenceAssembly
+
+open System
+
+let private privTest() =
+ Console.WriteLine("Private Hello World!")
+
+let test() =
+ privTest()
+ Console.WriteLine("Hello World!")
+ """
+
+ File.WriteAllText(inputFilePath, src)
+
+ let mvid1 =
+ FSharpWithInputAndOutputPath inputFilePath outputFilePath
+ |> withOptions ["--refonly";"--deterministic"]
+ |> compileGuid
+ let mvid2 =
+ FSharpWithInputAndOutputPath inputFilePath outputFilePath
+ |> withOptions ["--refonly";"--deterministic";"--platform:Itanium"]
+ |> compileGuid
+
+ // No two platforms should produce the same MVID
+ Assert.AreNotEqual(mvid1, mvid2)
+
+
+ []
+ let ``False-positive reference assemblies test, different aseemblies' mvid should not match`` () =
+ let inputFilePath = CompilerAssert.GenerateFsInputPath()
+ let outputFilePath = CompilerAssert.GenerateDllOutputPath()
+ let src =
+ """
+module ReferenceAssembly
+
+open System
+
+let test() =
+ Console.WriteLine("Hello World!")
+ """
+
+ File.WriteAllText(inputFilePath, src)
+
+ let mvid1 =
+ FSharpWithInputAndOutputPath inputFilePath outputFilePath
+ |> withOptions ["--refonly";"--deterministic"]
+ |> compileGuid
+
+
+ let inputFilePath2 = CompilerAssert.GenerateFsInputPath()
+ let outputFilePath2 = CompilerAssert.GenerateDllOutputPath()
+ let src2 =
+ """
+module ReferenceAssembly
+
+open System
+
+let test2() =
+ Console.WriteLine("Hello World!")
+ """
+
+ File.WriteAllText(inputFilePath2, src2)
+
+ let mvid2 =
+ FSharpWithInputAndOutputPath inputFilePath2 outputFilePath2
+ |> withOptions ["--refonly";"--deterministic"]
+ |> compileGuid
+
+ // Two different compilations should _not_ produce the same MVID
+ Assert.AreNotEqual(mvid1, mvid2)
+
+ []
+ let ``Reference assemblies should be deterministic when only private function name is different with the same function name length`` () =
+ let inputFilePath = CompilerAssert.GenerateFsInputPath()
+ let outputFilePath = CompilerAssert.GenerateDllOutputPath()
+ let src =
+ """
+module ReferenceAssembly
+
+open System
+
+let private privTest1() =
+ Console.WriteLine("Private Hello World!")
+
+let test() =
+ privTest1()
+ Console.WriteLine("Hello World!")
+ """
+
+ File.WriteAllText(inputFilePath, src)
+
+ let mvid1 =
+ FSharpWithInputAndOutputPath inputFilePath outputFilePath
+ |> withOptions ["--refonly";"--deterministic"]
+ |> compileGuid
+
+
+ let inputFilePath2 = CompilerAssert.GenerateFsInputPath()
+ let outputFilePath2 = CompilerAssert.GenerateDllOutputPath()
+ let src2 =
+ """
+module ReferenceAssembly
+
+open System
+
+let private privTest2() =
+ Console.WriteLine("Private Hello World!")
+
+let test() =
+ privTest2()
+ Console.WriteLine("Hello World!")
+ """
+
+ File.WriteAllText(inputFilePath2, src2)
+
+ let mvid2 =
+ FSharpWithInputAndOutputPath inputFilePath2 outputFilePath2
+ |> withOptions ["--refonly";"--deterministic"]
+ |> compileGuid
+
+ // Two compilations with changes only to private code should produce the same MVID
+ Assert.AreEqual(mvid1, mvid2)
+
+
+ []
+ let ``Reference assemblies should be deterministic when only private function name is different with the different function name length`` () =
+ let inputFilePath = CompilerAssert.GenerateFsInputPath()
+ let outputFilePath = CompilerAssert.GenerateDllOutputPath()
+ let src =
+ """
+module ReferenceAssembly
+
+open System
+
+let private privTest1() =
+ Console.WriteLine("Private Hello World!")
+
+let test() =
+ privTest1()
+ Console.WriteLine("Hello World!")
+ """
+
+ File.WriteAllText(inputFilePath, src)
+
+ let mvid1 =
+ FSharpWithInputAndOutputPath inputFilePath outputFilePath
+ |> withOptions ["--refonly";"--deterministic"]
+ |> compileGuid
+
+
+ let inputFilePath2 = CompilerAssert.GenerateFsInputPath()
+ let outputFilePath2 = CompilerAssert.GenerateDllOutputPath()
+ let src2 =
+ """
+module ReferenceAssembly
+
+open System
+
+let private privTest11() =
+ Console.WriteLine("Private Hello World!")
+
+let test() =
+ privTest11()
+ Console.WriteLine("Hello World!")
+ """
+
+ File.WriteAllText(inputFilePath2, src2)
+
+ let mvid2 =
+ FSharpWithInputAndOutputPath inputFilePath2 outputFilePath2
+ |> withOptions ["--refonly";"--deterministic"]
+ |> compileGuid
+
+ // Two compilations with changes only to private code should produce the same MVID
+ Assert.AreEqual(mvid1, mvid2)
+
+ []
+ let ``Reference assemblies should be deterministic when only private function body is different`` () =
+ let inputFilePath = CompilerAssert.GenerateFsInputPath()
+ let outputFilePath = CompilerAssert.GenerateDllOutputPath()
+ let src =
+ """
+module ReferenceAssembly
+
+open System
+
+let private privTest1() =
+ Console.WriteLine("Private Hello World!")
+
+let test() =
+ privTest1()
+ Console.WriteLine("Hello World!")
+ """
+
+ File.WriteAllText(inputFilePath, src)
+
+ let mvid1 =
+ FSharpWithInputAndOutputPath inputFilePath outputFilePath
+ |> withOptions ["--refonly";"--deterministic"]
+ |> compileGuid
+
+
+ let inputFilePath2 = CompilerAssert.GenerateFsInputPath()
+ let outputFilePath2 = CompilerAssert.GenerateDllOutputPath()
+ let src2 =
+ """
+module ReferenceAssembly
+
+open System
+
+let private privTest1() =
+ Console.Write("Private Hello World!")
+
+let test() =
+ privTest1()
+ Console.WriteLine("Hello World!")
+ """
+
+ File.WriteAllText(inputFilePath2, src2)
+
+ let mvid2 =
+ FSharpWithInputAndOutputPath inputFilePath2 outputFilePath2
+ |> withOptions ["--refonly";"--deterministic"]
+ |> compileGuid
+
+ // Two compilations with changes only to private code should produce the same MVID
+ Assert.AreEqual(mvid1, mvid2)
+
+ []
+ let ``Reference assemblies should be deterministic when only private function return type is different`` () =
+ let inputFilePath = CompilerAssert.GenerateFsInputPath()
+ let outputFilePath = CompilerAssert.GenerateDllOutputPath()
+ let src =
+ """
+module ReferenceAssembly
+
+open System
+
+let private privTest1() : string = "Private Hello World!"
+
+let test() =
+ privTest1() |> ignore
+ Console.WriteLine()
+ """
+
+ File.WriteAllText(inputFilePath, src)
+
+ let mvid1 =
+ FSharpWithInputAndOutputPath inputFilePath outputFilePath
+ |> withOptions ["--refonly";"--deterministic"]
+ |> compileGuid
+
+
+ let inputFilePath2 = CompilerAssert.GenerateFsInputPath()
+ let outputFilePath2 = CompilerAssert.GenerateDllOutputPath()
+ let src2 =
+ """
+module ReferenceAssembly
+
+open System
+
+let private privTest1() : int = 0
+
+let test() =
+ privTest1() |> ignore
+ Console.WriteLine()
+ """
+
+ File.WriteAllText(inputFilePath2, src2)
+
+ let mvid2 =
+ FSharpWithInputAndOutputPath inputFilePath2 outputFilePath2
+ |> withOptions ["--refonly";"--deterministic"]
+ |> compileGuid
+
+ // Two compilations with changes only to private code should produce the same MVID
+ Assert.AreEqual(mvid1, mvid2)
+
+ []
+ let ``Reference assemblies should be deterministic when only private function parameter count is different`` () =
+ let inputFilePath = CompilerAssert.GenerateFsInputPath()
+ let outputFilePath = CompilerAssert.GenerateDllOutputPath()
+ let src =
+ """
+module ReferenceAssembly
+
+open System
+
+let private privTest1 () : string = "Private Hello World!"
+
+let test() =
+ privTest1 () |> ignore
+ Console.WriteLine()
+ """
+
+ File.WriteAllText(inputFilePath, src)
+
+ let mvid1 =
+ FSharpWithInputAndOutputPath inputFilePath outputFilePath
+ |> withOptions ["--refonly";"--deterministic"]
+ |> compileGuid
+
+
+ let inputFilePath2 = CompilerAssert.GenerateFsInputPath()
+ let outputFilePath2 = CompilerAssert.GenerateDllOutputPath()
+ let src2 =
+ """
+module ReferenceAssembly
+
+open System
+
+let private privTest1 () () : string = "Private Hello World!"
+
+let test() =
+ privTest1 () () |> ignore
+ Console.WriteLine()
+ """
+
+ File.WriteAllText(inputFilePath2, src2)
+
+ let mvid2 =
+ FSharpWithInputAndOutputPath inputFilePath2 outputFilePath2
+ |> withOptions ["--refonly";"--deterministic"]
+ |> compileGuid
+
+ // Two compilations with changes only to private code should produce the same MVID
+ Assert.AreEqual(mvid1, mvid2)
+
+ []
+ let ``Reference assemblies should be deterministic when only private function parameter types are different`` () =
+ let inputFilePath = CompilerAssert.GenerateFsInputPath()
+ let outputFilePath = CompilerAssert.GenerateDllOutputPath()
+ let src =
+ """
+module ReferenceAssembly
+
+open System
+
+let private privTest1 () = "Private Hello World!"
+
+let test() =
+ privTest1() |> ignore
+ Console.WriteLine()
+ """
+
+ File.WriteAllText(inputFilePath, src)
+
+ let mvid1 =
+ FSharpWithInputAndOutputPath inputFilePath outputFilePath
+ |> withOptions ["--refonly";"--deterministic"]
+ |> compileGuid
+
+
+ let inputFilePath2 = CompilerAssert.GenerateFsInputPath()
+ let outputFilePath2 = CompilerAssert.GenerateDllOutputPath()
+ let src2 =
+ """
+module ReferenceAssembly
+
+open System
+
+let private privTest1 (_: string) = "Private Hello World!"
+
+let test() =
+ privTest1 "" |> ignore
+ Console.WriteLine()
+ """
+
+ File.WriteAllText(inputFilePath2, src2)
+
+ let mvid2 =
+ FSharpWithInputAndOutputPath inputFilePath2 outputFilePath2
+ |> withOptions ["--refonly";"--deterministic"]
+ |> compileGuid
+
+ // Two compilations with changes only to private code should produce the same MVID
+ Assert.AreEqual(mvid1, mvid2)
+
+ []
+ let ``Reference assemblies should be deterministic when private function is missing in one of them`` () =
+ let inputFilePath = CompilerAssert.GenerateFsInputPath()
+ let outputFilePath = CompilerAssert.GenerateDllOutputPath()
+ let src =
+ """
+module ReferenceAssembly
+
+open System
+
+let private privTest1 () = "Private Hello World!"
+
+let test() =
+ privTest1() |> ignore
+ Console.WriteLine()
+ """
+
+ File.WriteAllText(inputFilePath, src)
+
+ let mvid1 =
+ FSharpWithInputAndOutputPath inputFilePath outputFilePath
+ |> withOptions ["--refonly";"--deterministic"]
+ |> compileGuid
+
+
+ let inputFilePath2 = CompilerAssert.GenerateFsInputPath()
+ let outputFilePath2 = CompilerAssert.GenerateDllOutputPath()
+ let src2 =
+ """
+module ReferenceAssembly
+
+open System
+
+let test() =
+ Console.WriteLine()
+ """
+
+ File.WriteAllText(inputFilePath2, src2)
+
+ let mvid2 =
+ FSharpWithInputAndOutputPath inputFilePath2 outputFilePath2
+ |> withOptions ["--refonly";"--deterministic"]
+ |> compileGuid
+
+ // Two compilations with changes only to private code should produce the same MVID
+ Assert.AreEqual(mvid1, mvid2)
\ No newline at end of file
diff --git a/tests/fsharp/Compiler/CodeGen/EmittedIL/ReferenceAssemblyTests.fs b/tests/fsharp/Compiler/CodeGen/EmittedIL/ReferenceAssemblyTests.fs
new file mode 100644
index 00000000000..762cea82bfb
--- /dev/null
+++ b/tests/fsharp/Compiler/CodeGen/EmittedIL/ReferenceAssemblyTests.fs
@@ -0,0 +1,452 @@
+// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
+
+namespace FSharp.Compiler.UnitTests.CodeGen.EmittedIL
+
+open FSharp.Test.Compiler
+open NUnit.Framework
+open FSharp.Compiler.IO
+
+[]
+module ReferenceAssemblyTests =
+
+ let referenceAssemblyAttributeExpectedIL =
+ """.custom instance void [runtime]System.Runtime.CompilerServices.ReferenceAssemblyAttribute::.ctor() = ( 01 00 00 00 )"""
+
+ []
+ let ``Simple reference assembly should have expected IL``() =
+ let src =
+ """
+module ReferenceAssembly
+
+open System
+
+let test() =
+ Console.WriteLine("Hello World!")
+ """
+
+ FSharp src
+ |> withOptions ["--refonly"]
+ |> compile
+ |> shouldSucceed
+ |> verifyIL [
+ referenceAssemblyAttributeExpectedIL
+ """.class public abstract auto ansi sealed ReferenceAssembly
+ 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 )
+ .method public static void test() cil managed
+ {
+
+ .maxstack 8
+ IL_0000: ldnull
+ IL_0001: throw
+ }
+
+ }
+
+ .class private abstract auto ansi sealed ''.$ReferenceAssembly
+ extends [runtime]System.Object
+ {
+ }"""
+ ]
+ |> ignore
+
+ []
+ let ``Simple reference assembly should have expected IL without a private function``() =
+ let src =
+ """
+module ReferenceAssembly
+
+open System
+
+let private privTest() =
+ Console.WriteLine("Private Hello World!")
+
+let test() =
+ privTest()
+ Console.WriteLine("Hello World!")
+ """
+
+ FSharp src
+ |> withOptions ["--refonly"]
+ |> compile
+ |> shouldSucceed
+ |> verifyIL [
+ referenceAssemblyAttributeExpectedIL
+ """.class public abstract auto ansi sealed ReferenceAssembly
+ 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 )
+ .method public static void test() cil managed
+ {
+
+ .maxstack 8
+ IL_0000: ldnull
+ IL_0001: throw
+ }
+
+ }
+
+ .class private abstract auto ansi sealed ''.$ReferenceAssembly
+ extends [runtime]System.Object
+ {
+ }"""
+ ]
+ |> ignore
+
+ []
+ let ``Simple reference assembly should have expected IL with anonymous record``() =
+ let src =
+ """
+module ReferenceAssembly
+
+open System
+
+let test(_x: {| a: int32 |}) =
+ Console.WriteLine("Hello World!")
+ """
+
+ FSharp src
+ |> withOptions ["--refonly"]
+ |> compile
+ |> shouldSucceed
+ |> verifyIL [
+ referenceAssemblyAttributeExpectedIL
+ """.maxstack 8
+ IL_0000: ldnull
+ IL_0001: throw
+ }
+
+ }
+
+ .class private abstract auto ansi sealed ''.$ReferenceAssembly
+ extends [runtime]System.Object
+ {
+ }"""
+ ]
+ |> ignore
+
+ []
+ let ``Simple reference assembly with nested module should have expected IL``() =
+ let src =
+ """
+module ReferenceAssembly
+
+open System
+
+module Nested =
+
+ let test() =
+ Console.WriteLine("Hello World!")
+ """
+
+ FSharp src
+ |> withOptions ["--refonly"]
+ |> compile
+ |> shouldSucceed
+ |> verifyIL [
+ referenceAssemblyAttributeExpectedIL
+ """.class public abstract auto ansi sealed ReferenceAssembly
+ 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 )
+ .class abstract auto ansi sealed nested public Nested
+ 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 )
+ .method public static void test() cil managed
+ {
+
+ .maxstack 8
+ IL_0000: ldnull
+ IL_0001: throw
+ }
+
+ }
+
+ }
+
+ .class private abstract auto ansi sealed ''.$ReferenceAssembly
+ extends [runtime]System.Object
+ {
+ }"""
+ ]
+ |> ignore
+
+ []
+ let ``Simple reference assembly with nested module with type should have expected IL``() =
+ let src =
+ """
+module ReferenceAssembly
+
+open System
+
+module Nested =
+
+ type Test = { x: int }
+
+ let test(_x: Test) =
+ Console.WriteLine("Hello World!")
+ """
+
+ FSharp src
+ |> withOptions ["--refonly"]
+ |> compile
+ |> shouldSucceed
+ |> verifyIL [
+ referenceAssemblyAttributeExpectedIL
+ """.class public abstract auto ansi sealed ReferenceAssembly
+ 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 )
+ .class abstract auto ansi sealed nested public Nested
+ 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 )
+ .class auto ansi serializable sealed nested public Test
+ extends [runtime]System.Object
+ implements class [runtime]System.IEquatable`1,
+ [runtime]System.Collections.IStructuralEquatable,
+ class [runtime]System.IComparable`1,
+ [runtime]System.IComparable,
+ [runtime]System.Collections.IStructuralComparable
+ {
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 02 00 00 00 00 00 )
+ .field assembly int32 x@
+ .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 )
+ .method public hidebysig specialname
+ instance int32 get_x() cil managed
+ {
+
+ .maxstack 8
+ IL_0000: ldnull
+ IL_0001: throw
+ }
+
+ .method public specialname rtspecialname
+ instance void .ctor(int32 x) cil managed
+ {
+
+ .maxstack 8
+ IL_0000: ldnull
+ IL_0001: throw
+ }
+
+ .method public strict virtual instance string
+ ToString() cil managed
+ {
+ .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+
+ .maxstack 8
+ IL_0000: ldnull
+ IL_0001: throw
+ }
+
+ .method public hidebysig virtual final
+ instance int32 CompareTo(class ReferenceAssembly/Nested/Test obj) cil managed
+ {
+ .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+
+ .maxstack 8
+ IL_0000: ldnull
+ IL_0001: throw
+ }
+
+ .method public hidebysig virtual final
+ instance int32 CompareTo(object obj) cil managed
+ {
+ .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+
+ .maxstack 8
+ IL_0000: ldnull
+ IL_0001: throw
+ }
+
+ .method public hidebysig virtual final
+ instance int32 CompareTo(object obj,
+ class [runtime]System.Collections.IComparer comp) cil managed
+ {
+ .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+
+ .maxstack 8
+ IL_0000: ldnull
+ IL_0001: throw
+ }
+
+ .method public hidebysig virtual final
+ instance int32 GetHashCode(class [runtime]System.Collections.IEqualityComparer comp) cil managed
+ {
+ .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+
+ .maxstack 8
+ IL_0000: ldnull
+ IL_0001: throw
+ }
+
+ .method public hidebysig virtual final
+ instance int32 GetHashCode() cil managed
+ {
+ .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+
+ .maxstack 8
+ IL_0000: ldnull
+ IL_0001: throw
+ }
+
+ .method public hidebysig virtual final
+ instance bool Equals(object obj,
+ class [runtime]System.Collections.IEqualityComparer comp) cil managed
+ {
+ .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+
+ .maxstack 8
+ IL_0000: ldnull
+ IL_0001: throw
+ }
+
+ .method public hidebysig virtual final
+ instance bool Equals(class ReferenceAssembly/Nested/Test obj) cil managed
+ {
+ .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+
+ .maxstack 8
+ IL_0000: ldnull
+ IL_0001: throw
+ }
+
+ .method public hidebysig virtual final
+ instance bool Equals(object obj) cil managed
+ {
+ .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+
+ .maxstack 8
+ IL_0000: ldnull
+ IL_0001: throw
+ }
+
+ .property instance int32 x()
+ {
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags,
+ int32) = ( 01 00 04 00 00 00 00 00 00 00 00 00 )
+ .get instance int32 ReferenceAssembly/Nested/Test::get_x()
+ }
+ }
+
+ .method public static void test(class ReferenceAssembly/Nested/Test _x) cil managed
+ {
+
+ .maxstack 8
+ IL_0000: ldnull
+ IL_0001: throw
+ }
+
+ }
+
+ }
+
+ .class private abstract auto ansi sealed ''.$ReferenceAssembly
+ extends [runtime]System.Object
+ {
+ }"""
+ ]
+ |> ignore
+
+ []
+ let ``--refout should produce both normal and reference assemblies``() =
+ // TODO: We probably want a built-in test framework functionality which will be taking care of comparing/verifying refout.
+ let refoutDllPath = FileSystem.GetTempPathShim() + "Test.ref.dll"
+ let src =
+ """
+module ReferenceAssembly
+
+open System
+
+let test() =
+ Console.WriteLine("Hello World!")
+ """
+
+ // This will produce normal assembly as well as ref in {refoutPath}
+ let result =
+ FSharp src
+ |> withOptions [$"--refout:{refoutDllPath}"]
+ |> compile
+
+ // Should build successfully.
+ result |> shouldSucceed
+ // Verify that normal assembly has been produced.
+ |> verifyIL [""".class public abstract auto ansi sealed ReferenceAssembly
+ 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 )
+ .method public static void test() cil managed
+ {
+
+ .maxstack 8
+ IL_0000: ldstr "Hello World!"
+ IL_0005: call void [runtime]System.Console::WriteLine(string)
+ IL_000a: ret
+ }
+
+ }"""
+ ]
+ |> ignore
+
+ // Verify that ref assembly in custom path was produced.
+ if not (FileSystem.FileExistsShim refoutDllPath) then
+ failwith $"Can't find reference assembly {refoutDllPath}"
+
+ refoutDllPath
+ |> verifyILBinary [
+ referenceAssemblyAttributeExpectedIL
+ """.class public abstract auto ansi sealed ReferenceAssembly
+ 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 )
+ .method public static void test() cil managed
+ {
+
+ .maxstack 8
+ IL_0000: ldnull
+ IL_0001: throw
+ }
+
+ }"""
+ ]
+
+ []
+ let ``Can't use both --refonly and --staticlink``() =
+ let src =
+ """
+module ReferenceAssembly
+
+open System
+
+let test() =
+ Console.WriteLine("Hello World!")
+ """
+
+ FSharp src
+ |> withOptions ["--staticlink:foo"; "--refonly"]
+ |> compile
+ |> shouldFail
+ |> withSingleDiagnostic (Error 2030, Line 0, Col 1, Line 0, Col 1, "Invalid use of emitting a reference assembly. Check the compiler options to not specify static linking, or using '--refonly' and '--refout' together.")
+ |> ignore
+
+ []
+ let ``Can't use both --refoout and --staticlink``() =
+ let src =
+ """
+module ReferenceAssembly
+
+open System
+
+let test() =
+ Console.WriteLine("Hello World!")
+ """
+
+ FSharp src
+ |> withOptions ["--staticlink:foo"; "--refout:foo"]
+ |> compile
+ |> shouldFail
+ |> withSingleDiagnostic (Error 2030, Line 0, Col 1, Line 0, Col 1, "Invalid use of emitting a reference assembly. Check the compiler options to not specify static linking, or using '--refonly' and '--refout' together.")
+ |> ignore
\ No newline at end of file
diff --git a/tests/fsharp/Compiler/Language/SpanOptimizationTests.fs b/tests/fsharp/Compiler/Language/SpanOptimizationTests.fs
index 6d155dc723e..5345fbfd252 100644
--- a/tests/fsharp/Compiler/Language/SpanOptimizationTests.fs
+++ b/tests/fsharp/Compiler/Language/SpanOptimizationTests.fs
@@ -11,7 +11,7 @@ module SpanOptimizationTests =
[]
let SpanForInDo() =
- let source =
+ let source =
"""
module Test
@@ -40,7 +40,7 @@ let test () =
IL_0006: ldc.i4.0
IL_0007: stloc.1
IL_0008: br.s IL_0022
-
+
IL_000a: ldloca.s V_0
IL_000c: ldloc.1
IL_000d: call instance !0& valuetype [runtime]System.Span`1
- Re-format indentation on paste
- Přeformátovat odsazení při vložení
+ Re-format indentation on paste (Experimental)
+ Znovu naformátovat odsazení při vložení (experimentální)
diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.de.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.de.xlf
index 653c542d13f..7db4ba605f3 100644
--- a/vsintegration/src/FSharp.UIResources/xlf/Strings.de.xlf
+++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.de.xlf
@@ -193,8 +193,8 @@
- Re-format indentation on paste
- Einzug beim Einfügen neu formatieren
+ Re-format indentation on paste (Experimental)
+ Einzug beim Einfügen erneut formatieren (experimentell)
diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.es.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.es.xlf
index 39c2877127c..674c69434c2 100644
--- a/vsintegration/src/FSharp.UIResources/xlf/Strings.es.xlf
+++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.es.xlf
@@ -193,8 +193,8 @@
- Re-format indentation on paste
- Cambiar formato de sangría al pegar
+ Re-format indentation on paste (Experimental)
+ Volver a aplicar formato a la sangría al pegar (experimental)
diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.fr.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.fr.xlf
index 3d73fe222b1..ec9bafbe8df 100644
--- a/vsintegration/src/FSharp.UIResources/xlf/Strings.fr.xlf
+++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.fr.xlf
@@ -193,8 +193,8 @@
- Re-format indentation on paste
- Remettre en forme le retrait au collage
+ Re-format indentation on paste (Experimental)
+ Formater de nouveau la mise en retrait lors du collage (expérimental)
diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.it.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.it.xlf
index 34d9ec67029..9b2acf06d1b 100644
--- a/vsintegration/src/FSharp.UIResources/xlf/Strings.it.xlf
+++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.it.xlf
@@ -193,8 +193,8 @@
- Re-format indentation on paste
- Riformatta rientro dopo operazione Incolla
+ Re-format indentation on paste (Experimental)
+ Riformattar il rientro dopo operazione incolla (sperimentale)
diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.ja.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.ja.xlf
index 5771c8c5848..8ab4c15b6e1 100644
--- a/vsintegration/src/FSharp.UIResources/xlf/Strings.ja.xlf
+++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.ja.xlf
@@ -193,8 +193,8 @@
- Re-format indentation on paste
- 貼り付け時にインデントを再フォーマットする
+ Re-format indentation on paste (Experimental)
+ 貼り付け時にインデントを再フォーマットする (試験段階)
diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.ko.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.ko.xlf
index dacb9996564..4812b0acc99 100644
--- a/vsintegration/src/FSharp.UIResources/xlf/Strings.ko.xlf
+++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.ko.xlf
@@ -193,8 +193,8 @@
- Re-format indentation on paste
- 붙여넣을 때 들여쓰기 서식 다시 지정
+ Re-format indentation on paste (Experimental)
+ 붙여넣을 때 들여쓰기 서식 다시 지정(실험적)
diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.pl.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.pl.xlf
index 4a205499f29..c96168985ec 100644
--- a/vsintegration/src/FSharp.UIResources/xlf/Strings.pl.xlf
+++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.pl.xlf
@@ -193,8 +193,8 @@
- Re-format indentation on paste
- Ponownie formatuj wcięcia przy wklejaniu
+ Re-format indentation on paste (Experimental)
+ Ponowne formatowanie wcięcia przy wklejeniu (eksperymentalne)
diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.pt-BR.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.pt-BR.xlf
index 13cce041c99..076de7f9087 100644
--- a/vsintegration/src/FSharp.UIResources/xlf/Strings.pt-BR.xlf
+++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.pt-BR.xlf
@@ -193,8 +193,8 @@
- Re-format indentation on paste
- Reformatar o recuo ao colar
+ Re-format indentation on paste (Experimental)
+ Reformatar o recuo na pasta (Experimental)
diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.ru.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.ru.xlf
index 579c059dcd6..690059925df 100644
--- a/vsintegration/src/FSharp.UIResources/xlf/Strings.ru.xlf
+++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.ru.xlf
@@ -193,8 +193,8 @@
- Re-format indentation on paste
- Повторно форматировать отступы при вставке
+ Re-format indentation on paste (Experimental)
+ Повторно форматировать отступы при вставке (экспериментальная функция)
diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.tr.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.tr.xlf
index 6ff42fad0e4..e05c403767a 100644
--- a/vsintegration/src/FSharp.UIResources/xlf/Strings.tr.xlf
+++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.tr.xlf
@@ -193,8 +193,8 @@
- Re-format indentation on paste
- Yapıştırırken girintiyi yeniden biçimlendir
+ Re-format indentation on paste (Experimental)
+ Yapıştırırken girintiyi yeniden biçimlendir (Deneysel)
diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.zh-Hans.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.zh-Hans.xlf
index 6b0a4cd7d07..b219edc12c0 100644
--- a/vsintegration/src/FSharp.UIResources/xlf/Strings.zh-Hans.xlf
+++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.zh-Hans.xlf
@@ -193,8 +193,8 @@
- Re-format indentation on paste
- 粘贴时重新设置缩进格式
+ Re-format indentation on paste (Experimental)
+ 粘贴时重新设置缩进格式(实验)
diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.zh-Hant.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.zh-Hant.xlf
index acbacbce081..0b6b964edda 100644
--- a/vsintegration/src/FSharp.UIResources/xlf/Strings.zh-Hant.xlf
+++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.zh-Hant.xlf
@@ -193,8 +193,8 @@
- Re-format indentation on paste
- 在貼上時重設縮排格式
+ Re-format indentation on paste (Experimental)
+ 在貼上時重新格式化縮排 (實驗性)