merge
This commit is contained in:
Коммит
2304ea482a
|
@ -105,6 +105,14 @@ jobs:
|
|||
continueOnError: true
|
||||
condition: succeeded()
|
||||
|
||||
# Publish native PDBs for archiving
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: Publish Artifact Symbols
|
||||
inputs:
|
||||
PathtoPublish: '$(Build.SourcesDirectory)/artifacts/SymStore/$(BuildConfiguration)'
|
||||
ArtifactName: NativeSymbols
|
||||
condition: succeeded()
|
||||
|
||||
# Execute cleanup tasks
|
||||
- task: ms-vseng.MicroBuildTasks.521a94ea-9e68-468a-8167-6dcf361ea776.MicroBuildCleanup@1
|
||||
displayName: Execute cleanup tasks
|
||||
|
|
|
@ -75,6 +75,7 @@
|
|||
<RepositoryUrl Condition="'$(RepositoryUrl)' == ''">https://github.com/Microsoft/visualfsharp</RepositoryUrl>
|
||||
<RepositoryType Condition="'$(RepositoryType)' == ''">git</RepositoryType>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(FSharpSourceBuild)' == 'true' AND '$(RepositoryCommit)' == ''">
|
||||
<_DotGitDir>$(RepoRoot).git</_DotGitDir>
|
||||
<_HeadFileContent Condition="Exists('$(_DotGitDir)/HEAD')">$([System.IO.File]::ReadAllText('$(_DotGitDir)/HEAD').Trim())</_HeadFileContent>
|
||||
|
@ -87,7 +88,7 @@
|
|||
<PropertyGroup>
|
||||
<NoWarn Condition="'$(Language)' == 'F#'">$(NoWarn);FS2003</NoWarn><!-- warning when AssemblyInformationalVersion looks like '1.2.3-dev' -->
|
||||
<NoCompilerStandardLib>true</NoCompilerStandardLib><!-- necessary for resource generation using csc.exe -->
|
||||
<DebugType>portable</DebugType>
|
||||
<DebugType>embedded</DebugType>
|
||||
<MicroBuildAssemblyFileLanguage>fs</MicroBuildAssemblyFileLanguage>
|
||||
<UseStandardResourceNames>false</UseStandardResourceNames>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
|
|
|
@ -113,6 +113,12 @@ jobs:
|
|||
PathtoPublish: '$(Build.SourcesDirectory)\artifacts\VSSetup\$(_BuildConfig)\VisualFSharpFull.vsix'
|
||||
ArtifactName: 'Nightly'
|
||||
condition: succeeded()
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: Publish Artifact Symbols
|
||||
inputs:
|
||||
PathtoPublish: '$(Build.SourcesDirectory)\artifacts\SymStore\$(_BuildConfig)'
|
||||
ArtifactName: 'NativeSymbols'
|
||||
condition: succeeded()
|
||||
|
||||
#---------------------------------------------------------------------------------------------------------------------#
|
||||
# PR builds #
|
||||
|
|
|
@ -225,13 +225,14 @@ function UpdatePath() {
|
|||
TestAndAddToPath "$ArtifactsDir\bin\fsiAnyCpu\$configuration\net472"
|
||||
}
|
||||
|
||||
function VerifyAssemblyVersions() {
|
||||
$fsiPath = Join-Path $ArtifactsDir "bin\fsi\Proto\net472\publish\fsi.exe"
|
||||
function VerifyAssemblyVersionsAndSymbols() {
|
||||
$assemblyVerCheckPath = Join-Path $ArtifactsDir "Bootstrap\AssemblyCheck\AssemblyCheck.dll"
|
||||
|
||||
# Only verify versions on CI or official build
|
||||
if ($ci -or $official) {
|
||||
$asmVerCheckPath = "$RepoRoot\scripts"
|
||||
Exec-Console $fsiPath """$asmVerCheckPath\AssemblyVersionCheck.fsx"" -- ""$ArtifactsDir"""
|
||||
$dotnetPath = InitializeDotNetCli
|
||||
$dotnetExe = Join-Path $dotnetPath "dotnet.exe"
|
||||
Exec-Console $dotnetExe """$assemblyVerCheckPath"" ""$ArtifactsDir"""
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -308,7 +309,7 @@ try {
|
|||
}
|
||||
|
||||
if ($build) {
|
||||
VerifyAssemblyVersions
|
||||
VerifyAssemblyVersionsAndSymbols
|
||||
}
|
||||
|
||||
$desktopTargetFramework = "net472"
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
<ProductDependencies>
|
||||
</ProductDependencies>
|
||||
<ToolsetDependencies>
|
||||
<Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="1.0.0-beta.19364.1">
|
||||
<Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="1.0.0-beta.19375.15">
|
||||
<Uri>https://github.com/dotnet/arcade</Uri>
|
||||
<Sha>0c81c2bbdc49749e9940bc8858ebd16026d51277</Sha>
|
||||
<Sha>ef1c110152df0d500fffb87878a86f88d1ca5295</Sha>
|
||||
</Dependency>
|
||||
</ToolsetDependencies>
|
||||
</Dependencies>
|
||||
|
|
|
@ -236,10 +236,11 @@ function Make-BootstrapBuild() {
|
|||
Remove-Item -re $dir -ErrorAction SilentlyContinue
|
||||
Create-Directory $dir
|
||||
|
||||
# prepare FsLex and Fsyacc
|
||||
# prepare FsLex and Fsyacc and AssemblyCheck
|
||||
Run-MSBuild "$RepoRoot\src\buildtools\buildtools.proj" "/restore /t:Publish" -logFileName "BuildTools" -configuration $bootstrapConfiguration
|
||||
Copy-Item "$ArtifactsDir\bin\fslex\$bootstrapConfiguration\netcoreapp2.1\publish" -Destination "$dir\fslex" -Force -Recurse
|
||||
Copy-Item "$ArtifactsDir\bin\fsyacc\$bootstrapConfiguration\netcoreapp2.1\publish" -Destination "$dir\fsyacc" -Force -Recurse
|
||||
Copy-Item "$ArtifactsDir\bin\AssemblyCheck\$bootstrapConfiguration\netcoreapp2.1\publish" -Destination "$dir\AssemblyCheck" -Force -Recurse
|
||||
|
||||
# prepare compiler
|
||||
$projectPath = "$RepoRoot\proto.proj"
|
||||
|
|
|
@ -98,12 +98,18 @@ try {
|
|||
}
|
||||
|
||||
Write-Verbose "Installing $ToolName version $ToolVersion"
|
||||
Write-Verbose "Executing '$InstallerPath $LocalInstallerArguments'"
|
||||
Write-Verbose "Executing '$InstallerPath $($LocalInstallerArguments.Keys.ForEach({"-$_ '$($LocalInstallerArguments.$_)'"}) -join ' ')'"
|
||||
& $InstallerPath @LocalInstallerArguments
|
||||
if ($LASTEXITCODE -Ne "0") {
|
||||
$errMsg = "$ToolName installation failed"
|
||||
if ((Get-Variable 'DoNotAbortNativeToolsInstallationOnFailure' -ErrorAction 'SilentlyContinue') -and $DoNotAbortNativeToolsInstallationOnFailure) {
|
||||
Write-Warning $errMsg
|
||||
$showNativeToolsWarning = $true
|
||||
if ((Get-Variable 'DoNotDisplayNativeToolsInstallationWarnings' -ErrorAction 'SilentlyContinue') -and $DoNotDisplayNativeToolsInstallationWarnings) {
|
||||
$showNativeToolsWarning = $false
|
||||
}
|
||||
if ($showNativeToolsWarning) {
|
||||
Write-Warning $errMsg
|
||||
}
|
||||
$toolInstallationFailure = $true
|
||||
} else {
|
||||
Write-Error $errMsg
|
||||
|
|
|
@ -71,7 +71,7 @@ function ReadGlobalJsonNativeTools {
|
|||
local native_tools_list=$(echo $native_tools_section | awk -F"[{}]" '{print $2}')
|
||||
native_tools_list=${native_tools_list//[\" ]/}
|
||||
native_tools_list=${native_tools_list//,/$'\n'}
|
||||
native_tools_list="$(echo -e "${native_tools_list}" | tr -d '[:space:]')"
|
||||
native_tools_list="$(echo -e "${native_tools_list}" | tr -d '[[:space:]]')"
|
||||
|
||||
local old_IFS=$IFS
|
||||
while read -r line; do
|
||||
|
|
|
@ -59,9 +59,38 @@ function DownloadAndExtract {
|
|||
-Verbose:$Verbose
|
||||
|
||||
if ($UnzipStatus -Eq $False) {
|
||||
Write-Error "Unzip failed"
|
||||
return $False
|
||||
# Retry Download one more time with Force=true
|
||||
$DownloadRetryStatus = CommonLibrary\Get-File -Uri $Uri `
|
||||
-Path $TempToolPath `
|
||||
-DownloadRetries 1 `
|
||||
-RetryWaitTimeInSeconds $RetryWaitTimeInSeconds `
|
||||
-Force:$True `
|
||||
-Verbose:$Verbose
|
||||
|
||||
if ($DownloadRetryStatus -Eq $False) {
|
||||
Write-Error "Last attempt of download failed as well"
|
||||
return $False
|
||||
}
|
||||
|
||||
# Retry unzip again one more time with Force=true
|
||||
$UnzipRetryStatus = CommonLibrary\Expand-Zip -ZipPath $TempToolPath `
|
||||
-OutputDirectory $InstallDirectory `
|
||||
-Force:$True `
|
||||
-Verbose:$Verbose
|
||||
if ($UnzipRetryStatus -Eq $False)
|
||||
{
|
||||
Write-Error "Last attempt of unzip failed as well"
|
||||
# Clean up partial zips and extracts
|
||||
if (Test-Path $TempToolPath) {
|
||||
Remove-Item $TempToolPath -Force
|
||||
}
|
||||
if (Test-Path $InstallDirectory) {
|
||||
Remove-Item $InstallDirectory -Force -Recurse
|
||||
}
|
||||
return $False
|
||||
}
|
||||
}
|
||||
|
||||
return $True
|
||||
}
|
||||
|
||||
|
|
|
@ -39,11 +39,11 @@ function Write-PipelineTaskError {
|
|||
return
|
||||
fi
|
||||
|
||||
message_type="error"
|
||||
sourcepath=''
|
||||
linenumber=''
|
||||
columnnumber=''
|
||||
error_code=''
|
||||
local message_type="error"
|
||||
local sourcepath=''
|
||||
local linenumber=''
|
||||
local columnnumber=''
|
||||
local error_code=''
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
opt="$(echo "${1/#--/-}" | awk '{print tolower($0)}')"
|
||||
|
@ -76,7 +76,7 @@ function Write-PipelineTaskError {
|
|||
shift
|
||||
done
|
||||
|
||||
message="##vso[task.logissue"
|
||||
local message="##vso[task.logissue"
|
||||
|
||||
message="$message type=$message_type"
|
||||
|
||||
|
@ -100,3 +100,73 @@ function Write-PipelineTaskError {
|
|||
echo "$message"
|
||||
}
|
||||
|
||||
function Write-PipelineSetVariable {
|
||||
if [[ "$ci" != true ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
local name=''
|
||||
local value=''
|
||||
local secret=false
|
||||
local as_output=false
|
||||
local is_multi_job_variable=true
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
opt="$(echo "${1/#--/-}" | awk '{print tolower($0)}')"
|
||||
case "$opt" in
|
||||
-name|-n)
|
||||
name=$2
|
||||
shift
|
||||
;;
|
||||
-value|-v)
|
||||
value=$2
|
||||
shift
|
||||
;;
|
||||
-secret|-s)
|
||||
secret=true
|
||||
;;
|
||||
-as_output|-a)
|
||||
as_output=true
|
||||
;;
|
||||
-is_multi_job_variable|-i)
|
||||
is_multi_job_variable=$2
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
value=${value/;/%3B}
|
||||
value=${value/\\r/%0D}
|
||||
value=${value/\\n/%0A}
|
||||
value=${value/]/%5D}
|
||||
|
||||
local message="##vso[task.setvariable variable=$name;isSecret=$secret;isOutput=$is_multi_job_variable]$value"
|
||||
|
||||
if [[ "$as_output" == true ]]; then
|
||||
$message
|
||||
else
|
||||
echo "$message"
|
||||
fi
|
||||
}
|
||||
|
||||
function Write-PipelinePrependPath {
|
||||
local prepend_path=''
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
opt="$(echo "${1/#--/-}" | awk '{print tolower($0)}')"
|
||||
case "$opt" in
|
||||
-path|-p)
|
||||
prepend_path=$2
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
export PATH="$prepend_path:$PATH"
|
||||
|
||||
if [[ "$ci" == true ]]; then
|
||||
echo "##vso[task.prependpath]$prepend_path"
|
||||
fi
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
param(
|
||||
[Parameter(Mandatory=$true)][string] $BarBuildId, # ID of the build which assets should be downloaded
|
||||
[Parameter(Mandatory=$true)][string] $MaestroAccessToken, # Token used to access Maestro API
|
||||
[Parameter(Mandatory=$true)][string] $DropLocation # Where the assets should be downloaded to
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
Set-StrictMode -Version 2.0
|
||||
|
||||
. $PSScriptRoot\..\tools.ps1
|
||||
|
||||
try {
|
||||
Write-Host "Installing DARC ..."
|
||||
|
||||
. $PSScriptRoot\..\darc-init.ps1
|
||||
$exitCode = $LASTEXITCODE
|
||||
|
||||
if ($exitCode -ne 0) {
|
||||
Write-PipelineTaskError "Something failed while running 'darc-init.ps1'. Check for errors above. Exiting now..."
|
||||
ExitWithExitCode $exitCode
|
||||
}
|
||||
|
||||
darc gather-drop --non-shipping `
|
||||
--continue-on-error `
|
||||
--id $BarBuildId `
|
||||
--output-dir $DropLocation `
|
||||
--bar-uri https://maestro-prod.westus2.cloudapp.azure.com/ `
|
||||
--password $MaestroAccessToken `
|
||||
--latest-location
|
||||
}
|
||||
catch {
|
||||
Write-Host $_
|
||||
Write-Host $_.Exception
|
||||
Write-Host $_.ScriptStackTrace
|
||||
ExitWithExitCode 1
|
||||
}
|
|
@ -84,6 +84,7 @@ stages:
|
|||
/p:AzureStorageAccountName=$(ProxyBackedFeedsAccountName)
|
||||
/p:AzureStorageAccountKey=$(dotnetfeed-storage-access-key-1)
|
||||
/p:AzureDevOpsFeedsBaseUrl=$(dotnetfeed-internal-private-feed-url)
|
||||
/p:StaticInternalFeed=$(dotnetfeed-internal-nonstable-feed-url)
|
||||
/p:NugetPath=$(Agent.BuildDirectory)\Nuget\NuGet.exe
|
||||
/p:BARBuildId=$(BARBuildId)
|
||||
/p:MaestroApiEndpoint='https://maestro-prod.westus2.cloudapp.azure.com'
|
||||
|
@ -142,29 +143,6 @@ stages:
|
|||
filePath: $(Build.SourcesDirectory)/eng/common/post-build/symbols-validation.ps1
|
||||
arguments: -InputPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/ -ExtractPath $(Agent.BuildDirectory)/Temp/ -DotnetSymbolVersion $(SymbolToolVersion)
|
||||
|
||||
- job:
|
||||
displayName: Gather Drop
|
||||
dependsOn: setupMaestroVars
|
||||
variables:
|
||||
BARBuildId: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ]
|
||||
condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], variables.InternalServicing_30_Channel_Id)
|
||||
pool:
|
||||
vmImage: 'windows-2019'
|
||||
steps:
|
||||
- task: PowerShell@2
|
||||
displayName: Setup Darc CLI
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: '$(Build.SourcesDirectory)/eng/common/darc-init.ps1'
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: Run Darc gather-drop
|
||||
inputs:
|
||||
targetType: inline
|
||||
script: |
|
||||
darc gather-drop --non-shipping --continue-on-error --id $(BARBuildId) --output-dir $(Agent.BuildDirectory)/Temp/Drop/ --bar-uri https://maestro-prod.westus2.cloudapp.azure.com/ --password $(MaestroAccessToken) --latest-location
|
||||
enabled: false
|
||||
|
||||
- template: ../promote-build.yml
|
||||
parameters:
|
||||
ChannelId: ${{ variables.InternalServicing_30_Channel_Id }}
|
||||
|
|
|
@ -77,7 +77,7 @@ stages:
|
|||
filePath: eng\common\sdk-task.ps1
|
||||
arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet
|
||||
/p:ChannelId=$(PublicDevRelease_30_Channel_Id)
|
||||
/p:ArtifactsCategory=.NetCore
|
||||
/p:ArtifactsCategory=$(_DotNetArtifactsCategory)
|
||||
/p:IsStableBuild=$(IsStableBuild)
|
||||
/p:IsInternalBuild=$(IsInternalBuild)
|
||||
/p:RepositoryName=$(Build.Repository.Name)
|
||||
|
@ -139,27 +139,9 @@ stages:
|
|||
filePath: $(Build.SourcesDirectory)/eng/common/post-build/symbols-validation.ps1
|
||||
arguments: -InputPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/ -ExtractPath $(Agent.BuildDirectory)/Temp/ -DotnetSymbolVersion $(SymbolToolVersion)
|
||||
|
||||
- job:
|
||||
displayName: Gather Drop
|
||||
dependsOn: setupMaestroVars
|
||||
variables:
|
||||
BARBuildId: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ]
|
||||
condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], variables.PublicDevRelease_30_Channel_Id)
|
||||
pool:
|
||||
vmImage: 'windows-2019'
|
||||
steps:
|
||||
- task: PowerShell@2
|
||||
displayName: Setup Darc CLI
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: '$(Build.SourcesDirectory)/eng/common/darc-init.ps1'
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: Run Darc gather-drop
|
||||
inputs:
|
||||
targetType: inline
|
||||
script: |
|
||||
darc gather-drop --non-shipping --continue-on-error --id $(BARBuildId) --output-dir $(Agent.BuildDirectory)/Temp/Drop/ --bar-uri https://maestro-prod.westus2.cloudapp.azure.com/ --password $(MaestroAccessToken) --latest-location
|
||||
- template: ../darc-gather-drop.yml
|
||||
parameters:
|
||||
ChannelId: ${{ variables.PublicDevRelease_30_Channel_Id }}
|
||||
|
||||
- template: ../promote-build.yml
|
||||
parameters:
|
||||
|
|
|
@ -84,6 +84,7 @@ stages:
|
|||
/p:AzureStorageAccountName=$(ProxyBackedFeedsAccountName)
|
||||
/p:AzureStorageAccountKey=$(dotnetfeed-storage-access-key-1)
|
||||
/p:AzureDevOpsFeedsBaseUrl=$(dotnetfeed-internal-private-feed-url)
|
||||
/p:StaticInternalFeed=$(dotnetfeed-internal-nonstable-feed-url)
|
||||
/p:NugetPath=$(Agent.BuildDirectory)\Nuget\NuGet.exe
|
||||
/p:BARBuildId=$(BARBuildId)
|
||||
/p:MaestroApiEndpoint='https://maestro-prod.westus2.cloudapp.azure.com'
|
||||
|
@ -142,29 +143,6 @@ stages:
|
|||
filePath: $(Build.SourcesDirectory)/eng/common/post-build/symbols-validation.ps1
|
||||
arguments: -InputPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/ -ExtractPath $(Agent.BuildDirectory)/Temp/ -DotnetSymbolVersion $(SymbolToolVersion)
|
||||
|
||||
- job:
|
||||
displayName: Gather Drop
|
||||
dependsOn: setupMaestroVars
|
||||
variables:
|
||||
BARBuildId: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ]
|
||||
condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], variables.PublicRelease_30_Channel_Id)
|
||||
pool:
|
||||
vmImage: 'windows-2019'
|
||||
steps:
|
||||
- task: PowerShell@2
|
||||
displayName: Setup Darc CLI
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: '$(Build.SourcesDirectory)/eng/common/darc-init.ps1'
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: Run Darc gather-drop
|
||||
inputs:
|
||||
targetType: inline
|
||||
script: |
|
||||
darc gather-drop --non-shipping --continue-on-error --id $(BARBuildId) --output-dir $(Agent.BuildDirectory)/Temp/Drop/ --bar-uri https://maestro-prod.westus2.cloudapp.azure.com/ --password $(MaestroAccessToken) --latest-location
|
||||
enabled: false
|
||||
|
||||
- template: ../promote-build.yml
|
||||
parameters:
|
||||
ChannelId: ${{ variables.PublicRelease_30_Channel_Id }}
|
||||
|
|
|
@ -48,7 +48,7 @@ stages:
|
|||
filePath: eng\common\sdk-task.ps1
|
||||
arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet
|
||||
/p:ChannelId=$(PublicValidationRelease_30_Channel_Id)
|
||||
/p:ArtifactsCategory=.NetCoreValidation
|
||||
/p:ArtifactsCategory=$(_DotNetArtifactsCategory)
|
||||
/p:IsStableBuild=$(IsStableBuild)
|
||||
/p:IsInternalBuild=$(IsInternalBuild)
|
||||
/p:RepositoryName=$(Build.Repository.Name)
|
||||
|
@ -91,29 +91,9 @@ stages:
|
|||
jobs:
|
||||
- template: ../setup-maestro-vars.yml
|
||||
|
||||
- job:
|
||||
displayName: Gather Drop
|
||||
dependsOn: setupMaestroVars
|
||||
condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], variables.PublicValidationRelease_30_Channel_Id)
|
||||
variables:
|
||||
- name: BARBuildId
|
||||
value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ]
|
||||
- group: Publish-Build-Assets
|
||||
pool:
|
||||
vmImage: 'windows-2019'
|
||||
steps:
|
||||
- task: PowerShell@2
|
||||
displayName: Setup Darc CLI
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: '$(Build.SourcesDirectory)/eng/common/darc-init.ps1'
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: Run Darc gather-drop
|
||||
inputs:
|
||||
targetType: inline
|
||||
script: |
|
||||
darc gather-drop --non-shipping --continue-on-error --id $(BARBuildId) --output-dir $(Agent.BuildDirectory)/Temp/Drop/ --bar-uri https://maestro-prod.westus2.cloudapp.azure.com --password $(MaestroAccessToken) --latest-location
|
||||
- template: ../darc-gather-drop.yml
|
||||
parameters:
|
||||
ChannelId: ${{ variables.PublicValidationRelease_30_Channel_Id }}
|
||||
|
||||
- template: ../promote-build.yml
|
||||
parameters:
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
parameters:
|
||||
ChannelId: 0
|
||||
|
||||
jobs:
|
||||
- job: gatherDrop
|
||||
displayName: Gather Drop
|
||||
dependsOn: setupMaestroVars
|
||||
condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], ${{ parameters.ChannelId }})
|
||||
variables:
|
||||
- group: Publish-Build-Assets
|
||||
- name: BARBuildId
|
||||
value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ]
|
||||
pool:
|
||||
vmImage: 'windows-2019'
|
||||
steps:
|
||||
- task: PowerShell@2
|
||||
displayName: Darc gather-drop
|
||||
inputs:
|
||||
filePath: $(Build.SourcesDirectory)/eng/common/post-build/darc-gather-drop.ps1
|
||||
arguments: -BarBuildId $(BARBuildId)
|
||||
-DropLocation $(Agent.BuildDirectory)/Temp/Drop/
|
||||
-MaestroAccessToken $(MaestroAccessToken)
|
|
@ -8,4 +8,4 @@ steps:
|
|||
filePath: $(Build.SourcesDirectory)/eng/common/post-build/trigger-subscriptions.ps1
|
||||
arguments: -SourceRepo $(Build.Repository.Uri)
|
||||
-ChannelId ${{ parameters.ChannelId }}
|
||||
-BarToken $(MaestroAccessTokenInt)
|
||||
-BarToken $(MaestroAccessToken)
|
||||
|
|
|
@ -169,7 +169,7 @@ function InstallDotNetSdk([string] $dotnetRoot, [string] $version, [string] $arc
|
|||
InstallDotNet $dotnetRoot $version $architecture
|
||||
}
|
||||
|
||||
function InstallDotNet([string] $dotnetRoot, [string] $version, [string] $architecture = "", [string] $runtime = "", [bool] $skipNonVersionedFiles = $false) { $installScript = GetDotNetInstallScript $dotnetRoot
|
||||
function InstallDotNet([string] $dotnetRoot, [string] $version, [string] $architecture = "", [string] $runtime = "", [bool] $skipNonVersionedFiles = $false) {
|
||||
$installScript = GetDotNetInstallScript $dotnetRoot
|
||||
$installParameters = @{
|
||||
Version = $version
|
||||
|
|
|
@ -77,7 +77,7 @@ function ReadGlobalVersion {
|
|||
local pattern="\"$key\" *: *\"(.*)\""
|
||||
|
||||
if [[ ! $line =~ $pattern ]]; then
|
||||
Write-PipelineTelemetryError -category 'InitializeTools' "Error: Cannot find \"$key\" in $global_json_file"
|
||||
Write-PipelineTelemetryError -category 'InitializeToolset' "Error: Cannot find \"$key\" in $global_json_file"
|
||||
ExitWithExitCode 1
|
||||
fi
|
||||
|
||||
|
@ -146,14 +146,10 @@ function InitializeDotNetCli {
|
|||
|
||||
# Add dotnet to PATH. This prevents any bare invocation of dotnet in custom
|
||||
# build steps from using anything other than what we've downloaded.
|
||||
export PATH="$dotnet_root:$PATH"
|
||||
Write-PipelinePrependPath -path "$dotnet_root"
|
||||
|
||||
if [[ $ci == true ]]; then
|
||||
# Make Sure that our bootstrapped dotnet cli is available in future steps of the Azure Pipelines build
|
||||
echo "##vso[task.prependpath]$dotnet_root"
|
||||
echo "##vso[task.setvariable variable=DOTNET_MULTILEVEL_LOOKUP]0"
|
||||
echo "##vso[task.setvariable variable=DOTNET_SKIP_FIRST_TIME_EXPERIENCE]1"
|
||||
fi
|
||||
Write-PipelineSetVariable -name "DOTNET_MULTILEVEL_LOOKUP" -value "0"
|
||||
Write-PipelineSetVariable -name "DOTNET_SKIP_FIRST_TIME_EXPERIENCE" -value "1"
|
||||
|
||||
# return value
|
||||
_InitializeDotNetCli="$dotnet_root"
|
||||
|
@ -249,7 +245,7 @@ function InitializeNativeTools() {
|
|||
then
|
||||
local nativeArgs=""
|
||||
if [[ "$ci" == true ]]; then
|
||||
nativeArgs="-InstallDirectory $tools_dir"
|
||||
nativeArgs="--installDirectory $tools_dir"
|
||||
fi
|
||||
"$_script_dir/init-tools-native.sh" $nativeArgs
|
||||
fi
|
||||
|
@ -389,7 +385,8 @@ mkdir -p "$toolset_dir"
|
|||
mkdir -p "$temp_dir"
|
||||
mkdir -p "$log_dir"
|
||||
|
||||
if [[ $ci == true ]]; then
|
||||
export TEMP="$temp_dir"
|
||||
export TMP="$temp_dir"
|
||||
fi
|
||||
Write-PipelineSetVariable -name "Artifacts" -value "$artifacts_dir"
|
||||
Write-PipelineSetVariable -name "Artifacts.Toolset" -value "$toolset_dir"
|
||||
Write-PipelineSetVariable -name "Artifacts.Log" -value "$log_dir"
|
||||
Write-PipelineSetVariable -name "Temp" -value "$temp_dir"
|
||||
Write-PipelineSetVariable -name "TMP" -value "$temp_dir"
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
}
|
||||
},
|
||||
"msbuild-sdks": {
|
||||
"Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.19364.1",
|
||||
"Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.19375.15",
|
||||
"Microsoft.DotNet.Helix.Sdk": "2.0.0-beta.19069.2"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3025,7 +3025,8 @@ let generateIL requiredDataFixups (desiredMetadataVersion, generatePdb, ilg : IL
|
|||
//=====================================================================
|
||||
// TABLES+BLOBS --> PHYSICAL METADATA+BLOBS
|
||||
//=====================================================================
|
||||
let chunk sz next = ({addr=next; size=sz}, next + sz)
|
||||
let chunk sz next = ({addr=next; size=sz}, next + sz)
|
||||
let emptychunk next = ({addr=next; size=0}, next)
|
||||
let nochunk next = ({addr= 0x0;size= 0x0; }, next)
|
||||
|
||||
let count f arr =
|
||||
|
@ -3513,7 +3514,7 @@ let writeBytes (os: BinaryWriter) (chunk: byte[]) = os.Write(chunk, 0, chunk.Len
|
|||
|
||||
let writeBinaryAndReportMappings (outfile,
|
||||
ilg: ILGlobals, pdbfile: string option, signer: ILStrongNameSigner option, portablePDB, embeddedPDB,
|
||||
embedAllSource, embedSourceList, sourceLink, emitTailcalls, deterministic, showTimes, dumpDebugInfo, pathMap)
|
||||
embedAllSource, embedSourceList, sourceLink, checksumAlgorithm, emitTailcalls, deterministic, showTimes, dumpDebugInfo, 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
|
||||
|
@ -3562,7 +3563,7 @@ let writeBinaryAndReportMappings (outfile,
|
|||
with e ->
|
||||
failwith ("Could not open file for writing (binary mode): " + outfile)
|
||||
|
||||
let pdbData, pdbOpt, debugDirectoryChunk, debugDataChunk, debugEmbeddedPdbChunk, textV2P, mappings =
|
||||
let pdbData, pdbOpt, debugDirectoryChunk, debugDataChunk, debugChecksumPdbChunk, debugEmbeddedPdbChunk, debugDeterministicPdbChunk, textV2P, mappings =
|
||||
try
|
||||
|
||||
let imageBaseReal = modul.ImageBase // FIXED CHOICE
|
||||
|
@ -3667,42 +3668,61 @@ let writeBinaryAndReportMappings (outfile,
|
|||
let pdbOpt =
|
||||
match portablePDB with
|
||||
| true ->
|
||||
let (uncompressedLength, contentId, stream) as pdbStream =
|
||||
generatePortablePdb embedAllSource embedSourceList sourceLink showTimes pdbData deterministic pathMap
|
||||
let (uncompressedLength, contentId, stream, algorithmName, checkSum) as pdbStream =
|
||||
generatePortablePdb embedAllSource embedSourceList sourceLink checksumAlgorithm showTimes pdbData pathMap
|
||||
|
||||
if embeddedPDB then Some (compressPortablePdbStream uncompressedLength contentId stream)
|
||||
if embeddedPDB then
|
||||
let uncompressedLength, contentId, stream = compressPortablePdbStream uncompressedLength contentId stream
|
||||
Some (uncompressedLength, contentId, stream, algorithmName, checkSum)
|
||||
else Some pdbStream
|
||||
|
||||
| _ -> None
|
||||
|
||||
let debugDirectoryChunk, next =
|
||||
chunk (if pdbfile = None then
|
||||
0x0
|
||||
else if embeddedPDB && portablePDB then
|
||||
sizeof_IMAGE_DEBUG_DIRECTORY * 2
|
||||
let debugDirectoryChunk, next =
|
||||
chunk (if pdbfile = None then
|
||||
0x0
|
||||
else
|
||||
sizeof_IMAGE_DEBUG_DIRECTORY
|
||||
sizeof_IMAGE_DEBUG_DIRECTORY * 2 +
|
||||
(if embeddedPDB then sizeof_IMAGE_DEBUG_DIRECTORY else 0) +
|
||||
(if deterministic then sizeof_IMAGE_DEBUG_DIRECTORY else 0)
|
||||
) next
|
||||
|
||||
// The debug data is given to us by the PDB writer and appears to
|
||||
// typically be the type of the data plus the PDB file name. We fill
|
||||
// this in after we've written the binary. We approximate the size according
|
||||
// to what PDB writers seem to require and leave extra space just in case...
|
||||
let debugDataJustInCase = 40
|
||||
let debugDataChunk, next =
|
||||
let debugDataChunk, next =
|
||||
chunk (align 0x4 (match pdbfile with
|
||||
| None -> 0
|
||||
| Some f -> (24
|
||||
+ System.Text.Encoding.Unicode.GetByteCount f // See bug 748444
|
||||
+ debugDataJustInCase))) next
|
||||
|
||||
let debugEmbeddedPdbChunk, next =
|
||||
let streamLength =
|
||||
match pdbOpt with
|
||||
| Some (_, _, stream) -> int stream.Length
|
||||
| None -> 0
|
||||
chunk (align 0x4 (match embeddedPDB with
|
||||
| true -> 8 + streamLength
|
||||
| _ -> 0 )) next
|
||||
let debugChecksumPdbChunk, next =
|
||||
chunk (align 0x4 (match pdbOpt with
|
||||
| Some (_, _, _, algorithmName, checkSum) ->
|
||||
let alg = System.Text.Encoding.UTF8.GetBytes(algorithmName)
|
||||
let size = alg.Length + 1 + checkSum.Length
|
||||
size
|
||||
| None -> 0)) next
|
||||
|
||||
let debugEmbeddedPdbChunk, next =
|
||||
if embeddedPDB then
|
||||
let streamLength =
|
||||
match pdbOpt with
|
||||
| Some (_, _, stream, _, _) -> int stream.Length
|
||||
| None -> 0
|
||||
chunk (align 0x4 (match embeddedPDB with
|
||||
| true -> 8 + streamLength
|
||||
| _ -> 0 )) next
|
||||
else
|
||||
nochunk next
|
||||
|
||||
let debugDeterministicPdbChunk, next =
|
||||
if deterministic then emptychunk next
|
||||
else nochunk next
|
||||
|
||||
|
||||
let textSectionSize = next - textSectionAddr
|
||||
let nextPhys = align alignPhys (textSectionPhysLoc + textSectionSize)
|
||||
|
@ -3801,35 +3821,39 @@ let writeBinaryAndReportMappings (outfile,
|
|||
if pCurrent <> pExpected then
|
||||
failwith ("warning: "+chunkName+" not where expected, pCurrent = "+string pCurrent+", p.addr = "+string pExpected)
|
||||
writeBytes os chunk
|
||||
|
||||
|
||||
let writePadding (os: BinaryWriter) _comment sz =
|
||||
if sz < 0 then failwith "writePadding: size < 0"
|
||||
for i = 0 to sz - 1 do
|
||||
os.Write 0uy
|
||||
|
||||
|
||||
// Now we've computed all the offsets, write the image
|
||||
|
||||
|
||||
write (Some msdosHeaderChunk.addr) os "msdos header" msdosHeader
|
||||
|
||||
|
||||
write (Some peSignatureChunk.addr) os "pe signature" [| |]
|
||||
|
||||
|
||||
writeInt32 os 0x4550
|
||||
|
||||
|
||||
write (Some peFileHeaderChunk.addr) os "pe file header" [| |]
|
||||
|
||||
|
||||
if (modul.Platform = Some AMD64) then
|
||||
writeInt32AsUInt16 os 0x8664 // Machine - IMAGE_FILE_MACHINE_AMD64
|
||||
elif isItanium then
|
||||
writeInt32AsUInt16 os 0x200
|
||||
else
|
||||
writeInt32AsUInt16 os 0x014c // Machine - IMAGE_FILE_MACHINE_I386
|
||||
|
||||
|
||||
writeInt32AsUInt16 os numSections
|
||||
|
||||
let pdbData =
|
||||
let pdbData =
|
||||
// Hash code, data and metadata
|
||||
if deterministic then
|
||||
// Hash code, data and metadata
|
||||
use sha = System.Security.Cryptography.SHA1.Create() // IncrementalHash is core only
|
||||
use sha =
|
||||
match checksumAlgorithm with
|
||||
| HashAlgorithm.Sha1 -> System.Security.Cryptography.SHA1.Create() :> System.Security.Cryptography.HashAlgorithm
|
||||
| HashAlgorithm.Sha256 -> System.Security.Cryptography.SHA256.Create() :> System.Security.Cryptography.HashAlgorithm
|
||||
|
||||
let hCode = sha.ComputeHash code
|
||||
let hData = sha.ComputeHash data
|
||||
let hMeta = sha.ComputeHash metadata
|
||||
|
@ -3845,6 +3869,7 @@ let writeBinaryAndReportMappings (outfile,
|
|||
// Use last 4 bytes for timestamp - High bit set, to stop tool chains becoming confused
|
||||
let timestamp = int final.[16] ||| (int final.[17] <<< 8) ||| (int final.[18] <<< 16) ||| (int (final.[19] ||| 128uy) <<< 24)
|
||||
writeInt32 os timestamp
|
||||
|
||||
// Update pdbData with new guid and timestamp. Portable and embedded PDBs don't need the ModuleID
|
||||
// Full and PdbOnly aren't supported under deterministic builds currently, they rely on non-determinsitic Windows native code
|
||||
{ pdbData with ModuleID = final.[0..15] ; Timestamp = timestamp }
|
||||
|
@ -4130,10 +4155,14 @@ let writeBinaryAndReportMappings (outfile,
|
|||
if pdbfile.IsSome then
|
||||
write (Some (textV2P debugDirectoryChunk.addr)) os "debug directory" (Array.create debugDirectoryChunk.size 0x0uy)
|
||||
write (Some (textV2P debugDataChunk.addr)) os "debug data" (Array.create debugDataChunk.size 0x0uy)
|
||||
write (Some (textV2P debugChecksumPdbChunk.addr)) os "debug checksum" (Array.create debugChecksumPdbChunk.size 0x0uy)
|
||||
|
||||
if embeddedPDB then
|
||||
write (Some (textV2P debugEmbeddedPdbChunk.addr)) os "debug data" (Array.create debugEmbeddedPdbChunk.size 0x0uy)
|
||||
|
||||
if deterministic then
|
||||
write (Some (textV2P debugDeterministicPdbChunk.addr)) os "debug deterministic" Array.empty
|
||||
|
||||
writePadding os "end of .text" (dataSectionPhysLoc - textSectionPhysLoc - textSectionSize)
|
||||
|
||||
// DATA SECTION
|
||||
|
@ -4179,7 +4208,7 @@ let writeBinaryAndReportMappings (outfile,
|
|||
FileSystemUtilites.setExecutablePermission outfile
|
||||
with _ ->
|
||||
()
|
||||
pdbData, pdbOpt, debugDirectoryChunk, debugDataChunk, debugEmbeddedPdbChunk, textV2P, mappings
|
||||
pdbData, pdbOpt, debugDirectoryChunk, debugDataChunk, debugChecksumPdbChunk, debugEmbeddedPdbChunk, debugDeterministicPdbChunk, textV2P, mappings
|
||||
|
||||
// Looks like a finally
|
||||
with e ->
|
||||
|
@ -4204,11 +4233,11 @@ let writeBinaryAndReportMappings (outfile,
|
|||
try
|
||||
let idd =
|
||||
match pdbOpt with
|
||||
| Some (originalLength, contentId, stream) ->
|
||||
| Some (originalLength, contentId, stream, algorithmName, checkSum) ->
|
||||
if embeddedPDB then
|
||||
embedPortablePdbInfo originalLength contentId stream showTimes fpdb debugDataChunk debugEmbeddedPdbChunk
|
||||
embedPortablePdbInfo originalLength contentId stream showTimes fpdb debugDataChunk debugEmbeddedPdbChunk debugDeterministicPdbChunk debugChecksumPdbChunk algorithmName checkSum embeddedPDB deterministic
|
||||
else
|
||||
writePortablePdbInfo contentId stream showTimes fpdb pathMap debugDataChunk
|
||||
writePortablePdbInfo contentId stream showTimes fpdb pathMap debugDataChunk debugDeterministicPdbChunk debugChecksumPdbChunk algorithmName checkSum embeddedPDB deterministic
|
||||
| None ->
|
||||
#if FX_NO_PDB_WRITER
|
||||
Array.empty<idd>
|
||||
|
@ -4229,16 +4258,17 @@ let writeBinaryAndReportMappings (outfile,
|
|||
writeInt32AsUInt16 os2 i.iddMajorVersion
|
||||
writeInt32AsUInt16 os2 i.iddMinorVersion
|
||||
writeInt32 os2 i.iddType
|
||||
writeInt32 os2 i.iddData.Length // IMAGE_DEBUG_DIRECTORY.SizeOfData
|
||||
writeInt32 os2 i.iddChunk.addr // IMAGE_DEBUG_DIRECTORY.AddressOfRawData
|
||||
writeInt32 os2 (textV2P i.iddChunk.addr) // IMAGE_DEBUG_DIRECTORY.PointerToRawData
|
||||
writeInt32 os2 i.iddData.Length // IMAGE_DEBUG_DIRECTORY.SizeOfData
|
||||
writeInt32 os2 i.iddChunk.addr // IMAGE_DEBUG_DIRECTORY.AddressOfRawData
|
||||
writeInt32 os2 (textV2P i.iddChunk.addr) // IMAGE_DEBUG_DIRECTORY.PointerToRawData
|
||||
|
||||
// Write the Debug Data
|
||||
for i in idd do
|
||||
// write the debug raw data as given us by the PDB writer
|
||||
os2.BaseStream.Seek (int64 (textV2P i.iddChunk.addr), SeekOrigin.Begin) |> ignore
|
||||
if i.iddChunk.size < i.iddData.Length then failwith "Debug data area is not big enough. Debug info may not be usable"
|
||||
writeBytes os2 i.iddData
|
||||
if i.iddChunk.size <> 0 then
|
||||
// write the debug raw data as given us by the PDB writer
|
||||
os2.BaseStream.Seek (int64 (textV2P i.iddChunk.addr), SeekOrigin.Begin) |> ignore
|
||||
if i.iddChunk.size < i.iddData.Length then failwith "Debug data area is not big enough. Debug info may not be usable"
|
||||
writeBytes os2 i.iddData
|
||||
os2.Dispose()
|
||||
with e ->
|
||||
failwith ("Error while writing debug directory entry: "+e.Message)
|
||||
|
@ -4247,9 +4277,7 @@ let writeBinaryAndReportMappings (outfile,
|
|||
with e ->
|
||||
reraise()
|
||||
|
||||
end
|
||||
ignore debugDataChunk
|
||||
ignore debugEmbeddedPdbChunk
|
||||
end
|
||||
reportTime showTimes "Finalize PDB"
|
||||
|
||||
/// Sign the binary. No further changes to binary allowed past this point!
|
||||
|
@ -4277,9 +4305,10 @@ type options =
|
|||
embedAllSource: bool
|
||||
embedSourceList: string list
|
||||
sourceLink: string
|
||||
checksumAlgorithm: HashAlgorithm
|
||||
signer: ILStrongNameSigner option
|
||||
emitTailcalls : bool
|
||||
deterministic : bool
|
||||
emitTailcalls: bool
|
||||
deterministic: bool
|
||||
showTimes: bool
|
||||
dumpDebugInfo: bool
|
||||
pathMap: PathMap }
|
||||
|
@ -4287,5 +4316,5 @@ type options =
|
|||
let WriteILBinary (outfile, (args: options), modul, normalizeAssemblyRefs) =
|
||||
writeBinaryAndReportMappings (outfile,
|
||||
args.ilg, args.pdbfile, args.signer, args.portablePDB, args.embeddedPDB, args.embedAllSource,
|
||||
args.embedSourceList, args.sourceLink, args.emitTailcalls, args.deterministic, args.showTimes, args.dumpDebugInfo, args.pathMap) modul normalizeAssemblyRefs
|
||||
args.embedSourceList, args.sourceLink, args.checksumAlgorithm, args.emitTailcalls, args.deterministic, args.showTimes, args.dumpDebugInfo, args.pathMap) modul normalizeAssemblyRefs
|
||||
|> ignore
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
|
||||
|
||||
/// The IL Binary writer.
|
||||
module internal FSharp.Compiler.AbstractIL.ILBinaryWriter
|
||||
module internal FSharp.Compiler.AbstractIL.ILBinaryWriter
|
||||
|
||||
open Internal.Utilities
|
||||
open FSharp.Compiler.AbstractIL
|
||||
open FSharp.Compiler.AbstractIL.Internal
|
||||
open FSharp.Compiler.AbstractIL.IL
|
||||
open FSharp.Compiler.AbstractIL
|
||||
open FSharp.Compiler.AbstractIL.Internal
|
||||
open FSharp.Compiler.AbstractIL.IL
|
||||
open FSharp.Compiler.AbstractIL.ILPdbWriter
|
||||
|
||||
[<Sealed>]
|
||||
type ILStrongNameSigner =
|
||||
|
@ -24,6 +25,7 @@ type options =
|
|||
embedAllSource: bool
|
||||
embedSourceList: string list
|
||||
sourceLink: string
|
||||
checksumAlgorithm: HashAlgorithm
|
||||
signer : ILStrongNameSigner option
|
||||
emitTailcalls: bool
|
||||
deterministic: bool
|
||||
|
|
|
@ -11,8 +11,9 @@ open System.Reflection
|
|||
open System.Reflection.Metadata
|
||||
open System.Reflection.Metadata.Ecma335
|
||||
open System.Reflection.PortableExecutable
|
||||
open System.Text
|
||||
open Internal.Utilities
|
||||
open FSharp.Compiler.AbstractIL.IL
|
||||
open FSharp.Compiler.AbstractIL.IL
|
||||
open FSharp.Compiler.AbstractIL.Diagnostics
|
||||
open FSharp.Compiler.AbstractIL.Internal.Support
|
||||
open FSharp.Compiler.AbstractIL.Internal.Library
|
||||
|
@ -125,6 +126,27 @@ type idd =
|
|||
iddData: byte[]
|
||||
iddChunk: BinaryChunk }
|
||||
|
||||
/// The specified Hash algorithm to use on portable pdb files.
|
||||
type HashAlgorithm =
|
||||
| Sha1
|
||||
| Sha256
|
||||
|
||||
// Document checksum algorithms
|
||||
let guidSha1 = Guid("ff1816ec-aa5e-4d10-87f7-6f4963833460")
|
||||
let guidSha2 = Guid("8829d00f-11b8-4213-878b-770e8597ac16")
|
||||
|
||||
let checkSum (url: string) (checksumAlgorithm: HashAlgorithm) =
|
||||
try
|
||||
use file = FileSystem.FileStreamReadShim url
|
||||
let guid, alg =
|
||||
match checksumAlgorithm with
|
||||
| HashAlgorithm.Sha1 -> guidSha1, System.Security.Cryptography.SHA1.Create() :> System.Security.Cryptography.HashAlgorithm
|
||||
| HashAlgorithm.Sha256 -> guidSha2, System.Security.Cryptography.SHA256.Create() :> System.Security.Cryptography.HashAlgorithm
|
||||
|
||||
let checkSum = alg.ComputeHash file
|
||||
Some (guid, checkSum)
|
||||
with _ -> None
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Portable PDB Writer
|
||||
//---------------------------------------------------------------------
|
||||
|
@ -153,7 +175,7 @@ let pdbGetCvDebugInfo (mvid: byte[]) (timestamp: int32) (filepath: string) (cvCh
|
|||
}
|
||||
|
||||
let pdbMagicNumber= 0x4244504dL
|
||||
let pdbGetPdbDebugInfo (embeddedPDBChunk: BinaryChunk) (uncompressedLength: int64) (stream: MemoryStream) =
|
||||
let pdbGetEmbeddedPdbDebugInfo (embeddedPdbChunk: BinaryChunk) (uncompressedLength: int64) (stream: MemoryStream) =
|
||||
let iddPdbBuffer =
|
||||
let buffer = Array.zeroCreate (sizeof<int32> + sizeof<int32> + int(stream.Length))
|
||||
let (offset, size) = (0, sizeof<int32>) // Magic Number dword: 0x4244504dL
|
||||
|
@ -164,33 +186,57 @@ let pdbGetPdbDebugInfo (embeddedPDBChunk: BinaryChunk) (uncompressedLength: int6
|
|||
Buffer.BlockCopy(stream.ToArray(), 0, buffer, offset, size)
|
||||
buffer
|
||||
{ iddCharacteristics = 0 // Reserved
|
||||
iddMajorVersion = 0 // VersionMajor should be 0
|
||||
iddMajorVersion = 0x0100 // VersionMajor should be 0x0100
|
||||
iddMinorVersion = 0x0100 // VersionMinor should be 0x0100
|
||||
iddType = 17 // IMAGE_DEBUG_TYPE_EMBEDDEDPDB
|
||||
iddTimestamp = 0
|
||||
iddData = iddPdbBuffer // Path name to the pdb file when built
|
||||
iddChunk = embeddedPDBChunk
|
||||
iddChunk = embeddedPdbChunk
|
||||
}
|
||||
|
||||
let pdbGetDebugInfo (mvid: byte[]) (timestamp: int32) (filepath: string) (cvChunk: BinaryChunk) (embeddedPDBChunk: BinaryChunk option) (uncompressedLength: int64) (stream: MemoryStream option) =
|
||||
match stream, embeddedPDBChunk with
|
||||
| None, _ | _, None -> [| pdbGetCvDebugInfo mvid timestamp filepath cvChunk |]
|
||||
| Some s, Some chunk -> [| pdbGetCvDebugInfo mvid timestamp filepath cvChunk; pdbGetPdbDebugInfo chunk uncompressedLength s |]
|
||||
let pdbChecksumDebugInfo timestamp (checksumPdbChunk: BinaryChunk) (algorithmName:string) (checksum: byte[]) =
|
||||
let iddBuffer =
|
||||
let alg = Encoding.UTF8.GetBytes(algorithmName)
|
||||
let buffer = Array.zeroCreate (alg.Length + 1 + checksum.Length)
|
||||
Buffer.BlockCopy(alg, 0, buffer, 0, alg.Length)
|
||||
Buffer.BlockCopy(checksum, 0, buffer, alg.Length + 1, checksum.Length)
|
||||
buffer
|
||||
{ iddCharacteristics = 0 // Reserved
|
||||
iddMajorVersion = 1 // VersionMajor should be 1
|
||||
iddMinorVersion = 0x0100 // VersionMinor should be 0x0100
|
||||
iddType = 19 // IMAGE_DEBUG_TYPE_CHECKSUMPDB
|
||||
iddTimestamp = timestamp
|
||||
iddData = iddBuffer // Path name to the pdb file when built
|
||||
iddChunk = checksumPdbChunk
|
||||
}
|
||||
|
||||
// Document checksum algorithms
|
||||
let guidSourceHashMD5 = System.Guid(0x406ea660u, 0x64cfus, 0x4c82us, 0xb6uy, 0xf0uy, 0x42uy, 0xd4uy, 0x81uy, 0x72uy, 0xa7uy, 0x99uy) //406ea660-64cf-4c82-b6f0-42d48172a799
|
||||
let hashSizeOfMD5 = 16
|
||||
let pdbGetPdbDebugDeterministicInfo (deterministicPdbChunk: BinaryChunk) =
|
||||
{ iddCharacteristics = 0 // Reserved
|
||||
iddMajorVersion = 0 // VersionMajor should be 0
|
||||
iddMinorVersion = 0 // VersionMinor should be 00
|
||||
iddType = 16 // IMAGE_DEBUG_TYPE_DETERMINISTIC
|
||||
iddTimestamp = 0
|
||||
iddData = Array.empty // No DATA
|
||||
iddChunk = deterministicPdbChunk
|
||||
}
|
||||
|
||||
// If the FIPS algorithm policy is enabled on the computer (e.g., for US government employees and contractors)
|
||||
// then obtaining the MD5 implementation in BCL will throw.
|
||||
// In this case, catch the failure, and not set a checksum.
|
||||
let checkSum (url: string) =
|
||||
try
|
||||
use file = FileSystem.FileStreamReadShim url
|
||||
use md5 = System.Security.Cryptography.MD5.Create()
|
||||
let checkSum = md5.ComputeHash file
|
||||
Some (guidSourceHashMD5, checkSum)
|
||||
with _ -> None
|
||||
let pdbGetDebugInfo (contentId: byte[]) (timestamp: int32) (filepath: string)
|
||||
(cvChunk: BinaryChunk)
|
||||
(embeddedPdbChunk: BinaryChunk option)
|
||||
(deterministicPdbChunk: BinaryChunk)
|
||||
(checksumPdbChunk: BinaryChunk) (algorithmName:string) (checksum: byte [])
|
||||
(uncompressedLength: int64) (stream: MemoryStream option)
|
||||
(embeddedPdb: bool) (deterministic: bool) =
|
||||
[| yield pdbGetCvDebugInfo contentId timestamp filepath cvChunk
|
||||
yield pdbChecksumDebugInfo timestamp checksumPdbChunk algorithmName checksum
|
||||
if embeddedPdb then
|
||||
match stream, embeddedPdbChunk with
|
||||
| None, _ | _, None -> ()
|
||||
| Some s, Some chunk ->
|
||||
yield pdbGetEmbeddedPdbDebugInfo chunk uncompressedLength s
|
||||
if deterministic then
|
||||
yield pdbGetPdbDebugDeterministicInfo deterministicPdbChunk
|
||||
|]
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// PDB Writer. The function [WritePdbInfo] abstracts the
|
||||
|
@ -219,7 +265,7 @@ let getRowCounts tableRowCounts =
|
|||
tableRowCounts |> Seq.iter(fun x -> builder.Add x)
|
||||
builder.MoveToImmutable()
|
||||
|
||||
let generatePortablePdb (embedAllSource: bool) (embedSourceList: string list) (sourceLink: string) showTimes (info: PdbData) isDeterministic (pathMap: PathMap) =
|
||||
let generatePortablePdb (embedAllSource: bool) (embedSourceList: string list) (sourceLink: string) checksumAlgorithm showTimes (info: PdbData) (pathMap: PathMap) =
|
||||
sortMethods showTimes info
|
||||
let externalRowCounts = getRowCounts info.TableRowCounts
|
||||
let docs =
|
||||
|
@ -286,7 +332,7 @@ let generatePortablePdb (embedAllSource: bool) (embedSourceList: string list) (s
|
|||
metadata.SetCapacity(TableIndex.Document, docLength)
|
||||
for doc in docs do
|
||||
let handle =
|
||||
match checkSum doc.File with
|
||||
match checkSum doc.File checksumAlgorithm with
|
||||
| Some (hashAlg, checkSum) ->
|
||||
let dbgInfo =
|
||||
(serializeDocumentName doc.File,
|
||||
|
@ -481,25 +527,28 @@ let generatePortablePdb (embedAllSource: bool) (embedSourceList: string list) (s
|
|||
| None -> MetadataTokens.MethodDefinitionHandle 0
|
||||
| Some x -> MetadataTokens.MethodDefinitionHandle x
|
||||
|
||||
let deterministicIdProvider isDeterministic : System.Func<IEnumerable<Blob>, BlobContentId> =
|
||||
match isDeterministic with
|
||||
| false -> null
|
||||
| true ->
|
||||
let convert (content: IEnumerable<Blob>) =
|
||||
use sha = System.Security.Cryptography.SHA1.Create() // IncrementalHash is core only
|
||||
let hash = content
|
||||
|> Seq.collect (fun c -> c.GetBytes().Array |> sha.ComputeHash)
|
||||
|> Array.ofSeq |> sha.ComputeHash
|
||||
BlobContentId.FromHash hash
|
||||
System.Func<IEnumerable<Blob>, BlobContentId>( convert )
|
||||
// Compute the contentId for the pdb. Always do it deterministically, since we have to compute the anyway.
|
||||
// The contentId is the hash of the ID using whichever algorithm has been specified to the compiler
|
||||
let mutable contentHash = Array.empty<byte>
|
||||
|
||||
let serializer = PortablePdbBuilder(metadata, externalRowCounts, entryPoint, deterministicIdProvider isDeterministic)
|
||||
let algorithmName, hashAlgorithm =
|
||||
match checksumAlgorithm with
|
||||
| HashAlgorithm.Sha1 -> "SHA1", System.Security.Cryptography.SHA1.Create() :> System.Security.Cryptography.HashAlgorithm
|
||||
| HashAlgorithm.Sha256 -> "SHA256", System.Security.Cryptography.SHA256.Create() :> System.Security.Cryptography.HashAlgorithm
|
||||
let idProvider: System.Func<IEnumerable<Blob>, BlobContentId> =
|
||||
let convert (content: IEnumerable<Blob>) =
|
||||
let contentBytes = content |> Seq.collect (fun c -> c.GetBytes()) |> Array.ofSeq
|
||||
contentHash <- contentBytes |> hashAlgorithm.ComputeHash
|
||||
BlobContentId.FromHash contentHash
|
||||
System.Func<IEnumerable<Blob>, BlobContentId>(convert)
|
||||
|
||||
let serializer = PortablePdbBuilder(metadata, externalRowCounts, entryPoint, idProvider)
|
||||
let blobBuilder = new BlobBuilder()
|
||||
let contentId= serializer.Serialize blobBuilder
|
||||
let portablePdbStream = new MemoryStream()
|
||||
blobBuilder.WriteContentTo portablePdbStream
|
||||
reportTime showTimes "PDB: Created"
|
||||
(portablePdbStream.Length, contentId, portablePdbStream)
|
||||
(portablePdbStream.Length, contentId, portablePdbStream, algorithmName, contentHash)
|
||||
|
||||
let compressPortablePdbStream (uncompressedLength: int64) (contentId: BlobContentId) (stream: MemoryStream) =
|
||||
let compressedStream = new MemoryStream()
|
||||
|
@ -507,17 +556,17 @@ let compressPortablePdbStream (uncompressedLength: int64) (contentId: BlobConten
|
|||
stream.WriteTo compressionStream
|
||||
(uncompressedLength, contentId, compressedStream)
|
||||
|
||||
let writePortablePdbInfo (contentId: BlobContentId) (stream: MemoryStream) showTimes fpdb pathMap cvChunk =
|
||||
let writePortablePdbInfo (contentId: BlobContentId) (stream: MemoryStream) showTimes fpdb pathMap cvChunk deterministicPdbChunk checksumPdbChunk algName checksum embeddedPdb deterministicPdb =
|
||||
try FileSystem.FileDelete fpdb with _ -> ()
|
||||
use pdbFile = new FileStream(fpdb, FileMode.Create, FileAccess.ReadWrite)
|
||||
stream.WriteTo pdbFile
|
||||
reportTime showTimes "PDB: Closed"
|
||||
pdbGetDebugInfo (contentId.Guid.ToByteArray()) (int32 (contentId.Stamp)) (PathMap.apply pathMap fpdb) cvChunk None 0L None
|
||||
pdbGetDebugInfo (contentId.Guid.ToByteArray()) (int32 (contentId.Stamp)) (PathMap.apply pathMap fpdb) cvChunk None deterministicPdbChunk checksumPdbChunk algName checksum 0L None embeddedPdb deterministicPdb
|
||||
|
||||
let embedPortablePdbInfo (uncompressedLength: int64) (contentId: BlobContentId) (stream: MemoryStream) showTimes fpdb cvChunk pdbChunk =
|
||||
let embedPortablePdbInfo (uncompressedLength: int64) (contentId: BlobContentId) (stream: MemoryStream) showTimes fpdb cvChunk pdbChunk deterministicPdbChunk checksumPdbChunk algName checksum embeddedPdb deterministicPdb =
|
||||
reportTime showTimes "PDB: Closed"
|
||||
let fn = Path.GetFileName fpdb
|
||||
pdbGetDebugInfo (contentId.Guid.ToByteArray()) (int32 (contentId.Stamp)) fn cvChunk (Some pdbChunk) uncompressedLength (Some stream)
|
||||
pdbGetDebugInfo (contentId.Guid.ToByteArray()) (int32 (contentId.Stamp)) fn cvChunk (Some pdbChunk) deterministicPdbChunk checksumPdbChunk algName checksum uncompressedLength (Some stream) embeddedPdb deterministicPdb
|
||||
|
||||
#if !FX_NO_PDB_WRITER
|
||||
//---------------------------------------------------------------------
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
module internal FSharp.Compiler.AbstractIL.ILPdbWriter
|
||||
|
||||
open Internal.Utilities
|
||||
open FSharp.Compiler.AbstractIL.IL
|
||||
open FSharp.Compiler.AbstractIL.IL
|
||||
open FSharp.Compiler.ErrorLogger
|
||||
open FSharp.Compiler.Range
|
||||
open System.Collections.Generic
|
||||
|
@ -83,10 +83,14 @@ type idd =
|
|||
iddData: byte[];
|
||||
iddChunk: BinaryChunk }
|
||||
|
||||
val generatePortablePdb : embedAllSource:bool -> embedSourceList:string list -> sourceLink: string -> showTimes:bool -> info:PdbData -> isDeterministic:bool -> pathMap:PathMap -> (int64 * BlobContentId * MemoryStream)
|
||||
type HashAlgorithm =
|
||||
| Sha1
|
||||
| Sha256
|
||||
|
||||
val generatePortablePdb : embedAllSource: bool -> embedSourceList: string list -> sourceLink: string -> checksumAlgorithm: HashAlgorithm -> showTimes: bool -> info: PdbData -> pathMap:PathMap -> (int64 * BlobContentId * MemoryStream * string * byte[])
|
||||
val compressPortablePdbStream : uncompressedLength:int64 -> contentId:BlobContentId -> stream:MemoryStream -> (int64 * BlobContentId * MemoryStream)
|
||||
val embedPortablePdbInfo : uncompressedLength:int64 -> contentId:BlobContentId -> stream:MemoryStream -> showTimes:bool -> fpdb:string -> cvChunk:BinaryChunk -> pdbChunk:BinaryChunk -> idd[]
|
||||
val writePortablePdbInfo : contentId:BlobContentId -> stream:MemoryStream -> showTimes:bool -> fpdb:string -> pathMap:PathMap -> cvChunk:BinaryChunk -> idd[]
|
||||
val embedPortablePdbInfo: uncompressedLength: int64 -> contentId: BlobContentId -> stream: MemoryStream -> showTimes: bool -> fpdb: string -> cvChunk: BinaryChunk -> pdbChunk: BinaryChunk -> deterministicPdbChunk: BinaryChunk -> checksumPdbChunk: BinaryChunk -> algorithmName: string -> checksum: byte[] -> embeddedPDB: bool -> deterministic: bool -> idd[]
|
||||
val writePortablePdbInfo: contentId: BlobContentId -> stream: MemoryStream -> showTimes: bool -> fpdb: string -> pathMap: PathMap -> cvChunk: BinaryChunk -> deterministicPdbChunk: BinaryChunk -> checksumPdbChunk: BinaryChunk -> algorithmName: string -> checksum: byte[] -> embeddedPDB: bool -> deterministic: bool -> idd[]
|
||||
|
||||
#if !FX_NO_PDB_WRITER
|
||||
val writePdbInfo : showTimes:bool -> f:string -> fpdb:string -> info:PdbData -> cvChunk:BinaryChunk -> idd[]
|
||||
|
|
|
@ -1,22 +1,50 @@
|
|||
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
|
||||
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
|
||||
|
||||
open System
|
||||
open System.Diagnostics
|
||||
open System.IO
|
||||
open System.Reflection
|
||||
open System.Reflection.PortableExecutable
|
||||
open System.Text.RegularExpressions
|
||||
|
||||
module AssemblyVersionCheck =
|
||||
module AssemblyCheck =
|
||||
|
||||
let private versionZero = Version(0, 0, 0, 0)
|
||||
let private versionOne = Version(1, 0, 0, 0)
|
||||
let private commitHashPattern = new Regex(@"Commit Hash: (<developer build>)|([0-9a-fA-F]{40})", RegexOptions.Compiled)
|
||||
let private devVersionPattern = new Regex(@"-(ci|dev)", RegexOptions.Compiled)
|
||||
|
||||
let verifyAssemblyVersions (binariesPath:string) =
|
||||
let verifyEmbeddedPdb (filename:string) =
|
||||
use fileStream = File.OpenRead(filename)
|
||||
let reader = new PEReader(fileStream)
|
||||
let mutable hasEmbeddedPdb = false
|
||||
|
||||
try
|
||||
for entry in reader.ReadDebugDirectory() do
|
||||
match entry.Type with
|
||||
| DebugDirectoryEntryType.CodeView ->
|
||||
let _ = reader.ReadCodeViewDebugDirectoryData(entry)
|
||||
()
|
||||
|
||||
| DebugDirectoryEntryType.EmbeddedPortablePdb ->
|
||||
let _ = reader.ReadEmbeddedPortablePdbDebugDirectoryData(entry)
|
||||
hasEmbeddedPdb <- true
|
||||
()
|
||||
|
||||
| DebugDirectoryEntryType.PdbChecksum ->
|
||||
let _ = reader.ReadPdbChecksumDebugDirectoryData(entry)
|
||||
()
|
||||
|
||||
| _ -> ()
|
||||
with | e -> printfn "Error validating assembly %s\nMessage: %s" filename (e.ToString())
|
||||
hasEmbeddedPdb
|
||||
|
||||
let verifyAssemblies (binariesPath:string) =
|
||||
|
||||
let excludedAssemblies =
|
||||
[ "FSharp.Data.TypeProviders.dll" ]
|
||||
|> Set.ofList
|
||||
|
||||
let fsharpAssemblies =
|
||||
[ "FSharp*.dll"
|
||||
"fsc.exe"
|
||||
|
@ -28,12 +56,17 @@ module AssemblyVersionCheck =
|
|||
|> List.ofSeq
|
||||
|> List.filter (fun p -> (Set.contains (Path.GetFileName(p)) excludedAssemblies) |> not)
|
||||
|
||||
let fsharpExecutingWithEmbeddedPdbs =
|
||||
fsharpAssemblies
|
||||
|> List.filter (fun p -> not (p.Contains(@"\Proto\") || p.Contains(@"\Bootstrap\") || p.Contains(@".resources.") || p.Contains(@"\FSharpSdk\") || p.Contains(@"\tmp\") || p.Contains(@"\obj\")))
|
||||
|
||||
// verify that all assemblies have a version number other than 0.0.0.0 or 1.0.0.0
|
||||
let failedVersionCheck =
|
||||
fsharpAssemblies
|
||||
|> List.filter (fun a ->
|
||||
let assemblyVersion = AssemblyName.GetAssemblyName(a).Version
|
||||
assemblyVersion = versionZero || assemblyVersion = versionOne)
|
||||
|
||||
if failedVersionCheck.Length > 0 then
|
||||
printfn "The following assemblies had a version of %A or %A" versionZero versionOne
|
||||
printfn "%s\r\n" <| String.Join("\r\n", failedVersionCheck)
|
||||
|
@ -43,27 +76,36 @@ module AssemblyVersionCheck =
|
|||
// verify that all assemblies have a commit hash
|
||||
let failedCommitHash =
|
||||
fsharpAssemblies
|
||||
|> List.filter (fun p -> not (p.Contains(@"\FSharpSdk\")))
|
||||
|> List.filter (fun a ->
|
||||
let fileProductVersion = FileVersionInfo.GetVersionInfo(a).ProductVersion
|
||||
not (commitHashPattern.IsMatch(fileProductVersion) || devVersionPattern.IsMatch(fileProductVersion)))
|
||||
|
||||
if failedCommitHash.Length > 0 then
|
||||
printfn "The following assemblies don't have a commit hash set"
|
||||
printfn "%s\r\n" <| String.Join("\r\n", failedCommitHash)
|
||||
else
|
||||
printfn "All shipping assemblies had an appropriate commit hash."
|
||||
|
||||
// return code is the number of failures
|
||||
failedVersionCheck.Length + failedCommitHash.Length
|
||||
// verify that all assemblies have an embedded pdb
|
||||
let failedVerifyEmbeddedPdb =
|
||||
fsharpExecutingWithEmbeddedPdbs
|
||||
|> List.filter (fun a -> not (verifyEmbeddedPdb a))
|
||||
|
||||
if failedVerifyEmbeddedPdb.Length > 0 then
|
||||
printfn "The following assemblies don't have an embedded pdb"
|
||||
printfn "%s\r\n" <| String.Join("\r\n", failedVerifyEmbeddedPdb)
|
||||
else
|
||||
printfn "All shipping assemblies had an embedded PDB."
|
||||
|
||||
// return code is the number of failures
|
||||
failedVersionCheck.Length + failedCommitHash.Length + failedVerifyEmbeddedPdb.Length
|
||||
|
||||
|
||||
[<EntryPoint>]
|
||||
let main (argv:string array) =
|
||||
if argv.Length <> 1 then
|
||||
printfn "Usage: fsi.exe AssemblyVersionCheck.fsx -- path/to/binaries"
|
||||
printfn "Usage: dotnet AssemblyCheck.dll -- path/to/binaries"
|
||||
1
|
||||
else
|
||||
AssemblyVersionCheck.verifyAssemblyVersions argv.[0]
|
||||
|
||||
Environment.GetCommandLineArgs()
|
||||
|> Seq.skipWhile ((<>) "--")
|
||||
|> Seq.skip 1
|
||||
|> Array.ofSeq
|
||||
|> main
|
||||
AssemblyCheck.verifyAssemblies argv.[0]
|
|
@ -0,0 +1,17 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
<DisableImplicitFSharpCoreReference>true</DisableImplicitFSharpCoreReference>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="AssemblyCheck.fs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="$(MSBuildThisFileDirectory)..\..\fsharp\FSharp.Core\FSharp.Core.fsproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -8,6 +8,7 @@
|
|||
<ItemGroup>
|
||||
<Projects Include="fslex\fslex.fsproj" />
|
||||
<Projects Include="fsyacc\fsyacc.fsproj" />
|
||||
<Projects Include="AssemblyCheck\AssemblyCheck.fsproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="Build">
|
||||
|
|
|
@ -17,6 +17,7 @@ open Internal.Utilities.Text
|
|||
open FSharp.Compiler.AbstractIL
|
||||
open FSharp.Compiler.AbstractIL.IL
|
||||
open FSharp.Compiler.AbstractIL.ILBinaryReader
|
||||
open FSharp.Compiler.AbstractIL.ILPdbWriter
|
||||
open FSharp.Compiler.AbstractIL.Internal
|
||||
open FSharp.Compiler.AbstractIL.Internal.Library
|
||||
open FSharp.Compiler.AbstractIL.Extensions.ILX
|
||||
|
@ -2101,6 +2102,7 @@ type TcConfigBuilder =
|
|||
mutable maxErrors: int
|
||||
mutable abortOnError: bool (* intended for fsi scripts that should exit on first error *)
|
||||
mutable baseAddress: int32 option
|
||||
mutable checksumAlgorithm: HashAlgorithm
|
||||
#if DEBUG
|
||||
mutable showOptimizationData: bool
|
||||
#endif
|
||||
|
@ -2234,6 +2236,7 @@ type TcConfigBuilder =
|
|||
maxErrors = 100
|
||||
abortOnError = false
|
||||
baseAddress = None
|
||||
checksumAlgorithm = HashAlgorithm.Sha256
|
||||
|
||||
delaysign = false
|
||||
publicsign = false
|
||||
|
@ -2744,6 +2747,7 @@ type TcConfig private (data: TcConfigBuilder, validate: bool) =
|
|||
member x.flatErrors = data.flatErrors
|
||||
member x.maxErrors = data.maxErrors
|
||||
member x.baseAddress = data.baseAddress
|
||||
member x.checksumAlgorithm = data.checksumAlgorithm
|
||||
#if DEBUG
|
||||
member x.showOptimizationData = data.showOptimizationData
|
||||
#endif
|
||||
|
|
|
@ -10,6 +10,7 @@ open Internal.Utilities
|
|||
open FSharp.Compiler.AbstractIL
|
||||
open FSharp.Compiler.AbstractIL.IL
|
||||
open FSharp.Compiler.AbstractIL.ILBinaryReader
|
||||
open FSharp.Compiler.AbstractIL.ILPdbWriter
|
||||
open FSharp.Compiler.AbstractIL.Internal.Library
|
||||
open FSharp.Compiler
|
||||
open FSharp.Compiler.TypeChecker
|
||||
|
@ -338,6 +339,7 @@ type TcConfigBuilder =
|
|||
mutable maxErrors: int
|
||||
mutable abortOnError: bool
|
||||
mutable baseAddress: int32 option
|
||||
mutable checksumAlgorithm: HashAlgorithm
|
||||
#if DEBUG
|
||||
mutable showOptimizationData: bool
|
||||
#endif
|
||||
|
@ -500,6 +502,7 @@ type TcConfig =
|
|||
|
||||
member maxErrors: int
|
||||
member baseAddress: int32 option
|
||||
member checksumAlgorithm: HashAlgorithm
|
||||
#if DEBUG
|
||||
member showOptimizationData: bool
|
||||
#endif
|
||||
|
|
|
@ -9,6 +9,7 @@ open System
|
|||
open FSharp.Compiler
|
||||
open FSharp.Compiler.AbstractIL
|
||||
open FSharp.Compiler.AbstractIL.IL
|
||||
open FSharp.Compiler.AbstractIL.ILPdbWriter
|
||||
open FSharp.Compiler.AbstractIL.Internal.Library
|
||||
open FSharp.Compiler.AbstractIL.Extensions.ILX
|
||||
open FSharp.Compiler.AbstractIL.Diagnostics
|
||||
|
@ -523,6 +524,7 @@ let tagFullPDBOnlyPortable = "{full|pdbonly|portable|embedded}"
|
|||
let tagWarnList = "<warn;...>"
|
||||
let tagSymbolList = "<symbol;...>"
|
||||
let tagAddress = "<address>"
|
||||
let tagAlgorithm = "{SHA1|SHA256}"
|
||||
let tagInt = "<n>"
|
||||
let tagPathMap = "<path=sourcePath;...>"
|
||||
let tagNone = ""
|
||||
|
@ -948,6 +950,16 @@ let advancedFlagsFsc tcConfigB =
|
|||
OptionString (fun s -> tcConfigB.baseAddress <- Some(int32 s)), None,
|
||||
Some (FSComp.SR.optsBaseaddress()))
|
||||
|
||||
yield CompilerOption
|
||||
("checksumalgorithm", tagAlgorithm,
|
||||
OptionString (fun s ->
|
||||
tcConfigB.checksumAlgorithm <-
|
||||
match s.ToUpperInvariant() with
|
||||
| "SHA1" -> HashAlgorithm.Sha1
|
||||
| "SHA256" -> HashAlgorithm.Sha256
|
||||
| _ -> error(Error(FSComp.SR.optsUnknownChecksumAlgorithm s, rangeCmdArgs))), None,
|
||||
Some (FSComp.SR.optsChecksumAlgorithm()))
|
||||
|
||||
yield noFrameworkFlag true tcConfigB
|
||||
|
||||
yield CompilerOption
|
||||
|
|
|
@ -880,6 +880,7 @@ optsUtf8output,"Output messages in UTF-8 encoding"
|
|||
optsFullpaths,"Output messages with fully qualified paths"
|
||||
optsLib,"Specify a directory for the include path which is used to resolve source files and assemblies (Short form: -I)"
|
||||
optsBaseaddress,"Base address for the library to be built"
|
||||
optsChecksumAlgorithm,"Specify algorithm for calculating source file checksum stored in PDB. Supported values are: SHA1 or SHA256 (default)"
|
||||
optsNoframework,"Do not reference the default CLI assemblies by default"
|
||||
optsStandalone,"Statically link the F# library and all referenced DLLs that depend on it into the assembly being generated"
|
||||
optsStaticlink,"Statically link the given assembly and all referenced DLLs that depend on this assembly. Use an assembly name e.g. mylib, not a DLL name."
|
||||
|
@ -902,6 +903,7 @@ optsHelpBannerLanguage,"- LANGUAGE -"
|
|||
optsHelpBannerErrsAndWarns,"- ERRORS AND WARNINGS -"
|
||||
1063,optsUnknownArgumentToTheTestSwitch,"Unknown --test argument: '%s'"
|
||||
1064,optsUnknownPlatform,"Unrecognized platform '%s', valid values are 'x86', 'x64', 'Itanium', 'anycpu32bitpreferred', and 'anycpu'"
|
||||
1065,optsUnknownChecksumAlgorithm,"Algorithm '%s' is not supported"
|
||||
optsInternalNoDescription,"The command-line option '%s' is for test purposes only"
|
||||
optsDCLONoDescription,"The command-line option '%s' has been deprecated"
|
||||
optsDCLODeprecatedSuggestAlternative,"The command-line option '%s' has been deprecated. Use '%s' instead."
|
||||
|
|
|
@ -24,6 +24,7 @@ type public Fsc () as this =
|
|||
let mutable baseAddress : string = null
|
||||
let mutable capturedArguments : string list = [] // list of individual args, to pass to HostObject Compile()
|
||||
let mutable capturedFilenames : string list = [] // list of individual source filenames, to pass to HostObject Compile()
|
||||
let mutable checksumAlgorithm: string = null
|
||||
let mutable codePage : string = null
|
||||
let mutable commandLineArgs : ITaskItem list = []
|
||||
let mutable debugSymbols = false
|
||||
|
@ -135,7 +136,7 @@ type public Fsc () as this =
|
|||
builder.AppendSwitch("--tailcalls-")
|
||||
// PdbFile
|
||||
builder.AppendSwitchIfNotNull("--pdb:", pdbFile)
|
||||
// Platform
|
||||
// Platform
|
||||
builder.AppendSwitchIfNotNull("--platform:",
|
||||
let ToUpperInvariant (s:string) = if s = null then null else s.ToUpperInvariant()
|
||||
match ToUpperInvariant(platform), prefer32bit, ToUpperInvariant(targetType) with
|
||||
|
@ -145,6 +146,13 @@ type public Fsc () as this =
|
|||
| "X86", _, _ -> "x86"
|
||||
| "X64", _, _ -> "x64"
|
||||
| _ -> null)
|
||||
// checksumAlgorithm
|
||||
builder.AppendSwitchIfNotNull("--checksumalgorithm:",
|
||||
let ToUpperInvariant (s:string) = if s = null then null else s.ToUpperInvariant()
|
||||
match ToUpperInvariant(checksumAlgorithm) with
|
||||
| "SHA1" -> "Sha1"
|
||||
| "SHA256" -> "Sha256"
|
||||
| _ -> null)
|
||||
// Resources
|
||||
if resources <> null then
|
||||
for item in resources do
|
||||
|
@ -258,6 +266,11 @@ type public Fsc () as this =
|
|||
with get() = baseAddress
|
||||
and set(s) = baseAddress <- s
|
||||
|
||||
// --checksumalgorithm
|
||||
member fsc.ChecksumAlgorithm
|
||||
with get() = checksumAlgorithm
|
||||
and set(s) = checksumAlgorithm <- s
|
||||
|
||||
// --codepage <int>: Specify the codepage to use when opening source files
|
||||
member fsc.CodePage
|
||||
with get() = codePage
|
||||
|
|
|
@ -283,6 +283,7 @@ this file.
|
|||
<!-- NOTE: ManifestResourceWithNoCulture and ManifestNonResxWithNoCultureOnDisk are generated by Mono targets files -->
|
||||
<Fsc Condition="'%(_CoreCompileResourceInputs.WithCulture)' != 'true'"
|
||||
BaseAddress="$(BaseAddress)"
|
||||
ChecksumAlgorithm="$(PdbChecksumAlgorithm)"
|
||||
CodePage="$(CodePage)"
|
||||
DebugSymbols="$(DebugSymbols)"
|
||||
DebugType="$(DebugType)"
|
||||
|
|
|
@ -251,15 +251,15 @@
|
|||
<Compile Include="..\..\absil\ilread.fs">
|
||||
<Link>AbsIL\ilread.fs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\absil\ilwrite.fsi">
|
||||
<Link>AbsIL\ilwrite.fsi</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\absil\ilwritepdb.fsi">
|
||||
<Link>AbsIL\ilwritepdb.fsi</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\absil\ilwritepdb.fs">
|
||||
<Link>AbsIL\ilwritepdb.fs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\absil\ilwrite.fsi">
|
||||
<Link>AbsIL\ilwrite.fsi</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\absil\ilwrite.fs">
|
||||
<Link>AbsIL\ilwrite.fs</Link>
|
||||
</Compile>
|
||||
|
|
|
@ -49,15 +49,7 @@
|
|||
<file src="FSharp.Compiler.Private\$Configuration$\netstandard2.0\FSharp.Compiler.Private.dll" target="lib\netcoreapp2.1" />
|
||||
<file src="FSharp.Build\$Configuration$\netcoreapp2.1\FSharp.Build.dll" target="lib\netcoreapp2.1" />
|
||||
<file src="FSharp.Compiler.Interactive.Settings\$Configuration$\netstandard2.0\FSharp.Compiler.Interactive.Settings.dll"
|
||||
target="lib\netcoreapp2.1" />
|
||||
<!-- symbols -->
|
||||
<file src="fsc\$Configuration$\netcoreapp2.1\fsc.pdb" target="lib\netcoreapp2.1" />
|
||||
<file src="fsi\$Configuration$\netcoreapp2.1\fsi.pdb" target="lib\netcoreapp2.1" />
|
||||
<file src="FSharp.Core\$Configuration$\netstandard2.0\FSharp.Core.pdb" target="lib\netcoreapp2.1" />
|
||||
<file src="FSharp.Compiler.Private\$Configuration$\netstandard2.0\FSharp.Compiler.Private.pdb" target="lib\netcoreapp2.1" />
|
||||
<file src="FSharp.Build\$Configuration$\netcoreapp2.1\FSharp.Build.pdb" target="lib\netcoreapp2.1" />
|
||||
<file src="FSharp.Compiler.Interactive.Settings\$Configuration$\netstandard2.0\FSharp.Compiler.Interactive.Settings.pdb"
|
||||
target="lib\netcoreapp2.1" />
|
||||
target="lib\netcoreapp2.1" />
|
||||
<!-- additional files -->
|
||||
<file src="fsc\$Configuration$\netcoreapp2.1\default.win32manifest" target="contentFiles\any\any" />
|
||||
<file src="FSharp.Build\$Configuration$\netcoreapp2.1\Microsoft.FSharp.Targets" target="contentFiles\any\any" />
|
||||
|
@ -69,9 +61,9 @@
|
|||
<!-- resources -->
|
||||
<file src="FSharp.Core\$Configuration$\netstandard2.0\**\FSharp.Core.resources.dll" target="lib\netcoreapp2.1" />
|
||||
<file src="FSharp.Compiler.Private\$Configuration$\netstandard2.0\**\FSharp.Compiler.Private.resources.dll"
|
||||
target="lib\netcoreapp2.1" />
|
||||
target="lib\netcoreapp2.1" />
|
||||
<file src="FSharp.Compiler.Interactive.Settings\$Configuration$\netstandard2.0\**\FSharp.Compiler.Interactive.Settings.resources.dll"
|
||||
target="lib\netcoreapp2.1" />
|
||||
target="lib\netcoreapp2.1" />
|
||||
<file src="FSharp.Build\$Configuration$\netcoreapp2.1\**\FSharp.Build.resources.dll" target="lib\netcoreapp2.1" />
|
||||
</files>
|
||||
</package>
|
||||
|
|
|
@ -2138,6 +2138,7 @@ let main4 dynamicAssemblyCreator (Args (ctok, tcConfig, tcImports: TcImports, t
|
|||
embedAllSource = tcConfig.embedAllSource
|
||||
embedSourceList = tcConfig.embedSourceList
|
||||
sourceLink = tcConfig.sourceLink
|
||||
checksumAlgorithm = tcConfig.checksumAlgorithm
|
||||
signer = GetStrongNameSigner signingInfo
|
||||
dumpDebugInfo = tcConfig.dumpDebugInfo
|
||||
pathMap = tcConfig.pathMap },
|
||||
|
|
|
@ -27,6 +27,16 @@
|
|||
<target state="new">Unexpected symbol '.' in member definition. Expected 'with', '=' or other token.</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="optsChecksumAlgorithm">
|
||||
<source>Specify algorithm for calculating source file checksum stored in PDB. Supported values are: SHA1 or SHA256 (default)</source>
|
||||
<target state="new">Specify algorithm for calculating source file checksum stored in PDB. Supported values are: SHA1 or SHA256 (default)</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="optsUnknownChecksumAlgorithm">
|
||||
<source>Algorithm '{0}' is not supported</source>
|
||||
<target state="new">Algorithm '{0}' is not supported</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="undefinedNameNamespace">
|
||||
<source>The namespace '{0}' is not defined.</source>
|
||||
<target state="translated">Není definovaný obor názvů {0}.</target>
|
||||
|
|
|
@ -27,6 +27,16 @@
|
|||
<target state="new">Unexpected symbol '.' in member definition. Expected 'with', '=' or other token.</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="optsChecksumAlgorithm">
|
||||
<source>Specify algorithm for calculating source file checksum stored in PDB. Supported values are: SHA1 or SHA256 (default)</source>
|
||||
<target state="new">Specify algorithm for calculating source file checksum stored in PDB. Supported values are: SHA1 or SHA256 (default)</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="optsUnknownChecksumAlgorithm">
|
||||
<source>Algorithm '{0}' is not supported</source>
|
||||
<target state="new">Algorithm '{0}' is not supported</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="undefinedNameNamespace">
|
||||
<source>The namespace '{0}' is not defined.</source>
|
||||
<target state="translated">Der Namespace "{0}" ist nicht definiert.</target>
|
||||
|
|
|
@ -27,6 +27,16 @@
|
|||
<target state="new">Unexpected symbol '.' in member definition. Expected 'with', '=' or other token.</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="optsChecksumAlgorithm">
|
||||
<source>Specify algorithm for calculating source file checksum stored in PDB. Supported values are: SHA1 or SHA256 (default)</source>
|
||||
<target state="new">Specify algorithm for calculating source file checksum stored in PDB. Supported values are: SHA1 or SHA256 (default)</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="optsUnknownChecksumAlgorithm">
|
||||
<source>Algorithm '{0}' is not supported</source>
|
||||
<target state="new">Algorithm '{0}' is not supported</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="undefinedNameNamespace">
|
||||
<source>The namespace '{0}' is not defined.</source>
|
||||
<target state="translated">El espacio de nombres "{0}" no está definido.</target>
|
||||
|
|
|
@ -27,6 +27,16 @@
|
|||
<target state="new">Unexpected symbol '.' in member definition. Expected 'with', '=' or other token.</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="optsChecksumAlgorithm">
|
||||
<source>Specify algorithm for calculating source file checksum stored in PDB. Supported values are: SHA1 or SHA256 (default)</source>
|
||||
<target state="new">Specify algorithm for calculating source file checksum stored in PDB. Supported values are: SHA1 or SHA256 (default)</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="optsUnknownChecksumAlgorithm">
|
||||
<source>Algorithm '{0}' is not supported</source>
|
||||
<target state="new">Algorithm '{0}' is not supported</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="undefinedNameNamespace">
|
||||
<source>The namespace '{0}' is not defined.</source>
|
||||
<target state="translated">L'espace de noms '{0}' n'est pas défini.</target>
|
||||
|
|
|
@ -27,6 +27,16 @@
|
|||
<target state="new">Unexpected symbol '.' in member definition. Expected 'with', '=' or other token.</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="optsChecksumAlgorithm">
|
||||
<source>Specify algorithm for calculating source file checksum stored in PDB. Supported values are: SHA1 or SHA256 (default)</source>
|
||||
<target state="new">Specify algorithm for calculating source file checksum stored in PDB. Supported values are: SHA1 or SHA256 (default)</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="optsUnknownChecksumAlgorithm">
|
||||
<source>Algorithm '{0}' is not supported</source>
|
||||
<target state="new">Algorithm '{0}' is not supported</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="undefinedNameNamespace">
|
||||
<source>The namespace '{0}' is not defined.</source>
|
||||
<target state="translated">Lo spazio dei nomi '{0}' non è definito.</target>
|
||||
|
|
|
@ -27,6 +27,16 @@
|
|||
<target state="new">Unexpected symbol '.' in member definition. Expected 'with', '=' or other token.</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="optsChecksumAlgorithm">
|
||||
<source>Specify algorithm for calculating source file checksum stored in PDB. Supported values are: SHA1 or SHA256 (default)</source>
|
||||
<target state="new">Specify algorithm for calculating source file checksum stored in PDB. Supported values are: SHA1 or SHA256 (default)</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="optsUnknownChecksumAlgorithm">
|
||||
<source>Algorithm '{0}' is not supported</source>
|
||||
<target state="new">Algorithm '{0}' is not supported</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="undefinedNameNamespace">
|
||||
<source>The namespace '{0}' is not defined.</source>
|
||||
<target state="translated">名前空間 '{0}' が定義されていません。</target>
|
||||
|
|
|
@ -27,6 +27,16 @@
|
|||
<target state="new">Unexpected symbol '.' in member definition. Expected 'with', '=' or other token.</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="optsChecksumAlgorithm">
|
||||
<source>Specify algorithm for calculating source file checksum stored in PDB. Supported values are: SHA1 or SHA256 (default)</source>
|
||||
<target state="new">Specify algorithm for calculating source file checksum stored in PDB. Supported values are: SHA1 or SHA256 (default)</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="optsUnknownChecksumAlgorithm">
|
||||
<source>Algorithm '{0}' is not supported</source>
|
||||
<target state="new">Algorithm '{0}' is not supported</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="undefinedNameNamespace">
|
||||
<source>The namespace '{0}' is not defined.</source>
|
||||
<target state="translated">'{0}' 네임스페이스가 정의되지 않았습니다.</target>
|
||||
|
|
|
@ -27,6 +27,16 @@
|
|||
<target state="new">Unexpected symbol '.' in member definition. Expected 'with', '=' or other token.</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="optsChecksumAlgorithm">
|
||||
<source>Specify algorithm for calculating source file checksum stored in PDB. Supported values are: SHA1 or SHA256 (default)</source>
|
||||
<target state="new">Specify algorithm for calculating source file checksum stored in PDB. Supported values are: SHA1 or SHA256 (default)</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="optsUnknownChecksumAlgorithm">
|
||||
<source>Algorithm '{0}' is not supported</source>
|
||||
<target state="new">Algorithm '{0}' is not supported</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="undefinedNameNamespace">
|
||||
<source>The namespace '{0}' is not defined.</source>
|
||||
<target state="translated">Nie zdefiniowano przestrzeni nazw „{0}”.</target>
|
||||
|
|
|
@ -27,6 +27,16 @@
|
|||
<target state="new">Unexpected symbol '.' in member definition. Expected 'with', '=' or other token.</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="optsChecksumAlgorithm">
|
||||
<source>Specify algorithm for calculating source file checksum stored in PDB. Supported values are: SHA1 or SHA256 (default)</source>
|
||||
<target state="new">Specify algorithm for calculating source file checksum stored in PDB. Supported values are: SHA1 or SHA256 (default)</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="optsUnknownChecksumAlgorithm">
|
||||
<source>Algorithm '{0}' is not supported</source>
|
||||
<target state="new">Algorithm '{0}' is not supported</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="undefinedNameNamespace">
|
||||
<source>The namespace '{0}' is not defined.</source>
|
||||
<target state="translated">O namespace '{0}' não está definido.</target>
|
||||
|
|
|
@ -27,6 +27,16 @@
|
|||
<target state="new">Unexpected symbol '.' in member definition. Expected 'with', '=' or other token.</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="optsChecksumAlgorithm">
|
||||
<source>Specify algorithm for calculating source file checksum stored in PDB. Supported values are: SHA1 or SHA256 (default)</source>
|
||||
<target state="new">Specify algorithm for calculating source file checksum stored in PDB. Supported values are: SHA1 or SHA256 (default)</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="optsUnknownChecksumAlgorithm">
|
||||
<source>Algorithm '{0}' is not supported</source>
|
||||
<target state="new">Algorithm '{0}' is not supported</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="undefinedNameNamespace">
|
||||
<source>The namespace '{0}' is not defined.</source>
|
||||
<target state="translated">Пространство имен "{0}" не определено.</target>
|
||||
|
|
|
@ -27,6 +27,16 @@
|
|||
<target state="new">Unexpected symbol '.' in member definition. Expected 'with', '=' or other token.</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="optsChecksumAlgorithm">
|
||||
<source>Specify algorithm for calculating source file checksum stored in PDB. Supported values are: SHA1 or SHA256 (default)</source>
|
||||
<target state="new">Specify algorithm for calculating source file checksum stored in PDB. Supported values are: SHA1 or SHA256 (default)</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="optsUnknownChecksumAlgorithm">
|
||||
<source>Algorithm '{0}' is not supported</source>
|
||||
<target state="new">Algorithm '{0}' is not supported</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="undefinedNameNamespace">
|
||||
<source>The namespace '{0}' is not defined.</source>
|
||||
<target state="translated">'{0}' ad alanı tanımlı değil.</target>
|
||||
|
|
|
@ -27,6 +27,16 @@
|
|||
<target state="new">Unexpected symbol '.' in member definition. Expected 'with', '=' or other token.</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="optsChecksumAlgorithm">
|
||||
<source>Specify algorithm for calculating source file checksum stored in PDB. Supported values are: SHA1 or SHA256 (default)</source>
|
||||
<target state="new">Specify algorithm for calculating source file checksum stored in PDB. Supported values are: SHA1 or SHA256 (default)</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="optsUnknownChecksumAlgorithm">
|
||||
<source>Algorithm '{0}' is not supported</source>
|
||||
<target state="new">Algorithm '{0}' is not supported</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="undefinedNameNamespace">
|
||||
<source>The namespace '{0}' is not defined.</source>
|
||||
<target state="translated">未定义命名空间“{0}”。</target>
|
||||
|
|
|
@ -27,6 +27,16 @@
|
|||
<target state="new">Unexpected symbol '.' in member definition. Expected 'with', '=' or other token.</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="optsChecksumAlgorithm">
|
||||
<source>Specify algorithm for calculating source file checksum stored in PDB. Supported values are: SHA1 or SHA256 (default)</source>
|
||||
<target state="new">Specify algorithm for calculating source file checksum stored in PDB. Supported values are: SHA1 or SHA256 (default)</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="optsUnknownChecksumAlgorithm">
|
||||
<source>Algorithm '{0}' is not supported</source>
|
||||
<target state="new">Algorithm '{0}' is not supported</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="undefinedNameNamespace">
|
||||
<source>The namespace '{0}' is not defined.</source>
|
||||
<target state="translated">未定義命名空間 '{0}'。</target>
|
||||
|
|
|
@ -12495,7 +12495,7 @@ namespace ProviderImplementation.ProvidedTypes
|
|||
let pdbOpt =
|
||||
match portablePDB with
|
||||
| true ->
|
||||
let (uncompressedLength, contentId, stream) as pdbStream = generatePortablePdb embedAllSource embedSourceList sourceLink showTimes pdbData deterministic
|
||||
let (uncompressedLength, contentId, stream) as pdbStream = generatePortablePdb embedAllSource embedSourceList sourceLink showTimes pdbData
|
||||
if embeddedPDB then Some (compressPortablePdbStream uncompressedLength contentId stream)
|
||||
else Some (pdbStream)
|
||||
| _ -> None
|
||||
|
|
|
@ -13,4 +13,5 @@ Library1.dll
|
|||
|
||||
|
||||
cd.tmp
|
||||
|
||||
*.err
|
||||
*.vserr
|
||||
|
|
|
@ -32,6 +32,76 @@ module CompilerAssert =
|
|||
let checker = FSharpChecker.Create()
|
||||
let private config = TestFramework.initializeSuite ()
|
||||
|
||||
|
||||
// Do a one time dotnet sdk build to compute the proper set of reference assemblies to pass to the compiler
|
||||
#if !NETCOREAPP
|
||||
#else
|
||||
let projectFile = """
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup><Compile Include="Program.fs" /></ItemGroup>
|
||||
|
||||
<Target Name="WriteFrameworkReferences" AfterTargets="AfterBuild">
|
||||
<WriteLinesToFile File="FrameworkReferences.txt" Lines="@(ReferencePath)" Overwrite="true" WriteOnlyWhenDifferent="true" />
|
||||
</Target>
|
||||
|
||||
</Project>"""
|
||||
|
||||
let programFs = """
|
||||
open System
|
||||
|
||||
[<EntryPoint>]
|
||||
let main argv = 0"""
|
||||
|
||||
let getNetCoreAppReferences =
|
||||
let mutable output = ""
|
||||
let mutable errors = ""
|
||||
let mutable cleanUp = true
|
||||
let projectDirectory = Path.Combine(Path.GetTempPath(), "netcoreapp2.1", Path.GetRandomFileName())
|
||||
try
|
||||
try
|
||||
Directory.CreateDirectory(projectDirectory) |> ignore
|
||||
let projectFileName = Path.Combine(projectDirectory, "ProjectFile.fsproj")
|
||||
let programFsFileName = Path.Combine(projectDirectory, "Program.fs")
|
||||
let frameworkReferencesFileName = Path.Combine(projectDirectory, "FrameworkReferences.txt")
|
||||
|
||||
File.WriteAllText(projectFileName, projectFile)
|
||||
File.WriteAllText(programFsFileName, programFs)
|
||||
|
||||
let pInfo = ProcessStartInfo ()
|
||||
|
||||
pInfo.FileName <- config.DotNetExe
|
||||
pInfo.Arguments <- "build"
|
||||
pInfo.WorkingDirectory <- projectDirectory
|
||||
pInfo.RedirectStandardOutput <- true
|
||||
pInfo.RedirectStandardError <- true
|
||||
pInfo.UseShellExecute <- false
|
||||
|
||||
let p = Process.Start(pInfo)
|
||||
p.WaitForExit()
|
||||
|
||||
output <- p.StandardOutput.ReadToEnd ()
|
||||
errors <- p.StandardError.ReadToEnd ()
|
||||
if not (String.IsNullOrWhiteSpace errors) then Assert.Fail errors
|
||||
|
||||
if p.ExitCode <> 0 then Assert.Fail(sprintf "Program exited with exit code %d" p.ExitCode)
|
||||
|
||||
File.ReadLines(frameworkReferencesFileName) |> Seq.toArray
|
||||
with | e ->
|
||||
cleanUp <- false
|
||||
printfn "%s" output
|
||||
printfn "%s" errors
|
||||
raise (new Exception (sprintf "An error occured getting netcoreapp references: %A" e))
|
||||
finally
|
||||
if cleanUp then
|
||||
try Directory.Delete(projectDirectory) with | _ -> ()
|
||||
#endif
|
||||
|
||||
let private defaultProjectOptions =
|
||||
{
|
||||
ProjectFileName = "Z:\\test.fsproj"
|
||||
|
@ -41,14 +111,7 @@ module CompilerAssert =
|
|||
OtherOptions = [|"--preferreduilang:en-US";|]
|
||||
#else
|
||||
OtherOptions =
|
||||
// Hack: Currently a hack to get the runtime assemblies for netcore in order to compile.
|
||||
let assemblies =
|
||||
typeof<obj>.Assembly.Location
|
||||
|> Path.GetDirectoryName
|
||||
|> Directory.EnumerateFiles
|
||||
|> Seq.toArray
|
||||
|> Array.filter (fun x -> x.ToLowerInvariant().Contains("system.") || x.ToLowerInvariant().EndsWith("netstandard.dll"))
|
||||
|> Array.map (fun x -> sprintf "-r:%s" x)
|
||||
let assemblies = getNetCoreAppReferences |> Array.map (fun x -> sprintf "-r:%s" x)
|
||||
Array.append [|"--preferreduilang:en-US"; "--targetprofile:netcore"; "--noframework"|] assemblies
|
||||
#endif
|
||||
ReferencedProjects = [||]
|
||||
|
@ -60,6 +123,7 @@ module CompilerAssert =
|
|||
ExtraProjectInfo = None
|
||||
Stamp = None
|
||||
}
|
||||
|
||||
let private gate = obj ()
|
||||
|
||||
let private compile isExe source f =
|
||||
|
@ -109,11 +173,15 @@ module CompilerAssert =
|
|||
|
||||
Assert.IsEmpty(typeCheckResults.Errors, sprintf "Type Check errors: %A" typeCheckResults.Errors)
|
||||
|
||||
|
||||
|
||||
let TypeCheckWithErrors (source: string) expectedTypeErrors =
|
||||
let TypeCheckWithErrorsAndOptions options (source: string) expectedTypeErrors =
|
||||
lock gate <| fun () ->
|
||||
let parseResults, fileAnswer = checker.ParseAndCheckFileInProject("test.fs", 0, SourceText.ofString source, defaultProjectOptions) |> Async.RunSynchronously
|
||||
let parseResults, fileAnswer =
|
||||
checker.ParseAndCheckFileInProject(
|
||||
"test.fs",
|
||||
0,
|
||||
SourceText.ofString source,
|
||||
{ defaultProjectOptions with OtherOptions = Array.append options defaultProjectOptions.OtherOptions})
|
||||
|> Async.RunSynchronously
|
||||
|
||||
Assert.IsEmpty(parseResults.Errors, sprintf "Parse errors: %A" parseResults.Errors)
|
||||
|
||||
|
@ -136,11 +204,17 @@ module CompilerAssert =
|
|||
Assert.AreEqual(expectedErrorMsg, info.Message, "expectedErrorMsg")
|
||||
)
|
||||
|
||||
let TypeCheckWithErrors (source: string) expectedTypeErrors =
|
||||
TypeCheckWithErrorsAndOptions [||] source expectedTypeErrors
|
||||
|
||||
let TypeCheckSingleErrorWithOptions options (source: string) (expectedServerity: FSharpErrorSeverity) (expectedErrorNumber: int) (expectedErrorRange: int * int * int * int) (expectedErrorMsg: string) =
|
||||
TypeCheckWithErrorsAndOptions options source [| expectedServerity, expectedErrorNumber, expectedErrorRange, expectedErrorMsg |]
|
||||
|
||||
let TypeCheckSingleError (source: string) (expectedServerity: FSharpErrorSeverity) (expectedErrorNumber: int) (expectedErrorRange: int * int * int * int) (expectedErrorMsg: string) =
|
||||
TypeCheckWithErrors (source: string) [| expectedServerity, expectedErrorNumber, expectedErrorRange, expectedErrorMsg |]
|
||||
TypeCheckWithErrors source [| expectedServerity, expectedErrorNumber, expectedErrorRange, expectedErrorMsg |]
|
||||
|
||||
let CompileExe (source: string) =
|
||||
compile true source (fun (errors, _) ->
|
||||
compile true source (fun (errors, _) ->
|
||||
if errors.Length > 0 then
|
||||
Assert.Fail (sprintf "Compile had warnings and/or errors: %A" errors))
|
||||
|
||||
|
@ -215,3 +289,4 @@ module CompilerAssert =
|
|||
||> Seq.iter2 (fun expectedErrorMessage errorMessage ->
|
||||
Assert.AreEqual(expectedErrorMessage, errorMessage)
|
||||
)
|
||||
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
|
||||
|
||||
namespace FSharp.Compiler.UnitTests
|
||||
|
||||
open NUnit.Framework
|
||||
open FSharp.Compiler.SourceCodeServices
|
||||
|
||||
[<TestFixture>]
|
||||
module MemberConstraints =
|
||||
|
||||
[<Test>]
|
||||
let ``we can overload operators on a type and not add all the extra jazz such as inlining and the ^ operator.``() =
|
||||
CompilerAssert.CompileExeAndRun
|
||||
"""
|
||||
type Foo(x : int) =
|
||||
member this.Val = x
|
||||
|
||||
static member (-->) ((src : Foo), (target : Foo)) = new Foo(src.Val + target.Val)
|
||||
static member (-->) ((src : Foo), (target : int)) = new Foo(src.Val + target)
|
||||
|
||||
static member (+) ((src : Foo), (target : Foo)) = new Foo(src.Val + target.Val)
|
||||
static member (+) ((src : Foo), (target : int)) = new Foo(src.Val + target)
|
||||
|
||||
let x = Foo(3) --> 4
|
||||
let y = Foo(3) --> Foo(4)
|
||||
let x2 = Foo(3) + 4
|
||||
let y2 = Foo(3) + Foo(4)
|
||||
|
||||
if x.Val <> 7 then exit 1
|
||||
if y.Val <> 7 then exit 1
|
||||
if x2.Val <> 7 then exit 1
|
||||
if y2.Val <> 7 then exit 1
|
||||
"""
|
||||
|
||||
[<Test>]
|
||||
let ``Invalid member constraint with ErrorRanges``() = // Regression test for FSharp1.0:2262
|
||||
CompilerAssert.TypeCheckSingleErrorWithOptions
|
||||
[| "--test:ErrorRanges" |]
|
||||
"""
|
||||
let inline length (x: ^a) : int = (^a : (member Length : int with get, set) (x, ()))
|
||||
"""
|
||||
FSharpErrorSeverity.Error
|
||||
697
|
||||
(2, 42, 2, 75)
|
||||
"Invalid constraint"
|
|
@ -0,0 +1,109 @@
|
|||
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
|
||||
|
||||
namespace FSharp.Compiler.UnitTests
|
||||
|
||||
open NUnit.Framework
|
||||
open FSharp.Compiler.SourceCodeServices
|
||||
|
||||
[<TestFixture>]
|
||||
module PrimitiveConstraints =
|
||||
|
||||
[<Test>]
|
||||
let ``Test primitive : constraints``() =
|
||||
CompilerAssert.CompileExeAndRun
|
||||
"""
|
||||
#light
|
||||
|
||||
type Foo(x : int) =
|
||||
member this.Value = x
|
||||
override this.ToString() = "Foo"
|
||||
|
||||
type Bar(x : int) =
|
||||
inherit Foo(-1)
|
||||
member this.Value2 = x
|
||||
override this.ToString() = "Bar"
|
||||
|
||||
let test1 (x : Foo) = x.Value
|
||||
let test2 (x : Bar) = (x.Value, x.Value2)
|
||||
|
||||
let f = new Foo(128)
|
||||
let b = new Bar(256)
|
||||
|
||||
if test1 f <> 128 then exit 1
|
||||
if test2 b <> (-1, 256) then exit 1
|
||||
"""
|
||||
|
||||
[<Test>]
|
||||
let ``Test primitive :> constraints``() =
|
||||
CompilerAssert.CompileExeAndRun
|
||||
"""
|
||||
#light
|
||||
type Foo(x : int) =
|
||||
member this.Value = x
|
||||
override this.ToString() = "Foo"
|
||||
|
||||
type Bar(x : int) =
|
||||
inherit Foo(-1)
|
||||
member this.Value2 = x
|
||||
override this.ToString() = "Bar"
|
||||
|
||||
type Ram(x : int) =
|
||||
inherit Foo(10)
|
||||
member this.ValueA = x
|
||||
override this.ToString() = "Ram"
|
||||
|
||||
let test (x : Foo) = (x.Value, x.ToString())
|
||||
|
||||
let f = new Foo(128)
|
||||
let b = new Bar(256)
|
||||
let r = new Ram(314)
|
||||
|
||||
if test f <> (128, "Foo") then exit 1
|
||||
if test b <> (-1, "Bar") then exit 1
|
||||
if test r <> (10, "Ram") then exit 1
|
||||
"""
|
||||
|
||||
[<Test>]
|
||||
let ``Test primitive : null constraint``() =
|
||||
CompilerAssert.CompileExeAndRun
|
||||
"""
|
||||
let inline isNull<'a when 'a : null> (x : 'a) =
|
||||
match x with
|
||||
| null -> "is null"
|
||||
| _ -> (x :> obj).ToString()
|
||||
|
||||
let runTest =
|
||||
// Wrapping in try block to work around FSB 1989
|
||||
try
|
||||
if isNull null <> "is null" then exit 1
|
||||
if isNull "F#" <> "F#" then exit 1
|
||||
true
|
||||
with _ -> exit 1
|
||||
|
||||
if runTest <> true then exit 1
|
||||
|
||||
exit 0
|
||||
"""
|
||||
|
||||
[<Test>]
|
||||
/// Title: Type checking oddity
|
||||
///
|
||||
/// This suggestion was resolved as by design,
|
||||
/// so the test makes sure, we're emitting error message about 'not being a valid object construction expression'
|
||||
let ``Invalid object constructor``() = // Regression test for FSharp1.0:4189
|
||||
CompilerAssert.TypeCheckWithErrorsAndOptions
|
||||
[| "--test:ErrorRanges" |]
|
||||
"""
|
||||
type ImmutableStack<'a> private(items: 'a list) =
|
||||
|
||||
member this.Push item = ImmutableStack(item::items)
|
||||
member this.Pop = match items with | [] -> failwith "No elements in stack" | x::xs -> x,ImmutableStack(xs)
|
||||
|
||||
// Notice type annotation is commented out, which results in an error
|
||||
new(col (*: seq<'a>*)) = ImmutableStack(List.ofSeq col)
|
||||
|
||||
"""
|
||||
[| FSharpErrorSeverity.Error, 41, (4, 29, 4, 56), "A unique overload for method 'ImmutableStack`1' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: new : col:'b -> ImmutableStack<'a>, private new : items:'a list -> ImmutableStack<'a>"
|
||||
FSharpErrorSeverity.Error, 41, (5, 93, 5, 111), "A unique overload for method 'ImmutableStack`1' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: new : col:'b -> ImmutableStack<'a>, private new : items:'a list -> ImmutableStack<'a>"
|
||||
FSharpErrorSeverity.Error, 41, (8, 30, 8, 60), "A unique overload for method 'ImmutableStack`1' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: new : col:'b -> ImmutableStack<'a> when 'b :> seq<'c>, private new : items:'a list -> ImmutableStack<'a>"
|
||||
FSharpErrorSeverity.Error, 696, (8, 30, 8, 60), "This is not a valid object construction expression. Explicit object constructors must either call an alternate constructor or initialize all fields of the object and specify a call to a super class constructor." |]
|
|
@ -0,0 +1,23 @@
|
|||
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
|
||||
|
||||
namespace FSharp.Compiler.UnitTests
|
||||
|
||||
open NUnit.Framework
|
||||
open FSharp.Compiler.SourceCodeServices
|
||||
|
||||
[<TestFixture>]
|
||||
module ``Errors assigning to mutable objects`` =
|
||||
|
||||
[<Test>]
|
||||
let ``Assign to immutable error``() =
|
||||
CompilerAssert.TypeCheckSingleError
|
||||
"""
|
||||
let x = 10
|
||||
x <- 20
|
||||
|
||||
exit 0
|
||||
"""
|
||||
FSharpErrorSeverity.Error
|
||||
27
|
||||
(3, 1, 3, 8)
|
||||
"This value is not mutable. Consider using the mutable keyword, e.g. 'let mutable x = expression'."
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
|
||||
|
||||
namespace FSharp.Compiler.UnitTests
|
||||
|
||||
open NUnit.Framework
|
||||
open FSharp.Compiler.SourceCodeServices
|
||||
|
||||
[<TestFixture>]
|
||||
module NameResolutionTests =
|
||||
|
||||
[<Test>]
|
||||
let FieldNotInRecord () =
|
||||
CompilerAssert.TypeCheckSingleError
|
||||
"""
|
||||
type A = { Hello:string; World:string }
|
||||
type B = { Size:int; Height:int }
|
||||
type C = { Wheels:int }
|
||||
type D = { Size:int; Height:int; Walls:int }
|
||||
type E = { Unknown:string }
|
||||
type F = { Wallis:int; Size:int; Height:int; }
|
||||
|
||||
let r:F = { Size=3; Height=4; Wall=1 }
|
||||
"""
|
||||
FSharpErrorSeverity.Error
|
||||
1129
|
||||
(9, 31, 9, 35)
|
||||
"The record type 'F' does not contain a label 'Wall'."
|
||||
|
||||
[<Test>]
|
||||
let RecordFieldProposal () =
|
||||
CompilerAssert.TypeCheckSingleError
|
||||
"""
|
||||
type A = { Hello:string; World:string }
|
||||
type B = { Size:int; Height:int }
|
||||
type C = { Wheels:int }
|
||||
type D = { Size:int; Height:int; Walls:int }
|
||||
type E = { Unknown:string }
|
||||
type F = { Wallis:int; Size:int; Height:int; }
|
||||
|
||||
let r = { Size=3; Height=4; Wall=1 }
|
||||
"""
|
||||
FSharpErrorSeverity.Error
|
||||
39
|
||||
(9, 29, 9, 33)
|
||||
"The record label 'Wall' is not defined."
|
|
@ -0,0 +1,135 @@
|
|||
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
|
||||
|
||||
namespace FSharp.Compiler.UnitTests
|
||||
|
||||
open NUnit.Framework
|
||||
open FSharp.Compiler.SourceCodeServices
|
||||
|
||||
[<TestFixture>]
|
||||
module ``Type Mismatch`` =
|
||||
|
||||
[<Test>]
|
||||
let ``return Instead Of return!``() =
|
||||
CompilerAssert.TypeCheckSingleError
|
||||
"""
|
||||
let rec foo() = async { return foo() }
|
||||
"""
|
||||
FSharpErrorSeverity.Error
|
||||
1
|
||||
(2, 32, 2, 37)
|
||||
"Type mismatch. Expecting a\n ''a' \nbut given a\n 'Async<'a>' \nThe types ''a' and 'Async<'a>' cannot be unified. Consider using 'return!' instead of 'return'."
|
||||
|
||||
[<Test>]
|
||||
let ``yield Instead Of yield!``() =
|
||||
CompilerAssert.TypeCheckSingleError
|
||||
"""
|
||||
type Foo() =
|
||||
member this.Yield(x) = [x]
|
||||
|
||||
let rec f () = Foo() { yield f ()}
|
||||
"""
|
||||
FSharpErrorSeverity.Error
|
||||
1
|
||||
(5, 30, 5, 34)
|
||||
"Type mismatch. Expecting a\n ''a' \nbut given a\n ''a list' \nThe types ''a' and ''a list' cannot be unified. Consider using 'yield!' instead of 'yield'."
|
||||
|
||||
[<Test>]
|
||||
let ``Ref Cell Instead Of Not``() =
|
||||
CompilerAssert.TypeCheckSingleError
|
||||
"""
|
||||
let x = true
|
||||
if !x then
|
||||
printfn "hello"
|
||||
"""
|
||||
FSharpErrorSeverity.Error
|
||||
1
|
||||
(3, 5, 3, 6)
|
||||
"This expression was expected to have type\n 'bool ref' \nbut here has type\n 'bool' \r\nThe '!' operator is used to dereference a ref cell. Consider using 'not expr' here."
|
||||
|
||||
[<Test>]
|
||||
let ``Ref Cell Instead Of Not 2``() =
|
||||
CompilerAssert.TypeCheckSingleError
|
||||
"""
|
||||
let x = true
|
||||
let y = !x
|
||||
"""
|
||||
FSharpErrorSeverity.Error
|
||||
1
|
||||
(3, 10, 3, 11)
|
||||
"This expression was expected to have type\n ''a ref' \nbut here has type\n 'bool' \r\nThe '!' operator is used to dereference a ref cell. Consider using 'not expr' here."
|
||||
|
||||
[<Test>]
|
||||
let ``Guard Has Wrong Type``() =
|
||||
CompilerAssert.TypeCheckWithErrors
|
||||
"""
|
||||
let x = 1
|
||||
match x with
|
||||
| 1 when "s" -> true
|
||||
| _ -> false
|
||||
"""
|
||||
[|
|
||||
FSharpErrorSeverity.Error, 1, (4, 10, 4, 13), "A pattern match guard must be of type 'bool', but this 'when' expression is of type 'string'."
|
||||
FSharpErrorSeverity.Warning, 20, (3, 1, 5, 13), "The result of this expression has type 'bool' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'."
|
||||
|]
|
||||
|
||||
[<Test>]
|
||||
let ``Runtime Type Test In Pattern``() =
|
||||
CompilerAssert.TypeCheckWithErrors
|
||||
"""
|
||||
open System.Collections.Generic
|
||||
|
||||
let orig = Dictionary<obj,obj>()
|
||||
|
||||
let c =
|
||||
match orig with
|
||||
| :? IDictionary<obj,obj> -> "yes"
|
||||
| _ -> "no"
|
||||
"""
|
||||
[|
|
||||
FSharpErrorSeverity.Warning, 67, (8, 5, 8, 28), "This type test or downcast will always hold"
|
||||
FSharpErrorSeverity.Error, 193, (8, 5, 8, 28), "Type constraint mismatch. The type \n 'IDictionary<obj,obj>' \nis not compatible with type\n 'Dictionary<obj,obj>' \n"
|
||||
|]
|
||||
|
||||
[<Test>]
|
||||
let ``Runtime Type Test In Pattern 2``() =
|
||||
CompilerAssert.TypeCheckWithErrors
|
||||
"""
|
||||
open System.Collections.Generic
|
||||
|
||||
let orig = Dictionary<obj,obj>()
|
||||
|
||||
let c =
|
||||
match orig with
|
||||
| :? IDictionary<obj,obj> as y -> "yes" + y.ToString()
|
||||
| _ -> "no"
|
||||
"""
|
||||
[|
|
||||
FSharpErrorSeverity.Warning, 67, (8, 5, 8, 28), "This type test or downcast will always hold"
|
||||
FSharpErrorSeverity.Error, 193, (8, 5, 8, 28), "Type constraint mismatch. The type \n 'IDictionary<obj,obj>' \nis not compatible with type\n 'Dictionary<obj,obj>' \n"
|
||||
|]
|
||||
|
||||
[<Test>]
|
||||
let ``Override Errors``() =
|
||||
CompilerAssert.TypeCheckWithErrors
|
||||
"""
|
||||
type Base() =
|
||||
abstract member Member: int * string -> string
|
||||
default x.Member (i, s) = s
|
||||
|
||||
type Derived1() =
|
||||
inherit Base()
|
||||
override x.Member() = 5
|
||||
|
||||
type Derived2() =
|
||||
inherit Base()
|
||||
override x.Member (i : int) = "Hello"
|
||||
|
||||
type Derived3() =
|
||||
inherit Base()
|
||||
override x.Member (s : string, i : int) = sprintf "Hello %s" s
|
||||
"""
|
||||
[|
|
||||
FSharpErrorSeverity.Error, 856, (8, 16, 8, 22), "This override takes a different number of arguments to the corresponding abstract member. The following abstract members were found:\r\n abstract member Base.Member : int * string -> string"
|
||||
FSharpErrorSeverity.Error, 856, (12, 16, 12, 22), "This override takes a different number of arguments to the corresponding abstract member. The following abstract members were found:\r\n abstract member Base.Member : int * string -> string"
|
||||
FSharpErrorSeverity.Error, 1, (16, 24, 16, 34), "This expression was expected to have type\n 'int' \nbut here has type\n 'string' "
|
||||
|]
|
|
@ -0,0 +1,27 @@
|
|||
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
|
||||
|
||||
namespace FSharp.Compiler.UnitTests
|
||||
|
||||
open NUnit.Framework
|
||||
open FSharp.Compiler.SourceCodeServices
|
||||
|
||||
[<TestFixture>]
|
||||
module ``Unit generic abstract Type`` =
|
||||
|
||||
[<Test>]
|
||||
let ``Unit can not be used as return type of abstract method paramete on return type``() =
|
||||
CompilerAssert.TypeCheckSingleError
|
||||
"""
|
||||
type EDF<'S> =
|
||||
abstract member Apply : int -> 'S
|
||||
type SomeEDF () =
|
||||
interface EDF<unit> with
|
||||
member this.Apply d =
|
||||
// [ERROR] The member 'Apply' does not have the correct type to override the corresponding abstract method.
|
||||
()
|
||||
"""
|
||||
FSharpErrorSeverity.Error
|
||||
17
|
||||
(6, 21, 6, 26)
|
||||
"The member 'Apply : int -> unit' is specialized with 'unit' but 'unit' can't be used as return type of an abstract method parameterized on return type."
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
|
||||
|
||||
namespace FSharp.Compiler.UnitTests
|
||||
|
||||
open NUnit.Framework
|
||||
open FSharp.Compiler.SourceCodeServices
|
||||
|
||||
[<TestFixture>]
|
||||
module ``Upcast and Downcast`` =
|
||||
|
||||
[<Test>]
|
||||
let ``Downcast Instead Of Upcast``() =
|
||||
CompilerAssert.TypeCheckSingleError
|
||||
"""
|
||||
open System.Collections.Generic
|
||||
|
||||
let orig = Dictionary<obj,obj>() :> IDictionary<obj,obj>
|
||||
let c = orig :> Dictionary<obj,obj>
|
||||
"""
|
||||
FSharpErrorSeverity.Error
|
||||
193
|
||||
(5, 9, 5, 36)
|
||||
"Type constraint mismatch. The type \n 'IDictionary<obj,obj>' \nis not compatible with type\n 'Dictionary<obj,obj>' \n"
|
||||
|
||||
[<Test>]
|
||||
let ``Upcast Instead Of Downcast``() =
|
||||
CompilerAssert.TypeCheckWithErrors
|
||||
"""
|
||||
open System.Collections.Generic
|
||||
|
||||
let orig = Dictionary<obj,obj>()
|
||||
let c = orig :?> IDictionary<obj,obj>
|
||||
"""
|
||||
[|
|
||||
FSharpErrorSeverity.Warning, 67, (5, 9, 5, 38), "This type test or downcast will always hold"
|
||||
FSharpErrorSeverity.Error, 3198, (5, 9, 5, 38), "The conversion from Dictionary<obj,obj> to IDictionary<obj,obj> is a compile-time safe upcast, not a downcast. Consider using the :> (upcast) operator instead of the :?> (downcast) operator."
|
||||
|]
|
||||
|
||||
[<Test>]
|
||||
let ``Upcast Function Instead Of Downcast``() =
|
||||
CompilerAssert.TypeCheckWithErrors
|
||||
"""
|
||||
open System.Collections.Generic
|
||||
|
||||
let orig = Dictionary<obj,obj>()
|
||||
let c : IDictionary<obj,obj> = downcast orig
|
||||
"""
|
||||
[|
|
||||
FSharpErrorSeverity.Warning, 67, (5, 32, 5, 45), "This type test or downcast will always hold"
|
||||
FSharpErrorSeverity.Error, 3198, (5, 32, 5, 45), "The conversion from Dictionary<obj,obj> to IDictionary<obj,obj> is a compile-time safe upcast, not a downcast. Consider using 'upcast' instead of 'downcast'."
|
||||
|]
|
|
@ -0,0 +1,208 @@
|
|||
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
|
||||
|
||||
namespace FSharp.Compiler.UnitTests
|
||||
|
||||
open NUnit.Framework
|
||||
open FSharp.Compiler.SourceCodeServices
|
||||
|
||||
[<TestFixture>]
|
||||
module ``Warn Expression`` =
|
||||
|
||||
[<Test>]
|
||||
let ``Warn If Expression Result Unused``() =
|
||||
CompilerAssert.TypeCheckSingleError
|
||||
"""
|
||||
1 + 2
|
||||
printfn "%d" 3
|
||||
"""
|
||||
FSharpErrorSeverity.Warning
|
||||
20
|
||||
(2, 1, 2, 6)
|
||||
"The result of this expression has type 'int' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'."
|
||||
|
||||
[<Test>]
|
||||
let ``Warn If Possible Assignment``() =
|
||||
CompilerAssert.TypeCheckSingleError
|
||||
"""
|
||||
let x = 10
|
||||
let y = "hello"
|
||||
|
||||
let changeX() =
|
||||
x = 20
|
||||
y = "test"
|
||||
"""
|
||||
FSharpErrorSeverity.Warning
|
||||
20
|
||||
(6, 5, 6, 11)
|
||||
"The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to mutate a value, then mark the value 'mutable' and use the '<-' operator e.g. 'x <- expression'."
|
||||
|
||||
[<Test>]
|
||||
let ``Warn If Possible Assignment To Mutable``() =
|
||||
CompilerAssert.TypeCheckSingleError
|
||||
"""
|
||||
let mutable x = 10
|
||||
let y = "hello"
|
||||
|
||||
let changeX() =
|
||||
x = 20
|
||||
y = "test"
|
||||
"""
|
||||
FSharpErrorSeverity.Warning
|
||||
20
|
||||
(6, 5, 6, 11)
|
||||
"The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to mutate a value, then use the '<-' operator e.g. 'x <- expression'."
|
||||
|
||||
[<Test>]
|
||||
let ``Warn If Possible dotnet Property Setter``() =
|
||||
CompilerAssert.TypeCheckWithErrors
|
||||
"""
|
||||
open System
|
||||
|
||||
let z = System.Timers.Timer()
|
||||
let y = "hello"
|
||||
|
||||
let changeProperty() =
|
||||
z.Enabled = true
|
||||
y = "test"
|
||||
"""
|
||||
[|
|
||||
FSharpErrorSeverity.Warning, 760, (4, 9, 4, 30), "It is recommended that objects supporting the IDisposable interface are created using the syntax 'new Type(args)', rather than 'Type(args)' or 'Type' as a function value representing the constructor, to indicate that resources may be owned by the generated value"
|
||||
FSharpErrorSeverity.Warning, 20, (8, 5, 8, 21), "The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to set a value to a property, then use the '<-' operator e.g. 'z.Enabled <- expression'."
|
||||
|]
|
||||
|
||||
[<Test>]
|
||||
let ``Don't Warn If Property Without Setter``() =
|
||||
CompilerAssert.TypeCheckSingleError
|
||||
"""
|
||||
type MyClass(property1 : int) =
|
||||
member val Property2 = "" with get
|
||||
|
||||
let x = MyClass(1)
|
||||
let y = "hello"
|
||||
|
||||
let changeProperty() =
|
||||
x.Property2 = "22"
|
||||
y = "test"
|
||||
"""
|
||||
FSharpErrorSeverity.Warning
|
||||
20
|
||||
(9, 5, 9, 23)
|
||||
"The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'."
|
||||
|
||||
[<Test>]
|
||||
let ``Warn If Implicitly Discarded``() =
|
||||
CompilerAssert.TypeCheckSingleError
|
||||
"""
|
||||
let x = 10
|
||||
let y = 20
|
||||
|
||||
let changeX() =
|
||||
y * x = 20
|
||||
y = 30
|
||||
"""
|
||||
FSharpErrorSeverity.Warning
|
||||
20
|
||||
(6, 5, 6, 15)
|
||||
"The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'."
|
||||
|
||||
[<Test>]
|
||||
let ``Warn If Discarded In List``() =
|
||||
CompilerAssert.TypeCheckSingleError
|
||||
"""
|
||||
let div _ _ = 1
|
||||
let subView _ _ = [1; 2]
|
||||
|
||||
// elmish view
|
||||
let view model dispatch =
|
||||
[
|
||||
yield! subView model dispatch
|
||||
div [] []
|
||||
]
|
||||
"""
|
||||
FSharpErrorSeverity.Warning
|
||||
3221
|
||||
(9, 8, 9, 17)
|
||||
"This expression returns a value of type 'int' but is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to use the expression as a value in the sequence then use an explicit 'yield'."
|
||||
|
||||
[<Test>]
|
||||
let ``Warn If Discarded In List 2``() =
|
||||
CompilerAssert.TypeCheckSingleError
|
||||
"""
|
||||
// stupid things to make the sample compile
|
||||
let div _ _ = 1
|
||||
let subView _ _ = [1; 2]
|
||||
let y = 1
|
||||
|
||||
// elmish view
|
||||
let view model dispatch =
|
||||
[
|
||||
div [] [
|
||||
match y with
|
||||
| 1 -> yield! subView model dispatch
|
||||
| _ -> subView model dispatch
|
||||
]
|
||||
]
|
||||
"""
|
||||
FSharpErrorSeverity.Warning
|
||||
3222
|
||||
(13, 19, 13, 41)
|
||||
"This expression returns a value of type 'int list' but is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to use the expression as a value in the sequence then use an explicit 'yield!'."
|
||||
|
||||
[<Test>]
|
||||
let ``Warn If Discarded In List 3``() =
|
||||
CompilerAssert.TypeCheckSingleError
|
||||
"""
|
||||
// stupid things to make the sample compile
|
||||
let div _ _ = 1
|
||||
let subView _ _ = true
|
||||
let y = 1
|
||||
|
||||
// elmish view
|
||||
let view model dispatch =
|
||||
[
|
||||
div [] [
|
||||
match y with
|
||||
| 1 -> ()
|
||||
| _ -> subView model dispatch
|
||||
]
|
||||
]
|
||||
"""
|
||||
FSharpErrorSeverity.Warning
|
||||
20
|
||||
(13, 19, 13, 41)
|
||||
"The result of this expression has type 'bool' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'."
|
||||
|
||||
[<Test>]
|
||||
let ``Warn Only On Last Expression``() =
|
||||
CompilerAssert.TypeCheckSingleError
|
||||
"""
|
||||
let mutable x = 0
|
||||
while x < 1 do
|
||||
printfn "unneeded"
|
||||
x <- x + 1
|
||||
true
|
||||
"""
|
||||
FSharpErrorSeverity.Warning
|
||||
20
|
||||
(6, 5, 6, 9)
|
||||
"The result of this expression has type 'bool' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'."
|
||||
|
||||
[<Test>]
|
||||
let ``Warn If Possible Property Setter``() =
|
||||
CompilerAssert.TypeCheckSingleError
|
||||
"""
|
||||
type MyClass(property1 : int) =
|
||||
member val Property1 = property1
|
||||
member val Property2 = "" with get, set
|
||||
|
||||
let x = MyClass(1)
|
||||
let y = "hello"
|
||||
|
||||
let changeProperty() =
|
||||
x.Property2 = "20"
|
||||
y = "test"
|
||||
"""
|
||||
FSharpErrorSeverity.Warning
|
||||
20
|
||||
(10, 5, 10, 23)
|
||||
"The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to set a value to a property, then use the '<-' operator e.g. 'x.Property2 <- expression'."
|
|
@ -27,45 +27,45 @@ let test () =
|
|||
verifier.VerifyIL
|
||||
[
|
||||
""".method public static void test() cil managed
|
||||
{
|
||||
|
||||
.maxstack 5
|
||||
.locals init (valuetype [System.Private.CoreLib]System.Span`1<class [System.Private.CoreLib]System.Object> V_0,
|
||||
int32 V_1,
|
||||
valuetype [System.Private.CoreLib]System.Int32 V_2,
|
||||
class [System.Private.CoreLib]System.Object& V_3)
|
||||
IL_0000: call valuetype [System.Private.CoreLib]System.Span`1<!0> valuetype [System.Private.CoreLib]System.Span`1<class [System.Private.CoreLib]System.Object>::get_Empty()
|
||||
IL_0005: stloc.0
|
||||
IL_0006: ldc.i4.0
|
||||
IL_0007: stloc.2
|
||||
IL_0008: ldloca.s V_0
|
||||
IL_000a: call instance int32 valuetype [System.Private.CoreLib]System.Span`1<class [System.Private.CoreLib]System.Object>::get_Length()
|
||||
IL_000f: ldc.i4.1
|
||||
IL_0010: sub
|
||||
IL_0011: stloc.1
|
||||
IL_0012: ldloc.1
|
||||
IL_0013: ldloc.2
|
||||
IL_0014: blt.s IL_0034
|
||||
{
|
||||
|
||||
IL_0016: ldloca.s V_0
|
||||
IL_0018: ldloc.2
|
||||
IL_0019: call instance !0& valuetype [System.Private.CoreLib]System.Span`1<class [System.Private.CoreLib]System.Object>::get_Item(int32)
|
||||
IL_001e: stloc.3
|
||||
IL_001f: ldloc.3
|
||||
IL_0020: ldobj [System.Private.CoreLib]System.Object
|
||||
IL_0025: call void [System.Console]System.Console::WriteLine(object)
|
||||
IL_002a: ldloc.2
|
||||
IL_002b: ldc.i4.1
|
||||
IL_002c: add
|
||||
IL_002d: stloc.2
|
||||
IL_002e: ldloc.2
|
||||
IL_002f: ldloc.1
|
||||
IL_0030: ldc.i4.1
|
||||
IL_0031: add
|
||||
IL_0032: bne.un.s IL_0016
|
||||
.maxstack 5
|
||||
.locals init (valuetype [System.Runtime]System.Span`1<object> V_0,
|
||||
int32 V_1,
|
||||
int32 V_2,
|
||||
object& V_3)
|
||||
IL_0000: call valuetype [System.Runtime]System.Span`1<!0> valuetype [System.Runtime]System.Span`1<object>::get_Empty()
|
||||
IL_0005: stloc.0
|
||||
IL_0006: ldc.i4.0
|
||||
IL_0007: stloc.2
|
||||
IL_0008: ldloca.s V_0
|
||||
IL_000a: call instance int32 valuetype [System.Runtime]System.Span`1<object>::get_Length()
|
||||
IL_000f: ldc.i4.1
|
||||
IL_0010: sub
|
||||
IL_0011: stloc.1
|
||||
IL_0012: ldloc.1
|
||||
IL_0013: ldloc.2
|
||||
IL_0014: blt.s IL_0034
|
||||
|
||||
IL_0034: ret
|
||||
} """
|
||||
IL_0016: ldloca.s V_0
|
||||
IL_0018: ldloc.2
|
||||
IL_0019: call instance !0& valuetype [System.Runtime]System.Span`1<object>::get_Item(int32)
|
||||
IL_001e: stloc.3
|
||||
IL_001f: ldloc.3
|
||||
IL_0020: ldobj [System.Runtime]System.Object
|
||||
IL_0025: call void [System.Console]System.Console::WriteLine(object)
|
||||
IL_002a: ldloc.2
|
||||
IL_002b: ldc.i4.1
|
||||
IL_002c: add
|
||||
IL_002d: stloc.2
|
||||
IL_002e: ldloc.2
|
||||
IL_002f: ldloc.1
|
||||
IL_0030: ldc.i4.1
|
||||
IL_0031: add
|
||||
IL_0032: bne.un.s IL_0016
|
||||
|
||||
IL_0034: ret
|
||||
}"""
|
||||
])
|
||||
|
||||
[<Test>]
|
||||
|
@ -88,18 +88,18 @@ let test () =
|
|||
[
|
||||
""".method public static void test() cil managed
|
||||
{
|
||||
|
||||
|
||||
.maxstack 5
|
||||
.locals init (valuetype [System.Private.CoreLib]System.ReadOnlySpan`1<class [System.Private.CoreLib]System.Object> V_0,
|
||||
.locals init (valuetype [System.Runtime]System.ReadOnlySpan`1<object> V_0,
|
||||
int32 V_1,
|
||||
valuetype [System.Private.CoreLib]System.Int32 V_2,
|
||||
class [System.Private.CoreLib]System.Object& V_3)
|
||||
IL_0000: call valuetype [System.Private.CoreLib]System.ReadOnlySpan`1<!0> valuetype [System.Private.CoreLib]System.ReadOnlySpan`1<class [System.Private.CoreLib]System.Object>::get_Empty()
|
||||
int32 V_2,
|
||||
object& V_3)
|
||||
IL_0000: call valuetype [System.Runtime]System.ReadOnlySpan`1<!0> valuetype [System.Runtime]System.ReadOnlySpan`1<object>::get_Empty()
|
||||
IL_0005: stloc.0
|
||||
IL_0006: ldc.i4.0
|
||||
IL_0007: stloc.2
|
||||
IL_0008: ldloca.s V_0
|
||||
IL_000a: call instance int32 valuetype [System.Private.CoreLib]System.ReadOnlySpan`1<class [System.Private.CoreLib]System.Object>::get_Length()
|
||||
IL_000a: call instance int32 valuetype [System.Runtime]System.ReadOnlySpan`1<object>::get_Length()
|
||||
IL_000f: ldc.i4.1
|
||||
IL_0010: sub
|
||||
IL_0011: stloc.1
|
||||
|
@ -109,10 +109,10 @@ let test () =
|
|||
|
||||
IL_0016: ldloca.s V_0
|
||||
IL_0018: ldloc.2
|
||||
IL_0019: call instance !0& modreq([System.Private.CoreLib]System.Runtime.InteropServices.InAttribute) valuetype [System.Private.CoreLib]System.ReadOnlySpan`1<class [System.Private.CoreLib]System.Object>::get_Item(int32)
|
||||
IL_0019: call instance !0& modreq([System.Runtime]System.Runtime.InteropServices.InAttribute) valuetype [System.Runtime]System.ReadOnlySpan`1<object>::get_Item(int32)
|
||||
IL_001e: stloc.3
|
||||
IL_001f: ldloc.3
|
||||
IL_0020: ldobj [System.Private.CoreLib]System.Object
|
||||
IL_0020: ldobj [System.Runtime]System.Object
|
||||
IL_0025: call void [System.Console]System.Console::WriteLine(object)
|
||||
IL_002a: ldloc.2
|
||||
IL_002b: ldc.i4.1
|
||||
|
@ -176,29 +176,29 @@ module Test =
|
|||
[
|
||||
""".method public static void test() cil managed
|
||||
{
|
||||
|
||||
|
||||
.maxstack 3
|
||||
.locals init (valuetype System.Span`1<class [System.Private.CoreLib]System.Object> V_0,
|
||||
class [System.Private.CoreLib]System.Collections.IEnumerator V_1,
|
||||
.locals init (valuetype System.Span`1<object> V_0,
|
||||
class [System.Runtime]System.Collections.IEnumerator V_1,
|
||||
class [FSharp.Core]Microsoft.FSharp.Core.Unit V_2,
|
||||
class [System.Private.CoreLib]System.IDisposable V_3)
|
||||
class [System.Runtime]System.IDisposable V_3)
|
||||
IL_0000: ldc.i4.0
|
||||
IL_0001: newarr [System.Private.CoreLib]System.Object
|
||||
IL_0006: newobj instance void valuetype System.Span`1<class [System.Private.CoreLib]System.Object>::.ctor(!0[])
|
||||
IL_0001: newarr [System.Runtime]System.Object
|
||||
IL_0006: newobj instance void valuetype System.Span`1<object>::.ctor(!0[])
|
||||
IL_000b: stloc.0
|
||||
IL_000c: ldloc.0
|
||||
IL_000d: box valuetype System.Span`1<class [System.Private.CoreLib]System.Object>
|
||||
IL_0012: unbox.any [System.Private.CoreLib]System.Collections.IEnumerable
|
||||
IL_0017: callvirt instance class [System.Private.CoreLib]System.Collections.IEnumerator [System.Private.CoreLib]System.Collections.IEnumerable::GetEnumerator()
|
||||
IL_000d: box valuetype System.Span`1<object>
|
||||
IL_0012: unbox.any [System.Runtime]System.Collections.IEnumerable
|
||||
IL_0017: callvirt instance class [System.Runtime]System.Collections.IEnumerator [System.Runtime]System.Collections.IEnumerable::GetEnumerator()
|
||||
IL_001c: stloc.1
|
||||
.try
|
||||
{
|
||||
IL_001d: ldloc.1
|
||||
IL_001e: callvirt instance bool [System.Private.CoreLib]System.Collections.IEnumerator::MoveNext()
|
||||
IL_001e: callvirt instance bool [System.Runtime]System.Collections.IEnumerator::MoveNext()
|
||||
IL_0023: brfalse.s IL_0032
|
||||
|
||||
IL_0025: ldloc.1
|
||||
IL_0026: callvirt instance object [System.Private.CoreLib]System.Collections.IEnumerator::get_Current()
|
||||
IL_0026: callvirt instance object [System.Runtime]System.Collections.IEnumerator::get_Current()
|
||||
IL_002b: call void [System.Console]System.Console::WriteLine(object)
|
||||
IL_0030: br.s IL_001d
|
||||
|
||||
|
@ -206,24 +206,24 @@ module Test =
|
|||
IL_0033: stloc.2
|
||||
IL_0034: leave.s IL_004c
|
||||
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
IL_0036: ldloc.1
|
||||
IL_0037: isinst [System.Private.CoreLib]System.IDisposable
|
||||
IL_0037: isinst [System.Runtime]System.IDisposable
|
||||
IL_003c: stloc.3
|
||||
IL_003d: ldloc.3
|
||||
IL_003e: brfalse.s IL_0049
|
||||
|
||||
IL_0040: ldloc.3
|
||||
IL_0041: callvirt instance void [System.Private.CoreLib]System.IDisposable::Dispose()
|
||||
IL_0041: callvirt instance void [System.Runtime]System.IDisposable::Dispose()
|
||||
IL_0046: ldnull
|
||||
IL_0047: pop
|
||||
IL_0048: endfinally
|
||||
IL_0049: ldnull
|
||||
IL_004a: pop
|
||||
IL_004b: endfinally
|
||||
}
|
||||
}
|
||||
IL_004c: ldloc.2
|
||||
IL_004d: pop
|
||||
IL_004e: ret
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
|
||||
|
||||
namespace FSharp.Compiler.UnitTests
|
||||
|
||||
open NUnit.Framework
|
||||
open FSharp.Compiler.SourceCodeServices
|
||||
|
||||
[<TestFixture>]
|
||||
module ``Warnings assigning to mutable and immutable objects`` =
|
||||
|
||||
[<Test>]
|
||||
let ``Unused compare with immutable when assignment might be intended``() =
|
||||
CompilerAssert.TypeCheckSingleError
|
||||
"""
|
||||
let x = 10
|
||||
let y = "hello"
|
||||
|
||||
let changeX() =
|
||||
x = 20
|
||||
y = "test"
|
||||
|
||||
exit 0
|
||||
"""
|
||||
FSharpErrorSeverity.Warning
|
||||
20
|
||||
(6, 5, 6, 11)
|
||||
"The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to mutate a value, then mark the value 'mutable' and use the '<-' operator e.g. 'x <- expression'."
|
||||
|
||||
[<Test>]
|
||||
let ``Unused compare with mutable when assignment might be intended``() =
|
||||
CompilerAssert.TypeCheckSingleError
|
||||
"""
|
||||
let mutable x = 10
|
||||
let y = "hello"
|
||||
|
||||
let changeX() =
|
||||
x = 20
|
||||
y = "test"
|
||||
|
||||
exit 0
|
||||
"""
|
||||
FSharpErrorSeverity.Warning
|
||||
20
|
||||
(6, 5, 6, 11)
|
||||
"The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to mutate a value, then use the '<-' operator e.g. 'x <- expression'."
|
||||
|
||||
[<Test>]
|
||||
let ``Unused comparison of property in dotnet object when assignment might be intended``() =
|
||||
CompilerAssert.TypeCheckSingleError
|
||||
"""
|
||||
open System
|
||||
|
||||
let z = new System.Timers.Timer()
|
||||
let y = "hello"
|
||||
|
||||
let changeProperty() =
|
||||
z.Enabled = true
|
||||
y = "test"
|
||||
|
||||
exit 0
|
||||
"""
|
||||
FSharpErrorSeverity.Warning
|
||||
20
|
||||
(8, 5, 8, 21)
|
||||
"The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to set a value to a property, then use the '<-' operator e.g. 'z.Enabled <- expression'."
|
||||
|
||||
[<Test>]
|
||||
let ``Unused comparison of property when assignment might be intended ``() =
|
||||
CompilerAssert.TypeCheckSingleError
|
||||
"""
|
||||
type MyClass(property1 : int) =
|
||||
member val Property1 = property1
|
||||
member val Property2 = "" with get, set
|
||||
|
||||
let x = MyClass(1)
|
||||
let y = "hello"
|
||||
|
||||
let changeProperty() =
|
||||
x.Property2 = "20"
|
||||
y = "test"
|
||||
|
||||
exit 0
|
||||
"""
|
||||
FSharpErrorSeverity.Warning
|
||||
20
|
||||
(10, 5, 10, 23)
|
||||
"The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to set a value to a property, then use the '<-' operator e.g. 'x.Property2 <- expression'."
|
||||
|
||||
[<Test>]
|
||||
let ``Don't warn if assignment to property without setter ``() =
|
||||
CompilerAssert.TypeCheckSingleError
|
||||
"""
|
||||
type MyClass(property1 : int) =
|
||||
member val Property2 = "" with get
|
||||
|
||||
let x = MyClass(1)
|
||||
let y = "hello"
|
||||
|
||||
let changeProperty() =
|
||||
x.Property2 = "22"
|
||||
y = "test"
|
||||
|
||||
exit 0
|
||||
"""
|
||||
FSharpErrorSeverity.Warning
|
||||
20
|
||||
(9, 5, 9, 23)
|
||||
"The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'."
|
|
@ -36,7 +36,15 @@
|
|||
<Compile Include="Compiler\ErrorMessages\ConstructorTests.fs" />
|
||||
<Compile Include="Compiler\ErrorMessages\AccessOfTypeAbbreviationTests.fs" />
|
||||
<Compile Include="Compiler\ErrorMessages\ElseBranchHasWrongTypeTests.fs" />
|
||||
<Compile Include="Compiler\ConstraintSolver\PrimitiveConstraints.fs" />
|
||||
<Compile Include="Compiler\ConstraintSolver\MemberConstraints.fs" />
|
||||
<Compile Include="Compiler\ErrorMessages\MissingElseBranch.fs" />
|
||||
<Compile Include="Compiler\ErrorMessages\UnitGenericAbstactType.fs" />
|
||||
<Compile Include="Compiler\ErrorMessages\NameResolutionTests.fs" />
|
||||
<Compile Include="Compiler\ErrorMessages\TypeMismatchTests.fs" />
|
||||
<Compile Include="Compiler\ErrorMessages\UpcastDowncastTests.fs" />
|
||||
<Compile Include="Compiler\ErrorMessages\AssignmentErrorTests.fs" />
|
||||
<Compile Include="Compiler\ErrorMessages\WarnExpressionTests.fs" />
|
||||
<Compile Include="Compiler\SourceTextTests.fs" />
|
||||
<Compile Include="Compiler\Language\AnonRecordTests.fs" />
|
||||
<Compile Include="Compiler\Language\SpanOptimizationTests.fs" />
|
||||
|
|
|
@ -0,0 +1,168 @@
|
|||
namespace FSharp.Libraries.UnitTests
|
||||
|
||||
open System
|
||||
open NUnit.Framework
|
||||
open FSharp.Compiler.UnitTests
|
||||
|
||||
[<TestFixture>]
|
||||
module AsyncTests =
|
||||
// Regression for FSHARP1.0:5969
|
||||
// Async.StartChild: error when wait async is executed more than once
|
||||
[<Test>]
|
||||
let ``Execute Async multiple times``() =
|
||||
CompilerAssert.CompileExeAndRun
|
||||
"""
|
||||
module M
|
||||
|
||||
let a = async {
|
||||
let! a = Async.StartChild(
|
||||
async {
|
||||
do! Async.Sleep(1)
|
||||
return 27
|
||||
})
|
||||
let! result = Async.Parallel [ a; a; a; a ]
|
||||
return result
|
||||
} |> Async.RunSynchronously
|
||||
|
||||
exit 0
|
||||
"""
|
||||
|
||||
|
||||
// Regression for FSHARP1.0:5970
|
||||
// Async.StartChild: race in implementation of ResultCell in FSharp.Core
|
||||
[<Test>]
|
||||
let ``Joining StartChild``() =
|
||||
CompilerAssert.CompileExeAndRun
|
||||
"""
|
||||
module M
|
||||
|
||||
let Join (a1: Async<'a>) (a2: Async<'b>) = async {
|
||||
let! task1 = a1 |> Async.StartChild
|
||||
let! task2 = a2 |> Async.StartChild
|
||||
|
||||
let! res1 = task1
|
||||
let! res2 = task2
|
||||
return (res1,res2) }
|
||||
|
||||
let r =
|
||||
try
|
||||
Async.RunSynchronously (Join (async { do! Async.Sleep(30)
|
||||
failwith "fail"
|
||||
return 3+3 })
|
||||
(async { do! Async.Sleep(30)
|
||||
return 2 + 2 } ))
|
||||
with _ ->
|
||||
(0,0)
|
||||
|
||||
exit 0
|
||||
|
||||
"""
|
||||
|
||||
// Regression test for FSHARP1.0:6086
|
||||
[<Test>]
|
||||
let ``Mailbox Async dot not StackOverflow``() =
|
||||
CompilerAssert.CompileExeAndRun
|
||||
"""
|
||||
open Microsoft.FSharp.Control
|
||||
|
||||
type Color = Blue | Red | Yellow
|
||||
let complement = function
|
||||
| (Red, Yellow) | (Yellow, Red) -> Blue
|
||||
| (Red, Blue) | (Blue, Red) -> Yellow
|
||||
| (Yellow, Blue) | (Blue, Yellow) -> Red
|
||||
| (Blue, Blue) -> Blue
|
||||
| (Red, Red) -> Red
|
||||
| (Yellow, Yellow) -> Yellow
|
||||
|
||||
type Message = Color * AsyncReplyChannel<Color option>
|
||||
|
||||
let chameleon (meetingPlace : MailboxProcessor<Message>) initial =
|
||||
let rec loop c meets = async {
|
||||
let replyMessage = meetingPlace.PostAndReply(fun reply -> c, reply)
|
||||
match replyMessage with
|
||||
| Some(newColor) -> return! loop newColor (meets + 1)
|
||||
| None -> return meets
|
||||
}
|
||||
loop initial 0
|
||||
|
||||
let meetingPlace chams n = MailboxProcessor.Start(fun (processor : MailboxProcessor<Message>)->
|
||||
let rec fadingLoop total =
|
||||
async {
|
||||
if total <> 0 then
|
||||
let! (_, reply) = processor.Receive()
|
||||
reply.Reply None
|
||||
return! fadingLoop (total - 1)
|
||||
else
|
||||
printfn "Done"
|
||||
}
|
||||
let rec mainLoop curr =
|
||||
async {
|
||||
if (curr > 0) then
|
||||
let! (color1, reply1) = processor.Receive()
|
||||
let! (color2, reply2) = processor.Receive()
|
||||
let newColor = complement (color1, color2)
|
||||
reply1.Reply <| Some(newColor)
|
||||
reply2.Reply <| Some(newColor)
|
||||
return! mainLoop (curr - 1)
|
||||
else
|
||||
return! fadingLoop chams
|
||||
}
|
||||
mainLoop n
|
||||
)
|
||||
|
||||
open System
|
||||
open System.Diagnostics
|
||||
|
||||
let meetings = 100000
|
||||
|
||||
let colors = [Blue; Red; Yellow; Blue]
|
||||
let mp = meetingPlace (colors.Length) meetings
|
||||
let watch = Stopwatch.StartNew()
|
||||
let meets =
|
||||
colors
|
||||
|> List.map (chameleon mp)
|
||||
|> Async.Parallel
|
||||
|> Async.RunSynchronously
|
||||
watch.Stop()
|
||||
for meet in meets do
|
||||
printfn "%d" meet
|
||||
printfn "Total: %d in %O" (Seq.sum meets) (watch.Elapsed)
|
||||
|
||||
exit 0
|
||||
"""
|
||||
|
||||
// Regression for FSHARP1.0:5971
|
||||
[<Test>]
|
||||
let ``StartChild do not throw ObjectDisposedException``() =
|
||||
CompilerAssert.CompileExeAndRun
|
||||
"""
|
||||
module M
|
||||
|
||||
let b = async {return 5} |> Async.StartChild
|
||||
printfn "%A" (b |> Async.RunSynchronously |> Async.RunSynchronously)
|
||||
|
||||
exit 0
|
||||
"""
|
||||
|
||||
|
||||
[<Test>]
|
||||
let ``StartChild test Trampoline HijackLimit``() =
|
||||
CompilerAssert.CompileExeAndRun
|
||||
"""
|
||||
module M
|
||||
|
||||
let r =
|
||||
async {
|
||||
let! a = Async.StartChild(
|
||||
async {
|
||||
do! Async.Sleep(1)
|
||||
return 5
|
||||
}
|
||||
)
|
||||
let! _ = a
|
||||
for __ in 1..10000 do // 10000 > bindHijackLimit
|
||||
()
|
||||
} |> Async.RunSynchronously
|
||||
|
||||
exit 0
|
||||
"""
|
|
@ -39,6 +39,7 @@
|
|||
//<Expects status="success">section='- ADVANCED - ' ! option=fullpaths kind=OptionUnit</Expects>
|
||||
//<Expects status="success">section='- ADVANCED - ' ! option=lib kind=OptionStringList</Expects>
|
||||
//<Expects status="success">section='- ADVANCED - ' ! option=baseaddress kind=OptionString</Expects>
|
||||
//<Expects status="success">section='- ADVANCED - ' ! option=checksumalgorithm kind=OptionString</Expects>
|
||||
//<Expects status="success">section='- ADVANCED - ' ! option=noframework kind=OptionUnit</Expects>
|
||||
//<Expects status="success">section='- ADVANCED - ' ! option=standalone kind=OptionUnit</Expects>
|
||||
//<Expects status="success">section='- ADVANCED - ' ! option=staticlink kind=OptionString</Expects>
|
||||
|
|
|
@ -137,6 +137,10 @@ Copyright (c) Microsoft Corporation. All Rights Reserved.
|
|||
Default - mscorlib
|
||||
--baseaddress:<address> Base address for the library to be
|
||||
built
|
||||
--checksumalgorithm:{SHA1|SHA256} Specify algorithm for calculating
|
||||
source file checksum stored in PDB.
|
||||
Supported values are: SHA1 or SHA256
|
||||
(default)
|
||||
--noframework Do not reference the default CLI
|
||||
assemblies by default
|
||||
--standalone Statically link the F# library and
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
// #Regression #Conformance #TypeInference #TypeConstraints
|
||||
// Regression test for FSharp1.0:2262
|
||||
// We should emit an error, not ICE
|
||||
//<Expects id="FS0697" span="(6,42-6,75)" status="error">Invalid constraint</Expects>
|
||||
|
||||
let inline length (x: ^a) : int = (^a : (member Length : int with get, set) (x, ()))
|
|
@ -1,16 +0,0 @@
|
|||
// #Regression #Conformance #TypeInference #TypeConstraints
|
||||
// Regression test for FSharp1.0:4189
|
||||
// Title: Type checking oddity
|
||||
|
||||
// This suggestion was resolved as by design,
|
||||
// so the test makes sure, we're emitting error message about 'not being avalid object construction expression'
|
||||
|
||||
//<Expects status="error" span="(16,30-16,60)" id="FS0696">This is not a valid object construction expression\. Explicit object constructors must either call an alternate constructor or initialize all fields of the object and specify a call to a super class constructor\.$</Expects>
|
||||
|
||||
type ImmutableStack<'a> private(items: 'a list) =
|
||||
|
||||
member this.Push item = ImmutableStack(item::items)
|
||||
member this.Pop = match items with | [] -> failwith "No elements in stack" | x::xs -> x,ImmutableStack(xs)
|
||||
|
||||
// Notice type annotation is commented out, which results in an error
|
||||
new(col (*: seq<'a>*)) = ImmutableStack(List.ofSeq col)
|
|
@ -1,24 +0,0 @@
|
|||
// #Conformance #TypeInference #TypeConstraints
|
||||
// Verify you can overload operators on a type and not add all the extra jazz
|
||||
// such as inlining and the ^ operator.
|
||||
|
||||
type Foo(x : int) =
|
||||
member this.Val = x
|
||||
|
||||
static member (-->) ((src : Foo), (target : Foo)) = new Foo(src.Val + target.Val)
|
||||
static member (-->) ((src : Foo), (target : int)) = new Foo(src.Val + target)
|
||||
|
||||
static member (+) ((src : Foo), (target : Foo)) = new Foo(src.Val + target.Val)
|
||||
static member (+) ((src : Foo), (target : int)) = new Foo(src.Val + target)
|
||||
|
||||
let x = Foo(3) --> 4
|
||||
let y = Foo(3) --> Foo(4)
|
||||
let x2 = Foo(3) + 4
|
||||
let y2 = Foo(3) + Foo(4)
|
||||
|
||||
if x.Val <> 7 then exit 1
|
||||
if y.Val <> 7 then exit 1
|
||||
if x2.Val <> 7 then exit 1
|
||||
if y2.Val <> 7 then exit 1
|
||||
|
||||
exit 0
|
|
@ -1,26 +0,0 @@
|
|||
// #Conformance #TypeInference #TypeConstraints
|
||||
#light
|
||||
|
||||
// Test primitive constraints
|
||||
|
||||
// Test ':' constraints
|
||||
|
||||
type Foo(x : int) =
|
||||
member this.Value = x
|
||||
override this.ToString() = "Foo"
|
||||
|
||||
type Bar(x : int) =
|
||||
inherit Foo(-1)
|
||||
member this.Value2 = x
|
||||
override this.ToString() = "Bar"
|
||||
|
||||
let test1 (x : Foo) = x.Value
|
||||
let test2 (x : Bar) = (x.Value, x.Value2)
|
||||
|
||||
let f = new Foo(128)
|
||||
let b = new Bar(256)
|
||||
|
||||
if test1 f <> 128 then exit 1
|
||||
if test2 b <> (-1, 256) then exit 1
|
||||
|
||||
exit 0
|
|
@ -1,33 +0,0 @@
|
|||
// #Conformance #TypeInference #TypeConstraints
|
||||
|
||||
#light
|
||||
|
||||
// Test primitive constraints
|
||||
|
||||
// Test ':>' constraints
|
||||
|
||||
type Foo(x : int) =
|
||||
member this.Value = x
|
||||
override this.ToString() = "Foo"
|
||||
|
||||
type Bar(x : int) =
|
||||
inherit Foo(-1)
|
||||
member this.Value2 = x
|
||||
override this.ToString() = "Bar"
|
||||
|
||||
type Ram(x : int) =
|
||||
inherit Foo(10)
|
||||
member this.ValueA = x
|
||||
override this.ToString() = "Ram"
|
||||
|
||||
let test (x : Foo) = (x.Value, x.ToString())
|
||||
|
||||
let f = new Foo(128)
|
||||
let b = new Bar(256)
|
||||
let r = new Ram(314)
|
||||
|
||||
if test f <> (128, "Foo") then exit 1
|
||||
if test b <> (-1, "Bar") then exit 1
|
||||
if test r <> (10, "Ram") then exit 1
|
||||
|
||||
exit 0
|
|
@ -1,23 +0,0 @@
|
|||
// #Conformance #TypeInference #TypeConstraints
|
||||
#light
|
||||
|
||||
// Test primitive constraints
|
||||
|
||||
// Test ': null' constraints
|
||||
|
||||
let inline isNull<'a when 'a : null> (x : 'a) =
|
||||
match x with
|
||||
| null -> "is null"
|
||||
| _ -> (x :> obj).ToString()
|
||||
|
||||
let runTest =
|
||||
// Wrapping in try block to work around FSB 1989
|
||||
try
|
||||
if isNull null <> "is null" then exit 1
|
||||
if isNull "F#" <> "F#" then exit 1
|
||||
true
|
||||
with _ -> exit 1
|
||||
|
||||
if runTest <> true then exit 1
|
||||
|
||||
exit 0
|
|
@ -1,10 +1,5 @@
|
|||
SOURCE=E_NoImplicitDowncast01.fs SCFLAGS="--test:ErrorRanges --flaterrors" # E_NoImplicitDowncast01.fs
|
||||
|
||||
SOURCE=PrimConstraint01.fs # PrimConstraint01.fs
|
||||
SOURCE=PrimConstraint02.fs # PrimConstraint02.fs
|
||||
SOURCE=PrimConstraint03.fs # PrimConstraint03.fs
|
||||
SOURCE=E_PrimConstraint04.fs SCFLAGS="--test:ErrorRanges" # E_PrimConstraint04.fs
|
||||
|
||||
SOURCE=E_TypeFuncDeclaredExplicit01.fs # E_TypeFuncDeclaredExplicit01.fs
|
||||
|
||||
SOURCE=ValueRestriction01.fs # ValueRestriction01.fs
|
||||
|
@ -16,7 +11,4 @@
|
|||
SOURCE=DelegateConstraint01.fs # DelegateConstraint01.fs
|
||||
SOURCE=E_DelegateConstraint01.fs # E_DelegateConstraint01.fs
|
||||
|
||||
SOURCE=MemberConstraints01.fs # MemberConstraints01.fs
|
||||
SOURCE=E_MemberConstraints01.fs SCFLAGS="--test:ErrorRanges" # E_MemberConstraints01.fs
|
||||
|
||||
SOURCE=ConstructorConstraint01.fs # ConstructorConstraint01.fs
|
|
@ -1,13 +0,0 @@
|
|||
// #ErrorMessages #NameResolution
|
||||
//<Expects status="error" span="(11,31)" id="FS1129">The record type 'F' does not contain a label 'Wall'\.</Expects>
|
||||
|
||||
type A = { Hello:string; World:string }
|
||||
type B = { Size:int; Height:int }
|
||||
type C = { Wheels:int }
|
||||
type D = { Size:int; Height:int; Walls:int }
|
||||
type E = { Unknown:string }
|
||||
type F = { Wallis:int; Size:int; Height:int; }
|
||||
|
||||
let r:F = { Size=3; Height=4; Wall=1 }
|
||||
|
||||
exit 0
|
|
@ -1,6 +0,0 @@
|
|||
// #ErrorMessages #NameResolution
|
||||
//<Expects status="error" span="(4,36)" id="FS1126">'global' may only be used as the first name in a qualified path</Expects>
|
||||
|
||||
let x = global.System.String.Empty.global.System.String.Empty
|
||||
|
||||
exit 0
|
|
@ -1,13 +0,0 @@
|
|||
// #ErrorMessages #NameResolution
|
||||
//<Expects status="error" span="(11,29)" id="FS0039">The record label 'Wall' is not defined\.</Expects>
|
||||
|
||||
type A = { Hello:string; World:string }
|
||||
type B = { Size:int; Height:int }
|
||||
type C = { Wheels:int }
|
||||
type D = { Size:int; Height:int; Walls:int }
|
||||
type E = { Unknown:string }
|
||||
type F = { Wallis:int; Size:int; Height:int; }
|
||||
|
||||
let r = { Size=3; Height=4; Wall=1 }
|
||||
|
||||
exit 0
|
|
@ -1,3 +0,0 @@
|
|||
SOURCE=E_RecordFieldProposal.fs # E_RecordFieldProposal
|
||||
SOURCE=E_GlobalQualifierAfterDot.fs # E_GlobalQualifierAfterDot
|
||||
SOURCE=E_FieldNotInRecord.fs # E_FieldNotInRecord
|
|
@ -1,9 +0,0 @@
|
|||
// #ErrorMessages #UnitGenericAbstractType
|
||||
//<Expects status="error" span="(7,21)" id="FS0017">The member 'Apply : int -> unit' is specialized with 'unit' but 'unit' can't be used as return type of an abstract method parameterized on return type\.</Expects>
|
||||
type EDF<'S> =
|
||||
abstract member Apply : int -> 'S
|
||||
type SomeEDF () =
|
||||
interface EDF<unit> with
|
||||
member this.Apply d =
|
||||
// [ERROR] The member 'Apply' does not have the correct type to override the corresponding abstract method.
|
||||
()
|
|
@ -1 +0,0 @@
|
|||
SOURCE=E_UnitGenericAbstractType1.fs # E_UnitGenericAbstractType1
|
|
@ -1,17 +0,0 @@
|
|||
// #Regression #Libraries #Async
|
||||
// Regression for FSHARP1.0:5969
|
||||
// Async.StartChild: error when wait async is executed more than once
|
||||
|
||||
module M
|
||||
|
||||
let a = async {
|
||||
let! a = Async.StartChild(
|
||||
async {
|
||||
do! Async.Sleep(500)
|
||||
return 27
|
||||
})
|
||||
let! result = Async.Parallel [ a; a; a; a ]
|
||||
return result
|
||||
} |> Async.RunSynchronously
|
||||
|
||||
exit 0
|
|
@ -1,25 +0,0 @@
|
|||
// #Regression #Libraries #Async
|
||||
// Regression for FSHARP1.0:5970
|
||||
// Async.StartChild: race in implementation of ResultCell in FSharp.Core
|
||||
|
||||
module M
|
||||
|
||||
let Join (a1: Async<'a>) (a2: Async<'b>) = async {
|
||||
let! task1 = a1 |> Async.StartChild
|
||||
let! task2 = a2 |> Async.StartChild
|
||||
|
||||
let! res1 = task1
|
||||
let! res2 = task2
|
||||
return (res1,res2) }
|
||||
|
||||
let r =
|
||||
try
|
||||
Async.RunSynchronously (Join (async { do! Async.Sleep(30)
|
||||
failwith "fail"
|
||||
return 3+3 })
|
||||
(async { do! Async.Sleep(30)
|
||||
return 2 + 2 } ))
|
||||
with _ ->
|
||||
(0,0)
|
||||
|
||||
exit 0
|
|
@ -1,78 +0,0 @@
|
|||
// #Regression #Libraries #Async
|
||||
// Regression test for FSHARP1.0:6086
|
||||
// This is a bit of duplication because the same/similar test
|
||||
// can also be found under the FSHARP suite. Yet, I like to have
|
||||
// it here...
|
||||
|
||||
// The interesting thing about this test is that is used to throw
|
||||
// an exception when executed on 64bit (FSharp.Core 2.0)
|
||||
|
||||
open Microsoft.FSharp.Control
|
||||
|
||||
type Color = Blue | Red | Yellow
|
||||
let complement = function
|
||||
| (Red, Yellow) | (Yellow, Red) -> Blue
|
||||
| (Red, Blue) | (Blue, Red) -> Yellow
|
||||
| (Yellow, Blue) | (Blue, Yellow) -> Red
|
||||
| (Blue, Blue) -> Blue
|
||||
| (Red, Red) -> Red
|
||||
| (Yellow, Yellow) -> Yellow
|
||||
|
||||
type Message = Color * AsyncReplyChannel<Color option>
|
||||
|
||||
let chameleon (meetingPlace : MailboxProcessor<Message>) initial =
|
||||
let rec loop c meets = async {
|
||||
let replyMessage = meetingPlace.PostAndReply(fun reply -> c, reply)
|
||||
match replyMessage with
|
||||
| Some(newColor) -> return! loop newColor (meets + 1)
|
||||
| None -> return meets
|
||||
}
|
||||
loop initial 0
|
||||
|
||||
let meetingPlace chams n = MailboxProcessor.Start(fun (processor : MailboxProcessor<Message>)->
|
||||
let rec fadingLoop total =
|
||||
async {
|
||||
if total <> 0 then
|
||||
let! (_, reply) = processor.Receive()
|
||||
reply.Reply None
|
||||
return! fadingLoop (total - 1)
|
||||
else
|
||||
printfn "Done"
|
||||
}
|
||||
let rec mainLoop curr =
|
||||
async {
|
||||
if (curr > 0) then
|
||||
let! (color1, reply1) = processor.Receive()
|
||||
let! (color2, reply2) = processor.Receive()
|
||||
let newColor = complement (color1, color2)
|
||||
reply1.Reply <| Some(newColor)
|
||||
reply2.Reply <| Some(newColor)
|
||||
return! mainLoop (curr - 1)
|
||||
else
|
||||
return! fadingLoop chams
|
||||
}
|
||||
mainLoop n
|
||||
)
|
||||
|
||||
open System
|
||||
open System.Diagnostics
|
||||
|
||||
[<EntryPoint>]
|
||||
let main(args : string[]) =
|
||||
printfn "CommandLine : %s" (String.concat ", " args)
|
||||
let meetings = if args.Length > 0 then Int32.Parse(args.[0]) else 100000
|
||||
|
||||
let colors = [Blue; Red; Yellow; Blue]
|
||||
let mp = meetingPlace (colors.Length) meetings
|
||||
let watch = Stopwatch.StartNew()
|
||||
let meets =
|
||||
colors
|
||||
|> List.map (chameleon mp)
|
||||
|> Async.Parallel
|
||||
|> Async.RunSynchronously
|
||||
watch.Stop()
|
||||
for meet in meets do
|
||||
printfn "%d" meet
|
||||
printfn "Total: %d in %O" (Seq.sum meets) (watch.Elapsed)
|
||||
0
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
// #Regression #Libraries #Async
|
||||
// Regression for FSHARP1.0:5971
|
||||
// Async.StartChild: ObjectDisposedException
|
||||
|
||||
module M
|
||||
|
||||
let shortVersion(args: string []) =
|
||||
let b = async {return 5} |> Async.StartChild
|
||||
printfn "%A" (b |> Async.RunSynchronously |> Async.RunSynchronously)
|
||||
(0)
|
||||
|
||||
exit 0
|
|
@ -1,19 +0,0 @@
|
|||
// #Regression #Libraries #Async
|
||||
// Regression for FSHARP1.0:5972
|
||||
// Async.StartChild: fails to install trampolines properly
|
||||
module M
|
||||
|
||||
let r =
|
||||
async {
|
||||
let! a = Async.StartChild(
|
||||
async {
|
||||
do! Async.Sleep(500)
|
||||
return 5
|
||||
}
|
||||
)
|
||||
let! b = a
|
||||
for i in 1..10000 do // 10000 > bindHijackLimit
|
||||
()
|
||||
} |> Async.RunSynchronously
|
||||
|
||||
exit 0
|
|
@ -1,6 +0,0 @@
|
|||
SOURCE=MailboxAsyncNoStackOverflow01.fs # MailboxAsyncNoStackOverflow01.fs
|
||||
|
||||
SOURCE=ExecuteAsyncMultipleTimes01.fs # ExecuteAsyncMultipleTimes01.fs
|
||||
SOURCE=JoiningStartChild01.fs # JoiningStartChild01.fs
|
||||
SOURCE=StartChildNoObjectDisposedException01.fs # StartChildNoObjectDisposedException01.fs
|
||||
SOURCE=StartChildTestTrampolineHijackLimit01.fs # StartChildTestTrampolineHijackLimit01.fs
|
|
@ -1,7 +0,0 @@
|
|||
// #Warnings
|
||||
//<Expects status="Error" span="(5,1)" id="FS0027">This value is not mutable. Consider using the mutable keyword, e.g. 'let mutable x = expression'.</Expects>
|
||||
|
||||
let x = 10
|
||||
x <- 20
|
||||
|
||||
exit 0
|
|
@ -1,14 +0,0 @@
|
|||
// #Warnings
|
||||
//<Expects status="Warning" span="(11,5)" id="FS0020">The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'.</Expects>
|
||||
|
||||
type MyClass(property1 : int) =
|
||||
member val Property2 = "" with get
|
||||
|
||||
let x = MyClass(1)
|
||||
let y = "hello"
|
||||
|
||||
let changeProperty() =
|
||||
x.Property2 = "22"
|
||||
y = "test"
|
||||
|
||||
exit 0
|
|
@ -1,9 +0,0 @@
|
|||
// #Warnings
|
||||
//<Expects status="Error" span="(7,9)" id="FS0193">Type constraint mismatch. The type</Expects>
|
||||
|
||||
open System.Collections.Generic
|
||||
|
||||
let orig = Dictionary<obj,obj>() :> IDictionary<obj,obj>
|
||||
let c = orig :> Dictionary<obj,obj>
|
||||
|
||||
exit 0
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче