diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index 118e6891389c..93003652a8ef 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 929f04667eff..08bcbebd47d5 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 ffc4498fb857..055ddb7a5b6e 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 bc07a1c68482..55b298f16ccd 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 8c944f30b286..e361e03fabdd 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 7ab9baac5c8d..b1bca63ab1d8 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 3bd8b29ebd72..4585cfd6bba1 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 3aafc82e4171..8128f2c35705 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 37dceb1bab0a..7678b94ce740 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 90b1f9fdcdb1..f1e1cb53953b 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 dd7030ff5385..17f0a365805d 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 000000000000..76a97eb381ed
--- /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 000000000000..79835baea3f0
--- /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 863e8bd5ca3f..972f85371e6b 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 45b0cc396fbd..0356303cd017 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 be8025025fe1..8b3f7ea64686 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 aa69ea08050c..eb723a014a31 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 dae491a9d440..838075f689bb 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 4a80fea97d15..2e1861493259 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 0cf6ece074fc..74d8147a8bbf 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 057bc042c179..ded871675d12 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 6965a546cc7c..72c9527cad8b 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 7da0f5ed97a2..0fe4422cc23f 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 b5aba3ad10fc..497c42c2c47e 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 22266e786e5a..2d708e0bd577 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 5ad43a53542b..833af64d19ca 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 21f98a518f43..6fe439b04ef8 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 c2a1e9c25ce1..e8e3ce7e00cd 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 e6b819f448e1..5eabf3788804 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 1dedf910ac68..9a5e25f9bff8 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 2b9fbb8c049f..f6c84a6d2db6 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 7ddd68e404c1..b8a8c4d34150 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 152c9abc45f6..380f94f3b276 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 aa7143e11b12..20658961a663 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 d461f607afd9..42458640fd66 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 f9b5444a58da..213c8a5a129b 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 ada57d64b6eb..0dcad7df7867 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 221a7a7dbca0..5bcf19314200 100644
--- a/src/fsharp/service/FSharpCheckerResults.fsi
+++ b/src/fsharp/service/FSharpCheckerResults.fsi
@@ -509,6 +509,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 7e5177af5af3..bb7cad8ba014 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 557c94acb5f9..a49e7aa36667 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 ed1b773140b9..ed857c0db0bc 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 d93fe9947662..0431b2cb8a42 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'.
+ 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 reference assembly path'
+
+
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 with the specified file path.
+
+
Podporované jazykové verze:
@@ -434,7 +454,7 @@
- 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.
+ 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 638a9a8de5dc..448cf3ac1b38 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'.
+ 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 reference assembly path'
+
+
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 with the specified file path.
+
+
Unterstützte Sprachversionen:
@@ -434,7 +454,7 @@
- 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.
+ 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 b7ced72c91b7..3bd6b38e8a63 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'.
+ 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 reference assembly path'
+
+
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 with the specified file path.
+
+
Versiones de lenguaje admitidas:
@@ -434,7 +454,7 @@
- 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.
+ 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 52c3fdcea861..575166ffb4c5 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'.
+ 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 reference assembly path'
+
+
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 with the specified file path.
+
+
Versions linguistiques prises en charge :
@@ -434,7 +454,7 @@
- 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.
+ 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 249887688fdb..ec8fc05495c9 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'.
+ 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 reference assembly path'
+
+
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 with the specified file path.
+
+
Versioni del linguaggio supportate:
@@ -434,7 +454,7 @@
- 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.
+ 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 15c5da75f0d2..4f28abfabdec 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'.
+ '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 reference assembly path'
+
+
言語バージョンで許可された値を表示し、'最新' や 'プレビュー' などの言語バージョンを指定する
+
+
+ Produce a reference assembly, instead of a full assembly, as the primary output
+
+
+
+
+ Produce a reference assembly with the specified file path.
+
+
サポートされる言語バージョン:
@@ -434,7 +454,7 @@
- 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.
+ メンバーの宣言が無効です。メンバーの名前が見つからないか、かっこが含まれています。
diff --git a/src/fsharp/xlf/FSComp.txt.ko.xlf b/src/fsharp/xlf/FSComp.txt.ko.xlf
index 8f28ff6bc5ad..ae5d5a74eefb 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'.
+ '끝에서부터 조각화' 기능을 사용하려면 언어 버전 '미리 보기'가 필요합니다.
@@ -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 reference assembly path'
+
+
언어 버전의 허용된 값을 표시하고 '최신' 또는 '미리 보기'와 같은 언어 버전을 지정합니다.
+
+
+ Produce a reference assembly, instead of a full assembly, as the primary output
+
+
+
+
+ Produce a reference assembly with the specified file path.
+
+
지원되는 언어 버전:
@@ -434,7 +454,7 @@
- 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.
+ 멤버 선언이 잘못되었습니다. 멤버 이름이 없거나 괄호가 있습니다.
diff --git a/src/fsharp/xlf/FSComp.txt.pl.xlf b/src/fsharp/xlf/FSComp.txt.pl.xlf
index 70627d2892bb..aaccee27ffa6 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'.
+ 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 reference assembly path'
+
+
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 with the specified file path.
+
+
Obsługiwane wersje językowe:
@@ -434,7 +454,7 @@
- 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.
+ 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 26e583b87bf8..16496b3d78f1 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'.
+ 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 reference assembly path'
+
+
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 with the specified file path.
+
+
Versões de linguagens com suporte:
@@ -434,7 +454,7 @@
- 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.
+ 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 8b2d5dcc6e3d..c3e3ce97be5d 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'.
+ Для функции конечного среза требуется "предварительная" версия языка.
@@ -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 reference assembly path'
+
+
Отображение допустимых значений для версии языка. Укажите версию языка, например, "latest" или "preview".
+
+
+ Produce a reference assembly, instead of a full assembly, as the primary output
+
+
+
+
+ Produce a reference assembly with the specified file path.
+
+
Поддерживаемые языковые версии:
@@ -434,7 +454,7 @@
- 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.
+ Недопустимое объявление элемента. Имя элемента отсутствует или содержит скобки.
diff --git a/src/fsharp/xlf/FSComp.txt.tr.xlf b/src/fsharp/xlf/FSComp.txt.tr.xlf
index de3cedeb9381..5ad2de1bcd74 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'.
+ '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 reference assembly path'
+
+
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 with the specified file path.
+
+
Desteklenen dil sürümleri:
@@ -434,7 +454,7 @@
- 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.
+ 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 b2a5c4075fd3..7fd15ff380d0 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'.
+ “从末尾切片”功能需要语言版本“预览”。
@@ -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 reference assembly path'
+
+
显示语言版本的允许值,指定语言版本,如“最新”或“预览”
+
+
+ Produce a reference assembly, instead of a full assembly, as the primary output
+
+
+
+
+ Produce a reference assembly with the specified file path.
+
+
支持的语言版本:
@@ -434,7 +454,7 @@
- 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.
+ 成员声明无效。成员的名称缺失或包含括号。
diff --git a/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf b/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf
index 27dc0b276934..7070f0808361 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'.
+ 「從末端分割」功能需要語言版本「預覽」。
@@ -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 reference assembly path'
+
+
顯示語言版本允許的值,指定 'latest' 或 'preview' 等語言版本
+
+
+ Produce a reference assembly, instead of a full assembly, as the primary output
+
+
+
+
+ Produce a reference assembly with the specified file path.
+
+
支援的語言版本:
@@ -434,7 +454,7 @@
- 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.
+ 成員宣告無效。成員的名稱遺失或有括弧。
diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core.UnitTests.fsproj b/tests/FSharp.Core.UnitTests/FSharp.Core.UnitTests.fsproj
index aa39265d2a0f..4602d100ff41 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 000000000000..8987d993bdb4
--- /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 77f204b586b5..50f5e9b24dc1 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 261e7cd57b88..49d037c62921 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 6357af6102da..a2ff9e5035d6 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 facf0674bd7f..c44f1bd9f739 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 000000000000..fd8539ddab94
--- /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 000000000000..762cea82bfb7
--- /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 6d155dc723eb..5345fbfd252a 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
-
- Přeformátovat odsazení při vložení
+
+ 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 653c542d13f3..7db4ba605f3f 100644
--- a/vsintegration/src/FSharp.UIResources/xlf/Strings.de.xlf
+++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.de.xlf
@@ -193,8 +193,8 @@
-
- Einzug beim Einfügen neu formatieren
+
+ 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 39c2877127c6..674c69434c29 100644
--- a/vsintegration/src/FSharp.UIResources/xlf/Strings.es.xlf
+++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.es.xlf
@@ -193,8 +193,8 @@
-
- Cambiar formato de sangría al pegar
+
+ 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 3d73fe222b13..ec9bafbe8df0 100644
--- a/vsintegration/src/FSharp.UIResources/xlf/Strings.fr.xlf
+++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.fr.xlf
@@ -193,8 +193,8 @@
-
- Remettre en forme le retrait au collage
+
+ 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 34d9ec67029c..9b2acf06d1b0 100644
--- a/vsintegration/src/FSharp.UIResources/xlf/Strings.it.xlf
+++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.it.xlf
@@ -193,8 +193,8 @@
-
- Riformatta rientro dopo operazione Incolla
+
+ 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 5771c8c5848e..8ab4c15b6e1f 100644
--- a/vsintegration/src/FSharp.UIResources/xlf/Strings.ja.xlf
+++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.ja.xlf
@@ -193,8 +193,8 @@
-
- 貼り付け時にインデントを再フォーマットする
+
+ 貼り付け時にインデントを再フォーマットする (試験段階)
diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.ko.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.ko.xlf
index dacb9996564b..4812b0acc99b 100644
--- a/vsintegration/src/FSharp.UIResources/xlf/Strings.ko.xlf
+++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.ko.xlf
@@ -193,8 +193,8 @@
-
- 붙여넣을 때 들여쓰기 서식 다시 지정
+
+ 붙여넣을 때 들여쓰기 서식 다시 지정(실험적)
diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.pl.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.pl.xlf
index 4a205499f29f..c96168985ec2 100644
--- a/vsintegration/src/FSharp.UIResources/xlf/Strings.pl.xlf
+++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.pl.xlf
@@ -193,8 +193,8 @@
-
- Ponownie formatuj wcięcia przy wklejaniu
+
+ 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 13cce041c991..076de7f90874 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 @@
-
- Reformatar o recuo ao colar
+
+ 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 579c059dcd62..690059925dff 100644
--- a/vsintegration/src/FSharp.UIResources/xlf/Strings.ru.xlf
+++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.ru.xlf
@@ -193,8 +193,8 @@
-
- Повторно форматировать отступы при вставке
+
+ Повторно форматировать отступы при вставке (экспериментальная функция)
diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.tr.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.tr.xlf
index 6ff42fad0e49..e05c403767ad 100644
--- a/vsintegration/src/FSharp.UIResources/xlf/Strings.tr.xlf
+++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.tr.xlf
@@ -193,8 +193,8 @@
-
- Yapıştırırken girintiyi yeniden biçimlendir
+
+ 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 6b0a4cd7d073..b219edc12c0d 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 @@
-
- 粘贴时重新设置缩进格式
+
+ 粘贴时重新设置缩进格式(实验)
diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.zh-Hant.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.zh-Hant.xlf
index acbacbce0817..0b6b964edda5 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 @@
-
- 在貼上時重設縮排格式
+
+ 在貼上時重新格式化縮排 (實驗性)