Remove converter and use RepoToolset
This commit is contained in:
Родитель
4d5da9ebe3
Коммит
b6b238e08c
|
@ -15,27 +15,10 @@
|
|||
x64/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
nuget.exe
|
||||
.dotnet/
|
||||
|
||||
# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
|
||||
!packages/*/build/
|
||||
|
||||
# NuGet restore semaphore
|
||||
build/ToolsetPackages/toolsetpackages.semaphore
|
||||
|
||||
# NuGet package
|
||||
src/Tools/UploadNugetZip/*.zip
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
UnitTestResults.html
|
||||
|
||||
# NuGet V3 artifacts
|
||||
*-packages.config
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
project.lock.json
|
||||
# Per-user project properties
|
||||
launchSettings.json
|
||||
|
||||
*_i.c
|
||||
*_p.c
|
||||
|
@ -61,9 +44,6 @@ project.lock.json
|
|||
*.log
|
||||
*.scc
|
||||
|
||||
# Visual Studio cache files
|
||||
*.sln.ide/
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
|
@ -95,35 +75,6 @@ _TeamCity*
|
|||
*.ncrunch*
|
||||
.*crunch*.local.xml
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.Publish.xml
|
||||
|
||||
# NuGet Packages Directory
|
||||
packages/
|
||||
|
||||
# Windows Azure Build Output
|
||||
csx
|
||||
*.build.csdef
|
||||
|
||||
# Windows Store app package directory
|
||||
AppPackages/
|
||||
|
||||
# Others
|
||||
sql/
|
||||
*.Cache
|
||||
|
@ -136,26 +87,10 @@ ClientBin/
|
|||
*.pfx
|
||||
*.publishsettings
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file to a newer
|
||||
# Visual Studio version. Backup files are not needed, because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
|
||||
# SQL Server files
|
||||
App_Data/*.mdf
|
||||
App_Data/*.ldf
|
||||
|
||||
|
||||
#LightSwitch generated files
|
||||
GeneratedArtifacts/
|
||||
_Pvt_Extensions/
|
||||
ModelManifest.xml
|
||||
|
||||
# =========================
|
||||
# Windows detritus
|
||||
# =========================
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
@echo off
|
||||
powershell -ExecutionPolicy ByPass .\build\Scripts\Windows\Build.ps1 %*
|
||||
powershell -ExecutionPolicy ByPass .\build\Build.ps1 -restore -build %*
|
||||
exit /b %ErrorLevel%
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
@echo off
|
||||
powershell -ExecutionPolicy ByPass .\build\Build.ps1 -restore -build -test -sign -pack -ci %*
|
||||
exit /b %ErrorLevel%
|
|
@ -0,0 +1,17 @@
|
|||
<!-- Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -->
|
||||
<Project>
|
||||
<Import Project="build\NuGet.props"/>
|
||||
<Import Project="build\Versions.props"/>
|
||||
|
||||
<PropertyGroup>
|
||||
<Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
|
||||
|
||||
<RepoRoot>$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)\'))</RepoRoot>
|
||||
<SignToolDataPath>$(RepoRoot)build\SignToolData.json</SignToolDataPath>
|
||||
<VersionsPropsPath>$(RepoRoot)build\Versions.props</VersionsPropsPath>
|
||||
<RepoToolsetDir>$(NuGetPackageRoot)RoslynTools.Microsoft.RepoToolset\$(RoslynToolsMicrosoftRepoToolsetVersion)\tools\</RepoToolsetDir>
|
||||
|
||||
<RepositoryUrl>https://github.com/dotnet/symreader-portable</RepositoryUrl>
|
||||
<PackageProjectUrl>$(RepositoryUrl)</PackageProjectUrl>
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -1 +1,3 @@
|
|||
@call %~dp0build.cmd -skipBuild -skipTest %*
|
||||
@echo off
|
||||
powershell -ExecutionPolicy ByPass .\build\Build.ps1 -restore %*
|
||||
exit /b %ErrorLevel%
|
||||
|
|
|
@ -1,33 +1,13 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.25420.1
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26228.9
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.DiaSymReader.PortablePdb", "src\Microsoft.DiaSymReader.PortablePdb\Microsoft.DiaSymReader.PortablePdb.csproj", "{F83343BA-B4EA-451C-B6DB-5D645E6171BC}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.DiaSymReader.PortablePdb", "src\Microsoft.DiaSymReader.PortablePdb\Microsoft.DiaSymReader.PortablePdb.csproj", "{0B7BE784-8FBA-419D-82B2-377EA827CD62}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.DiaSymReader.PortablePdb.UnitTests", "src\Microsoft.DiaSymReader.PortablePdb.Tests\Microsoft.DiaSymReader.PortablePdb.UnitTests.csproj", "{DEB3D675-5A3C-46DA-8945-F2EFAB135EA0}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeployDesktopTestRuntime", "src\DeployDesktopTestRuntime\DeployDesktopTestRuntime.csproj", "{23683607-168A-4189-955E-908F0E80E60D}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeployCoreClrTestRuntime", "src\DeployCoreClrTestRuntime\DeployCoreClrTestRuntime.csproj", "{59BABFC3-C19B-4472-A93D-3DD3835BC219}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.DiaSymReader.Converter", "src\Microsoft.DiaSymReader.Converter\Microsoft.DiaSymReader.Converter.csproj", "{C0122B3F-86F0-4114-86F6-321535394C4E}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Pdb2Pdb", "src\Pdb2Pdb\Pdb2Pdb.csproj", "{C4C4BEEA-6E4C-4C03-841A-BB085AF9E097}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.DiaSymReader.Converter.UnitTests", "src\Microsoft.DiaSymReader.Converter.Tests\Microsoft.DiaSymReader.Converter.UnitTests.csproj", "{12421910-7B1F-457A-8958-84DE13734F9B}"
|
||||
EndProject
|
||||
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Microsoft.CodeAnalysis.Metadata", "src\Microsoft.CodeAnalysis.Metadata\Microsoft.CodeAnalysis.Metadata.shproj", "{D73ADF7D-2C1C-42AE-B2AB-EDC9497E4B71}"
|
||||
EndProject
|
||||
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Microsoft.CodeAnalysis.PooledObjects", "src\Microsoft.CodeAnalysis.PooledObjects\Microsoft.CodeAnalysis.PooledObjects.shproj", "{C1930979-C824-496B-A630-70F5369A636F}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.DiaSymReader.PortablePdb.UnitTests", "src\Microsoft.DiaSymReader.PortablePdb.Tests\Microsoft.DiaSymReader.PortablePdb.UnitTests.csproj", "{A6254A83-E3EF-47B8-967E-8D1455CE6905}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SharedMSBuildProjectFiles) = preSolution
|
||||
src\Microsoft.CodeAnalysis.Metadata\Microsoft.CodeAnalysis.Metadata.projitems*{c0122b3f-86f0-4114-86f6-321535394c4e}*SharedItemsImports = 4
|
||||
src\Microsoft.CodeAnalysis.PooledObjects\Microsoft.CodeAnalysis.PooledObjects.projitems*{c0122b3f-86f0-4114-86f6-321535394c4e}*SharedItemsImports = 4
|
||||
src\Microsoft.CodeAnalysis.PooledObjects\Microsoft.CodeAnalysis.PooledObjects.projitems*{c1930979-c824-496b-a630-70f5369a636f}*SharedItemsImports = 13
|
||||
src\Microsoft.CodeAnalysis.Metadata\Microsoft.CodeAnalysis.Metadata.projitems*{d73adf7d-2c1c-42ae-b2ab-edc9497e4b71}*SharedItemsImports = 13
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x64 = Debug|x64
|
||||
|
@ -35,62 +15,22 @@ Global
|
|||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{F83343BA-B4EA-451C-B6DB-5D645E6171BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F83343BA-B4EA-451C-B6DB-5D645E6171BC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F83343BA-B4EA-451C-B6DB-5D645E6171BC}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{F83343BA-B4EA-451C-B6DB-5D645E6171BC}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{F83343BA-B4EA-451C-B6DB-5D645E6171BC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F83343BA-B4EA-451C-B6DB-5D645E6171BC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F83343BA-B4EA-451C-B6DB-5D645E6171BC}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{F83343BA-B4EA-451C-B6DB-5D645E6171BC}.Release|x64.Build.0 = Release|Any CPU
|
||||
{DEB3D675-5A3C-46DA-8945-F2EFAB135EA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{DEB3D675-5A3C-46DA-8945-F2EFAB135EA0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{DEB3D675-5A3C-46DA-8945-F2EFAB135EA0}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{DEB3D675-5A3C-46DA-8945-F2EFAB135EA0}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{DEB3D675-5A3C-46DA-8945-F2EFAB135EA0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{DEB3D675-5A3C-46DA-8945-F2EFAB135EA0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{DEB3D675-5A3C-46DA-8945-F2EFAB135EA0}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{DEB3D675-5A3C-46DA-8945-F2EFAB135EA0}.Release|x64.Build.0 = Release|Any CPU
|
||||
{23683607-168A-4189-955E-908F0E80E60D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{23683607-168A-4189-955E-908F0E80E60D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{23683607-168A-4189-955E-908F0E80E60D}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{23683607-168A-4189-955E-908F0E80E60D}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{23683607-168A-4189-955E-908F0E80E60D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{23683607-168A-4189-955E-908F0E80E60D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{23683607-168A-4189-955E-908F0E80E60D}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{23683607-168A-4189-955E-908F0E80E60D}.Release|x64.Build.0 = Release|Any CPU
|
||||
{59BABFC3-C19B-4472-A93D-3DD3835BC219}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||
{59BABFC3-C19B-4472-A93D-3DD3835BC219}.Debug|Any CPU.Build.0 = Debug|x64
|
||||
{59BABFC3-C19B-4472-A93D-3DD3835BC219}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{59BABFC3-C19B-4472-A93D-3DD3835BC219}.Debug|x64.Build.0 = Debug|x64
|
||||
{59BABFC3-C19B-4472-A93D-3DD3835BC219}.Release|Any CPU.ActiveCfg = Release|x64
|
||||
{59BABFC3-C19B-4472-A93D-3DD3835BC219}.Release|Any CPU.Build.0 = Release|x64
|
||||
{59BABFC3-C19B-4472-A93D-3DD3835BC219}.Release|x64.ActiveCfg = Release|x64
|
||||
{59BABFC3-C19B-4472-A93D-3DD3835BC219}.Release|x64.Build.0 = Release|x64
|
||||
{C0122B3F-86F0-4114-86F6-321535394C4E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C0122B3F-86F0-4114-86F6-321535394C4E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C0122B3F-86F0-4114-86F6-321535394C4E}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{C0122B3F-86F0-4114-86F6-321535394C4E}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{C0122B3F-86F0-4114-86F6-321535394C4E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C0122B3F-86F0-4114-86F6-321535394C4E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C0122B3F-86F0-4114-86F6-321535394C4E}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{C0122B3F-86F0-4114-86F6-321535394C4E}.Release|x64.Build.0 = Release|Any CPU
|
||||
{C4C4BEEA-6E4C-4C03-841A-BB085AF9E097}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C4C4BEEA-6E4C-4C03-841A-BB085AF9E097}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C4C4BEEA-6E4C-4C03-841A-BB085AF9E097}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{C4C4BEEA-6E4C-4C03-841A-BB085AF9E097}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{C4C4BEEA-6E4C-4C03-841A-BB085AF9E097}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C4C4BEEA-6E4C-4C03-841A-BB085AF9E097}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C4C4BEEA-6E4C-4C03-841A-BB085AF9E097}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{C4C4BEEA-6E4C-4C03-841A-BB085AF9E097}.Release|x64.Build.0 = Release|Any CPU
|
||||
{12421910-7B1F-457A-8958-84DE13734F9B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{12421910-7B1F-457A-8958-84DE13734F9B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{12421910-7B1F-457A-8958-84DE13734F9B}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{12421910-7B1F-457A-8958-84DE13734F9B}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{12421910-7B1F-457A-8958-84DE13734F9B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{12421910-7B1F-457A-8958-84DE13734F9B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{12421910-7B1F-457A-8958-84DE13734F9B}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{12421910-7B1F-457A-8958-84DE13734F9B}.Release|x64.Build.0 = Release|Any CPU
|
||||
{0B7BE784-8FBA-419D-82B2-377EA827CD62}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0B7BE784-8FBA-419D-82B2-377EA827CD62}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0B7BE784-8FBA-419D-82B2-377EA827CD62}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{0B7BE784-8FBA-419D-82B2-377EA827CD62}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{0B7BE784-8FBA-419D-82B2-377EA827CD62}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0B7BE784-8FBA-419D-82B2-377EA827CD62}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{0B7BE784-8FBA-419D-82B2-377EA827CD62}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{0B7BE784-8FBA-419D-82B2-377EA827CD62}.Release|x64.Build.0 = Release|Any CPU
|
||||
{A6254A83-E3EF-47B8-967E-8D1455CE6905}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A6254A83-E3EF-47B8-967E-8D1455CE6905}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A6254A83-E3EF-47B8-967E-8D1455CE6905}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{A6254A83-E3EF-47B8-967E-8D1455CE6905}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{A6254A83-E3EF-47B8-967E-8D1455CE6905}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A6254A83-E3EF-47B8-967E-8D1455CE6905}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A6254A83-E3EF-47B8-967E-8D1455CE6905}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{A6254A83-E3EF-47B8-967E-8D1455CE6905}.Release|x64.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
4
Test.cmd
4
Test.cmd
|
@ -1 +1,3 @@
|
|||
@call %~dp0build.cmd -skipRestore -skipBuild %*
|
||||
@echo off
|
||||
powershell -ExecutionPolicy ByPass .\build\Build.ps1 -test %*
|
||||
exit /b %ErrorLevel%
|
|
@ -1,11 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<!--
|
||||
Builds packages and signs all artifacts.
|
||||
-->
|
||||
|
||||
<Target Name="Build">
|
||||
<MSBuild Projects="..\Toolset\MicroBuild.Sign.proj"/>
|
||||
<MSBuild Projects="..\Packaging\NuGet.proj"/>
|
||||
</Target>
|
||||
</Project>
|
|
@ -0,0 +1,10 @@
|
|||
<!-- Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<!-- Respect environment variable for the NuGet Packages Root if set; otherwise, use the current default location -->
|
||||
<NuGetPackageRoot Condition="'$(NuGetPackageRoot)' == ''">$(NUGET_PACKAGES)</NuGetPackageRoot>
|
||||
<NuGetPackageRoot Condition="'$(NuGetPackageRoot)' == '' AND '$(OS)' == 'Windows_NT'">$(UserProfile)\.nuget\packages\</NuGetPackageRoot>
|
||||
<NuGetPackageRoot Condition="'$(NuGetPackageRoot)' == '' AND '$(OS)' != 'Windows_NT'">$([System.Environment]::GetFolderPath(SpecialFolder.Personal))\.nuget\packages\</NuGetPackageRoot>
|
||||
<NuGetPackageRoot Condition="!HasTrailingSlash('$(NuGetPackageRoot)')">$(NuGetPackageRoot)\</NuGetPackageRoot>
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -1,18 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<!--
|
||||
Builds NuGet packages based on .nuspec files found in src\NuGet directory.
|
||||
-->
|
||||
<PropertyGroup>
|
||||
<OutDirName>Nuget</OutDirName>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="..\Targets\Settings.targets" />
|
||||
|
||||
<Target Name="Build">
|
||||
<Exec Command='"$(ToolsetCompilerPackageDir)\tools\csi.exe" "$(MSBuildProjectDirectory)\pack.csx" "$(NuGetVersion)" "$(MSBuildProjectDirectory)\..\..\src\NuGet" "$(OutDirBase)" "$(OutDir)"' />
|
||||
</Target>
|
||||
<Target Name="Clean">
|
||||
<RemoveDir Directories="$(OutDir)" />
|
||||
</Target>
|
||||
</Project>
|
|
@ -1,107 +0,0 @@
|
|||
#r "System.Xml.Linq"
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Xml.Linq;
|
||||
|
||||
var errors = new List<string>();
|
||||
|
||||
void ReportError(string message)
|
||||
{
|
||||
var color = Console.ForegroundColor;
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine(message);
|
||||
Console.ForegroundColor = color;
|
||||
}
|
||||
|
||||
void ReportSuccess(string message)
|
||||
{
|
||||
var color = Console.ForegroundColor;
|
||||
Console.ForegroundColor = ConsoleColor.Green;
|
||||
Console.WriteLine(message);
|
||||
Console.ForegroundColor = color;
|
||||
}
|
||||
|
||||
string usage = @"usage: pack.csx <version> <nuspec-dir> <binaries-dir> <output-directory>";
|
||||
|
||||
if (Args.Count() != 4)
|
||||
{
|
||||
Console.WriteLine(usage);
|
||||
Environment.Exit(1);
|
||||
}
|
||||
|
||||
var SolutionRoot = Path.GetFullPath(Path.Combine(ScriptRoot(), "../../"));
|
||||
string ScriptRoot([CallerFilePath]string path = "") => Path.GetDirectoryName(path);
|
||||
|
||||
// Strip trailing '\' characters because if the path is later passed on the
|
||||
// command line when surrounded by quotes (in case the path has spaces) some
|
||||
// utilities will consider the '\"' as an escape sequence for the end quote
|
||||
var BuildVersion = Args[0].Trim();
|
||||
var NuSpecDir = Path.GetFullPath(Args[1].Trim());
|
||||
var BinDir = Path.GetFullPath(Path.GetFullPath(Args[2]).Trim().TrimEnd('\\'));
|
||||
var OutDir = Path.GetFullPath(Path.GetFullPath(Args[3]).Trim().TrimEnd('\\'));
|
||||
|
||||
var doc = XDocument.Load(Path.Combine(SolutionRoot, "build/Targets/Dependencies.props"));
|
||||
XNamespace ns = @"http://schemas.microsoft.com/developer/msbuild/2003";
|
||||
|
||||
var dependencyVersions = from e in doc.Root.Descendants()
|
||||
where e.Name.LocalName.EndsWith("Version")
|
||||
select new { VariableName = e.Name.LocalName, Value = e.Value };
|
||||
|
||||
var commonArgs =
|
||||
$"-OutputDirectory \"{OutDir}\" " +
|
||||
$"-prop version=\"{BuildVersion}\" " +
|
||||
string.Join(" ", dependencyVersions.Select(d => $"-prop {d.VariableName}=\"{d.Value}\""));
|
||||
|
||||
Directory.CreateDirectory(OutDir);
|
||||
|
||||
int exitCode = 0;
|
||||
|
||||
foreach (var nuspec in Directory.EnumerateFiles(NuSpecDir, "*.nuspec", SearchOption.TopDirectoryOnly))
|
||||
{
|
||||
var libraryName = Path.GetFileNameWithoutExtension(nuspec);
|
||||
|
||||
var nugetArgs =
|
||||
$"pack \"{nuspec}\" " +
|
||||
$"-BasePath \"{Path.Combine(BinDir, libraryName)}\" " +
|
||||
commonArgs;
|
||||
|
||||
var nugetExePath = Path.GetFullPath(Path.Combine(SolutionRoot, "nuget.exe"));
|
||||
var p = new Process();
|
||||
p.StartInfo.FileName = nugetExePath;
|
||||
p.StartInfo.Arguments = nugetArgs;
|
||||
p.StartInfo.UseShellExecute = false;
|
||||
p.StartInfo.RedirectStandardError = true;
|
||||
p.StartInfo.RedirectStandardOutput = true;
|
||||
|
||||
Console.WriteLine($"{Environment.NewLine}Running: nuget.exe {nugetArgs}");
|
||||
|
||||
p.Start();
|
||||
p.WaitForExit();
|
||||
|
||||
if (p.ExitCode != 0)
|
||||
{
|
||||
exitCode = p.ExitCode;
|
||||
|
||||
var message = $"{nuspec}: error: {p.StandardError.ReadToEnd()}";
|
||||
errors.Add(message);
|
||||
ReportError(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
ReportSuccess(p.StandardOutput.ReadToEnd());
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var error in errors)
|
||||
{
|
||||
ReportError(error);
|
||||
}
|
||||
|
||||
return exitCode;
|
|
@ -1,447 +0,0 @@
|
|||
[CmdletBinding(PositionalBinding=$false)]
|
||||
Param(
|
||||
[switch] $clearPackageCache,
|
||||
[string] $configuration = "Debug",
|
||||
[string] $deployHive = "SymReaderPortable",
|
||||
[string] $locateVsApiVersion = "0.2.1-beta",
|
||||
[string] $msbuildVersion = "15.0",
|
||||
[string] $nugetVersion = "3.6.0-beta1",
|
||||
[switch] $official,
|
||||
[switch] $realSign,
|
||||
[string] $signToolVersion = "0.2.1-beta",
|
||||
[switch] $skipBuild,
|
||||
[switch] $skipDeploy,
|
||||
[switch] $skipRestore,
|
||||
[switch] $skipTest,
|
||||
[switch] $skipTest32,
|
||||
[switch] $skipTest64,
|
||||
[switch] $skipTestCore,
|
||||
[string] $target = "Build",
|
||||
[string] $testFilter = "*.UnitTests.dll",
|
||||
[string] $xUnitVersion = "2.2.0-beta3-build3402"
|
||||
)
|
||||
|
||||
set-strictmode -version 2.0
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
function Create-Directory([string[]] $path) {
|
||||
if (!(Test-Path -path $path)) {
|
||||
New-Item -path $path -force -itemType "Directory" | Out-Null
|
||||
}
|
||||
}
|
||||
|
||||
function Download-File([string] $address, [string] $fileName) {
|
||||
$webClient = New-Object -typeName "System.Net.WebClient"
|
||||
$webClient.DownloadFile($address, $fileName)
|
||||
}
|
||||
|
||||
function Get-ProductVersion([string[]] $path) {
|
||||
if (!(Test-Path -path $path)) {
|
||||
return ""
|
||||
}
|
||||
|
||||
$item = Get-Item -path $path
|
||||
return $item.VersionInfo.ProductVersion
|
||||
}
|
||||
|
||||
function Get-RegistryValue([string] $keyName, [string] $valueName) {
|
||||
$registryKey = Get-ItemProperty -path $keyName
|
||||
return $registryKey.$valueName
|
||||
}
|
||||
|
||||
function Locate-ArtifactsPath {
|
||||
$rootPath = Locate-RootPath
|
||||
$artifactsPath = Join-Path -path $rootPath -ChildPath "artifacts\$configuration\"
|
||||
|
||||
Create-Directory -path $artifactsPath
|
||||
return Resolve-Path -path $artifactsPath
|
||||
}
|
||||
|
||||
function Locate-BinariesPath {
|
||||
$artifactsPath = Locate-ArtifactsPath
|
||||
$binariesPath = Join-Path -path $artifactsPath -ChildPath "bin\"
|
||||
|
||||
Create-Directory -path $binariesPath
|
||||
return Resolve-Path -path $binariesPath
|
||||
}
|
||||
|
||||
function Locate-IntermediatesPath {
|
||||
$artifactsPath = Locate-ArtifactsPath
|
||||
$intermediatesPath = Join-Path -path $artifactsPath -ChildPath "obj\"
|
||||
|
||||
Create-Directory -path $intermediatesPath
|
||||
return Resolve-Path -path $intermediatesPath
|
||||
}
|
||||
|
||||
function Locate-LocateVsApi {
|
||||
$packagesPath = Locate-PackagesPath
|
||||
$locateVsApi = Join-Path -path $packagesPath -ChildPath "RoslynTools.Microsoft.LocateVS\$locateVsApiVersion\lib\net46\LocateVS.dll"
|
||||
|
||||
if (!(Test-Path -path $locateVsApi)) {
|
||||
throw "The specified LocateVS API version ($locateVsApiVersion) could not be located."
|
||||
}
|
||||
|
||||
return Resolve-Path -path $locateVsApi
|
||||
}
|
||||
|
||||
function Locate-MSBuild {
|
||||
$msbuildPath = Locate-MSBuildPath
|
||||
$msbuild = Join-Path -path $msbuildPath -childPath "MSBuild.exe"
|
||||
|
||||
if (!(Test-Path -path $msbuild)) {
|
||||
throw "The specified MSBuild version ($msbuildVersion) could not be located."
|
||||
}
|
||||
|
||||
return Resolve-Path -path $msbuild
|
||||
}
|
||||
|
||||
function Locate-MSBuildLogPath {
|
||||
$artifactsPath = Locate-ArtifactsPath
|
||||
$msbuildLogPath = Join-Path -path $artifactsPath -ChildPath "log\"
|
||||
|
||||
Create-Directory -path $msbuildLogPath
|
||||
return Resolve-Path -path $msbuildLogPath
|
||||
}
|
||||
|
||||
function Locate-MSBuildPath {
|
||||
$vsInstallPath = Locate-VsInstallPath
|
||||
$msbuildPath = Join-Path -path $vsInstallPath -childPath "MSBuild\$msbuildVersion\Bin"
|
||||
return Resolve-Path -path $msbuildPath
|
||||
}
|
||||
|
||||
function Locate-NuGet {
|
||||
$rootPath = Locate-RootPath
|
||||
$nuget = Join-Path -path $rootPath -childPath "nuget.exe"
|
||||
|
||||
if (Test-Path -path $nuget) {
|
||||
$currentVersion = Get-ProductVersion -path $nuget
|
||||
|
||||
if ($currentVersion.StartsWith($nugetVersion)) {
|
||||
return Resolve-Path -path $nuget
|
||||
}
|
||||
|
||||
Write-Host -object "The located version of NuGet ($currentVersion) is out of date. The specified version ($nugetVersion) will be downloaded instead."
|
||||
Remove-Item -path $nuget | Out-Null
|
||||
}
|
||||
|
||||
Download-File -address "https://dist.nuget.org/win-x86-commandline/v$nugetVersion/NuGet.exe" -fileName $nuget
|
||||
|
||||
if (!(Test-Path -path $nuget)) {
|
||||
throw "The specified NuGet version ($nugetVersion) could not be downloaded."
|
||||
}
|
||||
|
||||
return Resolve-Path -path $nuget
|
||||
}
|
||||
|
||||
function Locate-NuGetConfig {
|
||||
$rootPath = Locate-RootPath
|
||||
$nugetConfig = Join-Path -path $rootPath -childPath "nuget.config"
|
||||
return Resolve-Path -path $nugetConfig
|
||||
}
|
||||
|
||||
function Locate-PackagesPath {
|
||||
if ($env:NUGET_PACKAGES -eq $null) {
|
||||
$env:NUGET_PACKAGES = Join-Path -path $env:UserProfile -childPath ".nuget\packages\"
|
||||
}
|
||||
|
||||
$packagesPath = $env:NUGET_PACKAGES
|
||||
|
||||
Create-Directory -path $packagesPath
|
||||
return Resolve-Path -path $packagesPath
|
||||
}
|
||||
|
||||
function Locate-RootPath {
|
||||
$scriptPath = Locate-ScriptPath
|
||||
$rootPath = Join-Path -path $scriptPath -childPath "..\..\..\"
|
||||
return Resolve-Path -path $rootPath
|
||||
}
|
||||
|
||||
function Locate-ScriptPath {
|
||||
$myInvocation = Get-Variable -name "MyInvocation" -scope "Script"
|
||||
$scriptPath = Split-Path -path $myInvocation.Value.MyCommand.Definition -parent
|
||||
return Resolve-Path -path $scriptPath
|
||||
}
|
||||
|
||||
function Locate-SignConfig {
|
||||
$rootPath = Locate-RootPath
|
||||
$signConfig = Join-Path -path $rootPath -childPath "build\Signing\SignToolData.json"
|
||||
|
||||
if (!(Test-Path -path $signConfig)) {
|
||||
throw "The sign tool configuration file could not be located."
|
||||
}
|
||||
|
||||
return Resolve-Path -path $signConfig
|
||||
}
|
||||
|
||||
function Locate-SignTool {
|
||||
$packagesPath = Locate-PackagesPath
|
||||
$signTool = Join-Path -path $packagesPath -childPath "RoslynTools.Microsoft.SignTool\$signToolVersion\tools\SignTool.exe"
|
||||
|
||||
if (!(Test-Path -path $signTool)) {
|
||||
throw "The specified sign tool version ($signToolVersion) could not be located."
|
||||
}
|
||||
|
||||
return Resolve-Path -path $signTool
|
||||
}
|
||||
|
||||
function Locate-Solution {
|
||||
$rootPath = Locate-RootPath
|
||||
$solution = Join-Path -path $rootPath -childPath "*.sln"
|
||||
return Resolve-Path -path $solution
|
||||
}
|
||||
|
||||
function Locate-Toolset {
|
||||
$rootPath = Locate-RootPath
|
||||
$toolset = Join-Path -path $rootPath -childPath "build\Toolset\project.json"
|
||||
return Resolve-Path -path $toolset
|
||||
}
|
||||
|
||||
function Locate-VsInstallPath {
|
||||
$locateVsApi = Locate-LocateVsApi
|
||||
$requiredPackageIds = @()
|
||||
|
||||
$requiredPackageIds += "Microsoft.Component.MSBuild"
|
||||
$requiredPackageIds += "Microsoft.Net.Component.4.6.TargetingPack"
|
||||
$requiredPackageIds += "Microsoft.VisualStudio.Component.PortableLibrary"
|
||||
$requiredPackageIds += "Microsoft.VisualStudio.Component.Roslyn.Compiler"
|
||||
$requiredPackageIds += "Microsoft.VisualStudio.Component.VSSDK"
|
||||
|
||||
Add-Type -path $locateVsApi
|
||||
$vsInstallPath = [LocateVS.Instance]::GetInstallPath($msbuildVersion, $requiredPackageIds)
|
||||
return Resolve-Path -path $vsInstallPath
|
||||
}
|
||||
|
||||
function Locate-xUnit-x86 {
|
||||
$xUnitPath = Locate-xUnitPath
|
||||
$xUnit = Join-Path -path $xUnitPath -childPath "xunit.console.x86.exe"
|
||||
|
||||
if (!(Test-Path -path $xUnit)) {
|
||||
throw "The specified xUnit version ($xUnitVersion) could not be located."
|
||||
}
|
||||
|
||||
return Resolve-Path -path $xUnit
|
||||
}
|
||||
|
||||
function Locate-xUnit-x64 {
|
||||
$xUnitPath = Locate-xUnitPath
|
||||
$xUnit = Join-Path -path $xUnitPath -childPath "xunit.console.exe"
|
||||
|
||||
if (!(Test-Path -path $xUnit)) {
|
||||
throw "The specified xUnit version ($xUnitVersion) could not be located."
|
||||
}
|
||||
|
||||
return Resolve-Path -path $xUnit
|
||||
}
|
||||
|
||||
function Locate-xUnitPath {
|
||||
$packagesPath = Locate-PackagesPath
|
||||
$xUnitPath = Join-Path -path $packagesPath -childPath "xunit.runner.console\$xUnitVersion\tools\"
|
||||
|
||||
Create-Directory -path $xUnitPath
|
||||
return Resolve-Path -path $xUnitPath
|
||||
}
|
||||
|
||||
function Locate-xUnitLogPath {
|
||||
$artifactsPath = Locate-ArtifactsPath
|
||||
$xUnitLogPath = Join-Path -path $artifactsPath -ChildPath "log\"
|
||||
|
||||
Create-Directory -path $xUnitLogPath
|
||||
return Resolve-Path -path $xUnitLogPath
|
||||
}
|
||||
|
||||
function Locate-xUnitTestBinaries {
|
||||
$binariesPath = Locate-BinariesPath
|
||||
$binariesPath = Join-Path -path $binariesPath -childPath "DesktopTests"
|
||||
$testBinaries = Get-ChildItem -path $binariesPath -filter $testFilter -recurse -force
|
||||
|
||||
$xUnitTestBinaries = @()
|
||||
|
||||
foreach ($xUnitTestBinary in $testBinaries) {
|
||||
$xUnitTestBinaries += $xUnitTestBinary.FullName
|
||||
}
|
||||
|
||||
return $xUnitTestBinaries
|
||||
}
|
||||
|
||||
|
||||
function Perform-Build {
|
||||
Write-Host -object ""
|
||||
|
||||
if ($skipBuild) {
|
||||
Write-Host -object "Skipping build..."
|
||||
return
|
||||
}
|
||||
|
||||
$msbuild = Locate-MSBuild
|
||||
$msbuildLogPath = Locate-MSBuildLogPath
|
||||
|
||||
$deploy = (-not $skipDeploy)
|
||||
$solution = Locate-Solution
|
||||
|
||||
$solutionSummaryLog = Join-Path -path $msbuildLogPath -childPath "MSBuild.log"
|
||||
$solutionWarningLog = Join-Path -path $msbuildLogPath -childPath "MSBuild.wrn"
|
||||
$solutionFailureLog = Join-Path -path $msbuildLogPath -childPath "MSBuild.err"
|
||||
|
||||
|
||||
Write-Host -object "Starting solution build..."
|
||||
& $msbuild /t:$target /p:Configuration=$configuration /p:DeployExtension=$deploy /p:DeployHive=$deployHive /p:OfficialBuild=$official /m /tv:$msbuildVersion /v:m /flp1:Summary`;Verbosity=diagnostic`;Encoding=UTF-8`;LogFile=$solutionSummaryLog /flp2:WarningsOnly`;Verbosity=diagnostic`;Encoding=UTF-8`;LogFile=$solutionWarningLog /flp3:ErrorsOnly`;Verbosity=diagnostic`;Encoding=UTF-8`;LogFile=$solutionFailureLog /nr:false $solution
|
||||
|
||||
if ($lastExitCode -ne 0) {
|
||||
throw "The build failed with an exit code of '$lastExitCode'."
|
||||
}
|
||||
|
||||
Write-Host -object "The build completed successfully." -foregroundColor Green
|
||||
}
|
||||
|
||||
function Perform-RealSign {
|
||||
Write-Host -object ""
|
||||
|
||||
if ($skipBuild) {
|
||||
Write-Host -object "Skipping real signing..."
|
||||
return
|
||||
}
|
||||
|
||||
$binariesPath = Locate-BinariesPath
|
||||
$intermediatesPath = Locate-IntermediatesPath
|
||||
$packagesPath = Locate-PackagesPath
|
||||
$msbuild = Locate-MSBuild
|
||||
$signConfig = Locate-SignConfig
|
||||
$signTool = Locate-SignTool
|
||||
|
||||
if ($realSign) {
|
||||
Write-Host -object "Starting real signing..."
|
||||
& $signTool -intermediateOutputPath $intermediatesPath -msbuildPath $msbuild -nugetPackagesPath $packagesPath -config $signConfig $binariesPath
|
||||
}
|
||||
else {
|
||||
Write-Host -object "Starting test signing..."
|
||||
& $signTool -test -intermediateOutputPath $intermediatesPath -msbuildPath $msbuild -nugetPackagesPath $packagesPath -config $signConfig $binariesPath
|
||||
}
|
||||
|
||||
if ($lastExitCode -ne 0) {
|
||||
throw "The real sign task failed with an exit code of '$lastExitCode'."
|
||||
}
|
||||
|
||||
Write-Host -object "The real sign task completed successfully." -foregroundColor Green
|
||||
}
|
||||
|
||||
function Perform-Restore {
|
||||
Write-Host -object ""
|
||||
|
||||
if ($skipRestore) {
|
||||
Write-Host -object "Skipping restore..."
|
||||
return
|
||||
}
|
||||
|
||||
$nuget = Locate-NuGet
|
||||
$nugetConfig = Locate-NuGetConfig
|
||||
$packagesPath = Locate-PackagesPath
|
||||
$toolset = Locate-Toolset
|
||||
$solution = Locate-Solution
|
||||
|
||||
if ($clearPackageCache) {
|
||||
Write-Host -object "Clearing local package cache..."
|
||||
& $nuget locals all -clear
|
||||
}
|
||||
|
||||
Write-Host -object "Starting toolset restore..."
|
||||
& $nuget restore -packagesDirectory $packagesPath -msbuildVersion $msbuildVersion -verbosity quiet -nonInteractive -configFile $nugetConfig $toolset
|
||||
|
||||
if ($lastExitCode -ne 0) {
|
||||
throw "The restore failed with an exit code of '$lastExitCode'."
|
||||
}
|
||||
|
||||
Write-Host -object "Locating MSBuild install path..."
|
||||
$msbuildPath = Locate-MSBuildPath
|
||||
|
||||
Write-Host -object "Starting solution restore..."
|
||||
& $nuget restore -packagesDirectory $packagesPath -msbuildPath $msbuildPath -verbosity quiet -nonInteractive -configFile $nugetConfig $solution
|
||||
|
||||
if ($lastExitCode -ne 0) {
|
||||
throw "The restore failed with an exit code of '$lastExitCode'."
|
||||
}
|
||||
|
||||
Write-Host -object "The restore completed successfully." -foregroundColor Green
|
||||
}
|
||||
|
||||
function Perform-Test-x86 {
|
||||
Write-Host -object ""
|
||||
|
||||
if ($skipTest -or $skipTest32) {
|
||||
Write-Host -object "Skipping test x86..."
|
||||
return
|
||||
}
|
||||
|
||||
$xUnit = Locate-xUnit-x86
|
||||
$xUnitLogPath = Locate-xUnitLogPath
|
||||
$xUnitTestBinaries = @(Locate-xUnitTestBinaries)
|
||||
|
||||
$xUnitResultLog = Join-Path -path $xUnitLogPath -childPath "xUnit-x86.xml"
|
||||
|
||||
Write-Host "$xUnit $xUnitTestBinaries -xml $xUnitResultLog"
|
||||
& $xUnit @xUnitTestBinaries -xml $xUnitResultLog
|
||||
|
||||
if ($lastExitCode -ne 0) {
|
||||
throw "The test failed with an exit code of '$lastExitCode'."
|
||||
}
|
||||
|
||||
Write-Host -object "The test completed successfully." -foregroundColor Green
|
||||
}
|
||||
|
||||
function Perform-Test-x64 {
|
||||
Write-Host -object ""
|
||||
|
||||
if ($skipTest -or $skipTest64) {
|
||||
Write-Host -object "Skipping test x64..."
|
||||
return
|
||||
}
|
||||
|
||||
$xUnit = Locate-xUnit-x64
|
||||
$xUnitLogPath = Locate-xUnitLogPath
|
||||
$xUnitTestBinaries = @(Locate-xUnitTestBinaries)
|
||||
|
||||
$xUnitResultLog = Join-Path -path $xUnitLogPath -childPath "xUnit-x64.xml"
|
||||
|
||||
Write-Host "$xUnit $xUnitTestBinaries -xml $xUnitResultLog"
|
||||
& $xUnit @xUnitTestBinaries -xml $xUnitResultLog
|
||||
|
||||
if ($lastExitCode -ne 0) {
|
||||
throw "The test failed with an exit code of '$lastExitCode'."
|
||||
}
|
||||
|
||||
Write-Host -object "The test completed successfully." -foregroundColor Green
|
||||
}
|
||||
|
||||
function Perform-Test-Core {
|
||||
Write-Host -object ""
|
||||
|
||||
if ($skipTest -or $skipTestCore) {
|
||||
Write-Host -object "Skipping test Core..."
|
||||
return
|
||||
}
|
||||
|
||||
$binariesPath = Locate-BinariesPath
|
||||
$binariesPath = Join-Path $binariesPath "CoreTests"
|
||||
|
||||
$corerun = Join-Path $binariesPath "CoreRun.exe"
|
||||
$xUnit = Join-Path $binariesPath "xunit.console.netcore.exe"
|
||||
$xUnitLogPath = Locate-xUnitLogPath
|
||||
$xUnitTestBinaries = @(Locate-xUnitTestBinaries)
|
||||
|
||||
$xUnitResultLog = Join-Path -path $xUnitLogPath -childPath "xUnit-Core.xml"
|
||||
|
||||
Write-Host "$corerun $xUnit $xUnitTestBinaries -xml $xUnitResultLog"
|
||||
& $corerun $xUnit @xUnitTestBinaries -xml $xUnitResultLog
|
||||
|
||||
if ($lastExitCode -ne 0) {
|
||||
throw "The test failed with an exit code of '$lastExitCode'."
|
||||
}
|
||||
|
||||
Write-Host -object "The test completed successfully." -foregroundColor Green
|
||||
}
|
||||
|
||||
Perform-Restore
|
||||
Perform-Build
|
||||
Perform-RealSign
|
||||
Perform-Test-x86
|
||||
Perform-Test-x64
|
||||
Perform-Test-Core
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"sign": [
|
||||
{
|
||||
"certificate": "WindowsPhone623",
|
||||
"strongName": "MsSharedLib72",
|
||||
"values": [
|
||||
"Microsoft.DiaSymReader.PortablePdb/netstandard1.1/Microsoft.DiaSymReader.PortablePdb.dll"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
Двоичные данные
build/Signing/35MSSharedLib1024.snk
Двоичные данные
build/Signing/35MSSharedLib1024.snk
Двоичный файл не отображается.
|
@ -1,19 +0,0 @@
|
|||
{
|
||||
"sign": [
|
||||
{
|
||||
"certificate": "WindowsPhone623",
|
||||
"strongName": "MsSharedLib72",
|
||||
"values": [
|
||||
"Microsoft.DiaSymReader.PortablePdb/Microsoft.DiaSymReader.PortablePdb.dll"
|
||||
]
|
||||
},
|
||||
{
|
||||
"certificate": "Microsoft402",
|
||||
"strongName": "MsSharedLib72",
|
||||
"values": [
|
||||
"Microsoft.DiaSymReader.Converter/Microsoft.DiaSymReader.Converter.dll",
|
||||
"Pdb2Pdb/Pdb2Pdb.exe"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<!-- Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -->
|
||||
|
||||
<!-- ====================================================================================
|
||||
Strong Name Signing Settings
|
||||
==================================================================================== -->
|
||||
<PropertyGroup>
|
||||
<ShouldSignBuild Condition="'$(RealSignBuild)' == 'true' OR '$(SignType)' == 'real'">true</ShouldSignBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
<Choose>
|
||||
<When Condition="'$(SignAssembly)' == 'true'">
|
||||
<Choose>
|
||||
<When Condition="'$(ShouldSignBuild)' == 'true' OR '$(BuildingProject)' == 'false'">
|
||||
<!-- We are either real-signing or doing a design build, so we need to delay sign -->
|
||||
<PropertyGroup>
|
||||
<DelaySign>true</DelaySign>
|
||||
<PublicSign>false</PublicSign>
|
||||
</PropertyGroup>
|
||||
</When>
|
||||
|
||||
<Otherwise>
|
||||
<!-- We are not real-signing or doing a design build, so we need to public sign -->
|
||||
<PropertyGroup>
|
||||
<DelaySign>false</DelaySign>
|
||||
<PublicSign>true</PublicSign>
|
||||
</PropertyGroup>
|
||||
</Otherwise>
|
||||
</Choose>
|
||||
|
||||
<!-- Binaries are delay or public-signed with the MS key; later, the signing system will finish the strong-name signing. -->
|
||||
<PropertyGroup >
|
||||
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)\35MSSharedLib1024.snk</AssemblyOriginatorKeyFile>
|
||||
<PublicKey>0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9</PublicKey>
|
||||
<PublicKeyToken>31BF3856AD364E35</PublicKeyToken>
|
||||
</PropertyGroup>
|
||||
</When>
|
||||
</Choose>
|
||||
|
||||
<!-- ====================================================================================
|
||||
Build Flag Verification
|
||||
==================================================================================== -->
|
||||
<PropertyGroup>
|
||||
<PrepareForBuildDependsOn>$(PrepareForBuildDependsOn);VerifyBuildFlags</PrepareForBuildDependsOn>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="VerifyBuildFlags">
|
||||
<Error Condition="('$(RealSignBuild)' == 'true' OR '$(SignType)' == 'real') AND '$(BuildVersion)' == '42.42.42.42'"
|
||||
Text="Must specify a build version in order to real sign a build." />
|
||||
</Target>
|
||||
</Project>
|
|
@ -1,29 +0,0 @@
|
|||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<MicroBuildCoreVersion>0.2.0</MicroBuildCoreVersion>
|
||||
<RoslynToolsMicrosoftSignToolVersion>0.2.1-beta</RoslynToolsMicrosoftSignToolVersion>
|
||||
<ToolsetCompilerPackageVersion>2.0.0-rc3-61228-03</ToolsetCompilerPackageVersion>
|
||||
<XUnitConsoleRunnerPackageVersion>2.2.0-beta3-build3402</XUnitConsoleRunnerPackageVersion>
|
||||
|
||||
<!-- symreader -->
|
||||
<MicrosoftDiaSymReaderVersion>1.1.0</MicrosoftDiaSymReaderVersion>
|
||||
<MicrosoftDiaSymReaderNativeVersion>1.5.0-beta2-24728</MicrosoftDiaSymReaderNativeVersion>
|
||||
|
||||
<!-- CoreFX -->
|
||||
<SystemCollectionsVersion>4.3.0</SystemCollectionsVersion>
|
||||
<SystemCollectionsImmutableVersion>1.3.1</SystemCollectionsImmutableVersion>
|
||||
<SystemDiagnosticsDebugVersion>4.3.0</SystemDiagnosticsDebugVersion>
|
||||
<SystemGlobalizationVersion>4.3.0</SystemGlobalizationVersion>
|
||||
<SystemIOVersion>4.3.0</SystemIOVersion>
|
||||
<SystemIOFileSystemVersion>4.3.0</SystemIOFileSystemVersion>
|
||||
<SystemLinqVersion>4.3.0</SystemLinqVersion>
|
||||
<SystemReflectionVersion>4.3.0</SystemReflectionVersion>
|
||||
<SystemReflectionMetadataVersion>1.4.2</SystemReflectionMetadataVersion>
|
||||
<SystemReflectionPrimitivesVersion>4.3.0</SystemReflectionPrimitivesVersion>
|
||||
<SystemRuntimeVersion>4.3.0</SystemRuntimeVersion>
|
||||
<SystemRuntimeExtensionsVersion>4.3.0</SystemRuntimeExtensionsVersion>
|
||||
<SystemRuntimeInteropServicesVersion>4.3.0</SystemRuntimeInteropServicesVersion>
|
||||
<SystemTextEncodingVersion>4.3.0</SystemTextEncodingVersion>
|
||||
<SystemThreadingVersion>4.3.0</SystemThreadingVersion>
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -1,10 +0,0 @@
|
|||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<!-- Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -->
|
||||
|
||||
<!-- This file is imported by all projects at the end of the project files -->
|
||||
|
||||
<Import Project="..\Signing\StrongName.targets"/>
|
||||
<Import Project="..\Toolset\DefaultImports.targets"/>
|
||||
<Import Project="..\Toolset\GenerateAssemblyInfo.targets" />
|
||||
<Import Project="..\Toolset\GenerateInternalsVisibleTo.targets" />
|
||||
</Project>
|
|
@ -1,19 +0,0 @@
|
|||
<Project DefaultTargets="Build" InitialTargets="RestoreToolsetCheck" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<!-- Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -->
|
||||
|
||||
<Import Project="Version.props" />
|
||||
<Import Project="Dependencies.props" />
|
||||
<Import Project="..\Toolset\DefaultSettings.targets" />
|
||||
|
||||
<PropertyGroup>
|
||||
<!--
|
||||
Suppress generating TFA so that projects targeting Portable Profile7 can reference the dll
|
||||
(see https://github.com/dotnet/roslyn/issues/11067).
|
||||
-->
|
||||
<GenerateTargetFrameworkAttribute>false</GenerateTargetFrameworkAttribute>
|
||||
|
||||
<!-- To copy .dll.config and .exe.config files of the referenced projects to the output dir
|
||||
(see https://github.com/Microsoft/msbuild/issues/1307) -->
|
||||
<AllowedReferenceRelatedFileExtensions>$(AllowedReferenceRelatedFileExtensions);.dll.config;.exe.config</AllowedReferenceRelatedFileExtensions>
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -1,7 +0,0 @@
|
|||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<AssemblyVersion>1.2.0</AssemblyVersion>
|
||||
<NuGetMoniker></NuGetMoniker>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\Toolset\Version.props"/>
|
||||
</Project>
|
|
@ -0,0 +1,18 @@
|
|||
<!-- Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net462</TargetFramework>
|
||||
<!-- Output dir for restore artifacts -->
|
||||
<BaseIntermediateOutputPath>$(MSBuildThisProjectDirectory)..\..\artifacts\Toolset</BaseIntermediateOutputPath>
|
||||
</PropertyGroup>
|
||||
<Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />
|
||||
<ItemGroup>
|
||||
<PackageReference Include="RoslynTools.Microsoft.RepoToolset" Version="$(RoslynToolsMicrosoftRepoToolsetVersion)" />
|
||||
<PackageReference Include="RoslynTools.Microsoft.XUnitLogger" Version="$(RoslynToolsMicrosoftXUnitLoggerVersion)" />
|
||||
<PackageReference Include="RoslynTools.Microsoft.SignTool" Version="$(RoslynToolsMicrosoftSignToolVersion)" />
|
||||
<PackageReference Include="MicroBuild.Core" Version="$(MicroBuildCoreVersion)" />
|
||||
<PackageReference Include="MicroBuild.Core.Sentinel" Version="1.0.0" />
|
||||
<PackageReference Include="Microsoft.Net.Compilers" Version="$(MicrosoftNetCompilersVersion)" />
|
||||
</ItemGroup>
|
||||
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
|
||||
</Project>
|
|
@ -1,21 +0,0 @@
|
|||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<!-- Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -->
|
||||
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" Condition="'$(TargetFrameworkIdentifier)' == '.NETPortable'" />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" Condition="'$(TargetFrameworkIdentifier)' != '.NETPortable'" />
|
||||
|
||||
<Choose>
|
||||
<When Condition="'$(TargetFrameworkIdentifier)' == '.NETPortable' AND
|
||||
'$(TargetFrameworkVersion)' == 'v5.0'">
|
||||
<!-- Treat portable exes as CoreClr-targeting-exes -->
|
||||
<PropertyGroup Condition="'$(OutputType)' == 'Exe'">
|
||||
<NuGetTargetMoniker>.NETCoreApp,Version=v1.0</NuGetTargetMoniker>
|
||||
<BaseNuGetRuntimeIdentifier Condition="'$(OS)' == 'Windows_NT'">win7</BaseNuGetRuntimeIdentifier>
|
||||
</PropertyGroup>
|
||||
</When>
|
||||
</Choose>
|
||||
|
||||
<PropertyGroup>
|
||||
<DocumentationFile Condition="'$(DocumentationFile)' == '' AND '$(NoDocumentationFile)' != 'true' AND '$(AssemblyName)' != ''">$(OutputPath)\$(AssemblyName).xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -1,38 +0,0 @@
|
|||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<!-- Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -->
|
||||
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<Import Project="Toolset.targets" />
|
||||
|
||||
<!-- Common Settings -->
|
||||
|
||||
<PropertyGroup>
|
||||
<Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<SignAssembly Condition="'$(SignAssembly)' == ''">true</SignAssembly>
|
||||
<OverwriteReadOnlyFiles Condition="'$(OverwriteReadOnlyFiles)' == ''">true</OverwriteReadOnlyFiles>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<HighEntropyVA>true</HighEntropyVA>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- C# Specific Settings -->
|
||||
|
||||
<PropertyGroup>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<NoWarn>1591</NoWarn>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="Layout.props" />
|
||||
</Project>
|
|
@ -1,82 +0,0 @@
|
|||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<GeneratedAssemblyInfoFile>$(IntermediateOutputPath)GeneratedAssemblyInfo_$(BuildVersion)$(DefaultLanguageSourceExtension)</GeneratedAssemblyInfoFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<AssemblyVersionAttribute Include="System.Reflection.AssemblyCompanyAttribute">
|
||||
<_Parameter1>Microsoft Corporation</_Parameter1>
|
||||
</AssemblyVersionAttribute>
|
||||
<AssemblyInfoAttribute Include="System.Reflection.AssemblyConfigurationAttribute">
|
||||
<_Parameter1>$(Configuration)</_Parameter1>
|
||||
</AssemblyInfoAttribute>
|
||||
<AssemblyVersionAttribute Include="System.Reflection.AssemblyCopyrightAttribute">
|
||||
<_Parameter1>© Microsoft Corporation. All rights reserved.</_Parameter1>
|
||||
</AssemblyVersionAttribute>
|
||||
<AssemblyInfoAttribute Include="System.Reflection.AssemblyDefaultAliasAttribute">
|
||||
<_Parameter1>$(AssemblyName)</_Parameter1>
|
||||
</AssemblyInfoAttribute>
|
||||
<AssemblyVersionAttribute Include="System.Reflection.AssemblyFileVersionAttribute">
|
||||
<_Parameter1>$(BuildVersion)</_Parameter1>
|
||||
</AssemblyVersionAttribute>
|
||||
<AssemblyVersionAttribute Include="System.Reflection.AssemblyInformationalVersionAttribute">
|
||||
<_Parameter1>$(BuildVersion)</_Parameter1>
|
||||
</AssemblyVersionAttribute>
|
||||
<AssemblyVersionAttribute Include="System.Reflection.AssemblyVersionAttribute">
|
||||
<_Parameter1>$(AssemblyVersion)</_Parameter1>
|
||||
</AssemblyVersionAttribute>
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- It is extremely important to make CoreCompile depend on us, and not anything else.
|
||||
|
||||
This has to do with how XAML tasks compile a temporary assembly during the two markup compile
|
||||
passes.
|
||||
|
||||
Targets happen in this order:
|
||||
PrepareForBuild, PreBuildEvent, ResolveReferences, PrepareResources, ResolveKeySource, Compile, ...
|
||||
Here's the target dependency DAG that invokes markup compile:
|
||||
CoreBuild -> PrepareResources -> XamlMarkupCompilePass1, XamlMarkupCompilePass2.
|
||||
|
||||
As part of pass 1, we determine a list of .xaml files that reference types from the current
|
||||
assembly. For those, we can't emit BAML just yet because we can't reference the assembly being
|
||||
compiled. We pass this list to MarkupCompilePass2. As part of pass 2, we run the
|
||||
XamlTemporaryAssemblyGeneration target. It generates a special ***.tmp_proj project that is a
|
||||
trimmed down version of the current project's XML. It then spawns a new MSBuild process to build
|
||||
the tmp_proj with only a limited set of targets, specifically:
|
||||
|
||||
<Target Name="CompileTemporaryAssembly" DependsOnTargets="BuildOnlySettings;ResolveKeySource;_GenerateCompileInputs;CoreCompile" />
|
||||
|
||||
Hence, as part of building the temporary assembly the most important target being called is
|
||||
CoreCompile. Targets such as CoreBuild and Compile aren't even called there. Hence, if we predicate
|
||||
GenerateAssemblyInfoFile on Compile or CoreBuild, it won't get called when generating the
|
||||
assembly info file. As a result, we won't pass GeneratedAssemblyInfo_42.42.42.42.cs to the
|
||||
compiler when compiling the temporary assembly, and the temporary assembly will be generated
|
||||
with AssemblyVersion 0.0.0.0. Next, the unfortunate consequence is that the temp assembly will be
|
||||
used to compile the .baml files in MarkupCompilePass2, and the .baml files will end up referencing
|
||||
version 0.0.0.0 of the assembly, resulting in runtime assembly load failures.
|
||||
|
||||
This is why if we use CoreCompile below the correct version will end up in the temporary assembly
|
||||
and the .baml will be generated correctly eliminating the assembly load failures.
|
||||
|
||||
-->
|
||||
<CoreCompileDependsOn>GenerateAssemblyInfoFile;$(CoreCompileDependsOn)</CoreCompileDependsOn>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Depends on PrepareForBuild because the latter is responsible for calling MakeDir(IntermediateOutputPath).
|
||||
Without it, if we do a design-time build of a project (e.g. in Workspace.LoadSolution) immediately following
|
||||
a tfpt treeclean, WriteCodeFragment may fail because the obj folder doesn't even exist at that time. -->
|
||||
<Target Name="GenerateAssemblyInfoFile"
|
||||
Inputs="$(MSBuildThisFileFullPath)"
|
||||
Outputs="$(GeneratedAssemblyInfoFile)"
|
||||
DependsOnTargets="PrepareForBuild"
|
||||
Condition="('$(Language)' == 'C#' or '$(Language)' == 'VB') and '$(OS)' == 'Windows_NT' ">
|
||||
|
||||
<WriteCodeFragment AssemblyAttributes="@(AssemblyVersionAttribute)"
|
||||
Language="$(Language)"
|
||||
OutputFile="$(GeneratedAssemblyInfoFile)">
|
||||
<Output TaskParameter="OutputFile" ItemName="Compile" />
|
||||
<Output TaskParameter="OutputFile" ItemName="FileWrites" />
|
||||
</WriteCodeFragment>
|
||||
</Target>
|
||||
</Project>
|
|
@ -1,57 +0,0 @@
|
|||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<GeneratedInternalsVisibleToFile>$(IntermediateOutputPath)GeneratedInternalsVisibleTo$(DefaultLanguageSourceExtension)</GeneratedInternalsVisibleToFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<CompileDependsOn>GenerateInternalsVisibleToFile;$(CompileDependsOn)</CompileDependsOn>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemDefinitionGroup>
|
||||
<InternalsVisibleTo>
|
||||
<Visible>false</Visible>
|
||||
</InternalsVisibleTo>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(PublicKey)' != '' and '$(SignAssembly)' == 'True'">
|
||||
<InternalsVisibleToSuffix>, PublicKey=$(PublicKey)</InternalsVisibleToSuffix>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Dependency on PrepareForBuild is necessary so that we don't accidentally get ordered before it.
|
||||
We rely on PrepareForBuild to create the IntermediateOutputDirectory if it doesn't exist. -->
|
||||
<Target Name="GenerateInternalsVisibleToFile"
|
||||
Inputs="$(MSBuildThisFileFullPath);$(MSBuildProjectFile)"
|
||||
Outputs="$(GeneratedInternalsVisibleToFile)"
|
||||
DependsOnTargets="PrepareForBuild"
|
||||
Condition="'@(InternalsVisibleTo)' != ''">
|
||||
|
||||
<!--
|
||||
This is a slightly evil trick. What we have is a group of InternalsVisibleTo items which
|
||||
we need to convert to the items that the WriteCodeFragment expects. They look like this:
|
||||
|
||||
<InternalsVisibleTo Include="Foo" />
|
||||
|
||||
And need to convert it to:
|
||||
|
||||
<InternalsVisibleToAttribute Include="System.Runtime.CompilerServices.InternalsVisibleToAttribute">
|
||||
<_Parameter1>Foo</Parameter1>
|
||||
</InternalsVisibleToAttribute>
|
||||
|
||||
One way (although a bit evil) is to use the old CreateItem task. Since we use the well-defined
|
||||
"Identity" metadata on each of our itemgroups, MSBuild batching will take effect and this task
|
||||
will be invoked once for each InternalsVisibleTo item.
|
||||
-->
|
||||
<CreateItem Include="System.Runtime.CompilerServices.InternalsVisibleToAttribute"
|
||||
AdditionalMetadata="_Parameter1=%(InternalsVisibleTo.Identity)$(InternalsVisibleToSuffix)"
|
||||
Condition="'@(InternalsVisibleTo)' != ''">
|
||||
<Output TaskParameter="Include" ItemName="InternalsVisibleToAttribute" />
|
||||
</CreateItem>
|
||||
|
||||
<WriteCodeFragment AssemblyAttributes="@(InternalsVisibleToAttribute)"
|
||||
Language="$(Language)"
|
||||
OutputFile="$(GeneratedInternalsVisibleToFile)">
|
||||
<Output TaskParameter="OutputFile" ItemName="Compile" />
|
||||
<Output TaskParameter="OutputFile" ItemName="FileWrites" />
|
||||
</WriteCodeFragment>
|
||||
</Target>
|
||||
</Project>
|
|
@ -1,20 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<!--
|
||||
Properties describing the layout of the repo.
|
||||
-->
|
||||
|
||||
<PropertyGroup>
|
||||
<ArtifactsDir>$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)\..\..\artifacts'))</ArtifactsDir>
|
||||
<OutDirName Condition="'$(OutDirName)' == ''">$([System.IO.Path]::GetFileName('$(MSBuildProjectDirectory)'))</OutDirName>
|
||||
<OutDirBase>$(ArtifactsDir)\$(Configuration)\bin</OutDirBase>
|
||||
<OutDir Condition="'$(OutDir)' == ''">$(OutDirBase)\$(OutDirName)</OutDir>
|
||||
<IntermediateOutputPath Condition="'$(IntermediateOutputPath)' == ''">$(ArtifactsDir)\$(Configuration)\obj\$(OutDirName)</IntermediateOutputPath>
|
||||
<OutputPath>$(OutDir)</OutputPath>
|
||||
|
||||
<!-- Disable AppX packaging for the Roslyn source. Not setting this to false has the side effect
|
||||
that any builds of portable projects end up in a sub folder of $(OutDir). Search for this flag in
|
||||
Microsoft.Common.CurrentVersion.targets to see how it is consumed -->
|
||||
<WindowsAppContainer>false</WindowsAppContainer>
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -1,26 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
|
||||
</PropertyGroup>
|
||||
|
||||
<ImportGroup>
|
||||
<Import Project="..\Targets\Dependencies.props"/>
|
||||
<Import Project="Layout.props" />
|
||||
<Import Project="NuGet.props"/>
|
||||
<Import Project="$(NuGetPackageRoot)\MicroBuild.Core\$(MicroBuildCoreVersion)\build\MicroBuild.Core.props" />
|
||||
<Import Project="$(NuGetPackageRoot)\MicroBuild.Core\$(MicroBuildCoreVersion)\build\MicroBuild.Core.targets" />
|
||||
</ImportGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<SignToolArgs Include='-nugetPackagesPath "$(NugetPackageRoot)"' />
|
||||
<SignToolArgs Include='-intermediateOutputPath "$(IntermediateOutputPath)"' />
|
||||
<SignToolArgs Include='-msbuildPath "$(MSBuildBinPath)\msbuild.exe"' />
|
||||
<SignToolArgs Include='-config "$(MSBuildThisFileDirectory)..\Signing\SignToolData.json"' />
|
||||
<SignToolArgs Include='"$(OutDirBase)"' />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="Build">
|
||||
<Exec Command="$(NuGetPackageRoot)\RoslynTools.Microsoft.SignTool\$(RoslynToolsMicrosoftSignToolVersion)\tools\SignTool.exe @(SignToolArgs, ' ')" />
|
||||
</Target>
|
||||
</Project>
|
|
@ -1,17 +0,0 @@
|
|||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<!-- Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -->
|
||||
|
||||
<!-- ====================================================================================
|
||||
NuGet Restore Settings
|
||||
==================================================================================== -->
|
||||
<PropertyGroup>
|
||||
<ProjectDir>$(MSBuildThisFileDirectory)..\..\</ProjectDir>
|
||||
<NuGetToolPath>$(ProjectDir)\nuget.exe</NuGetToolPath>
|
||||
<ToolsetPackagesDir>$(ProjectDir)build\Toolset\</ToolsetPackagesDir>
|
||||
|
||||
<!-- Respect environment variable for the NuGet Packages Root if set; otherwise, use the current default location -->
|
||||
<NuGetPackageRoot Condition="'$(NuGetPackageRoot)' == ''">$(NUGET_PACKAGES)</NuGetPackageRoot>
|
||||
<NuGetPackageRoot Condition="'$(NuGetPackageRoot)' == '' AND '$(OS)' == 'Windows_NT'">$(UserProfile)\.nuget\packages</NuGetPackageRoot>
|
||||
<NuGetPackageRoot Condition="'$(NuGetPackageRoot)' == '' AND '$(OS)' != 'Windows_NT'">$([System.Environment]::GetFolderPath(SpecialFolder.Personal))\.nuget\packages</NuGetPackageRoot>
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -1,26 +0,0 @@
|
|||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<!-- Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -->
|
||||
|
||||
<!--
|
||||
|
||||
Requires the following properties to be set:
|
||||
ToolsetCompilerPackageVersion
|
||||
XUnitConsoleRunnerPackageVersion
|
||||
|
||||
-->
|
||||
|
||||
<Import Project="NuGet.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<ToolsetCompilerPackageDir>$(NuGetPackageRoot)\Microsoft.Net.Compilers\$(ToolsetCompilerPackageVersion)</ToolsetCompilerPackageDir>
|
||||
<ToolsetCompilerPropsFilePath>$(ToolsetCompilerPackageDir)\build\Microsoft.Net.Compilers.props</ToolsetCompilerPropsFilePath>
|
||||
<XUnitConsoleRunnerExeFilePath>$(NuGetPackageRoot)\xunit.runner.console\$(XUnitConsoleRunnerPackageVersion)\tools\xunit.console.x86.exe</XUnitConsoleRunnerExeFilePath>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="RestoreToolsetCheck" Condition="'$(BuildingProject)' == 'true'">
|
||||
<Error Text="Toolset packages have not been restored, run Restore.cmd before building"
|
||||
Condition="!Exists('$(ToolsetCompilerPropsFilePath)') or !Exists('$(XUnitConsoleRunnerExeFilePath)')" />
|
||||
</Target>
|
||||
|
||||
<Import Project="$(ToolsetCompilerPropsFilePath)" Condition="Exists('$(ToolsetCompilerPropsFilePath)')" />
|
||||
</Project>
|
|
@ -1,51 +0,0 @@
|
|||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<!-- Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -->
|
||||
|
||||
<!--
|
||||
|
||||
Requires the following properties to be set:
|
||||
AssemblyVersion
|
||||
NuGetMoniker (empty for release build)
|
||||
|
||||
Defines the following properties:
|
||||
BuildVersion
|
||||
NuGetVersion
|
||||
VsixVersion
|
||||
|
||||
-->
|
||||
|
||||
<Choose>
|
||||
<When Condition="$(BUILD_BUILDNUMBER) == ''">
|
||||
<PropertyGroup>
|
||||
<NuGetMoniker>dev</NuGetMoniker>
|
||||
<NuGetVersionSuffix>dev</NuGetVersionSuffix>
|
||||
<BuildVersion>$(AssemblyVersion).0</BuildVersion>
|
||||
<VsixVersion>$(AssemblyVersion).9000000</VsixVersion>
|
||||
</PropertyGroup>
|
||||
</When>
|
||||
|
||||
<Otherwise>
|
||||
<PropertyGroup>
|
||||
<BuildNumberFiveDigitDateStamp>$([MSBuild]::Subtract($(BUILD_BUILDNUMBER.Split('.')[0].Substring(3).Trim()), 8800))</BuildNumberFiveDigitDateStamp>
|
||||
<BuildNumberBuildOfTheDayPadded>$(BUILD_BUILDNUMBER.Split('.')[1].PadLeft(2,'0'))</BuildNumberBuildOfTheDayPadded>
|
||||
<NuGetVersionSuffix>$(NuGetMoniker)-$(BuildNumberFiveDigitDateStamp)-$(BuildNumberBuildOfTheDayPadded)</NuGetVersionSuffix>
|
||||
<BuildVersion>$(AssemblyVersion).$(BuildNumberFiveDigitDateStamp)</BuildVersion>
|
||||
<VsixVersion>$(AssemblyVersion).$(BuildNumberFiveDigitDateStamp)$(BuildNumberBuildOfTheDayPadded)</VsixVersion>
|
||||
</PropertyGroup>
|
||||
</Otherwise>
|
||||
</Choose>
|
||||
|
||||
<Choose>
|
||||
<When Condition="'$(NuGetMoniker)' == ''" >
|
||||
<PropertyGroup>
|
||||
<NuGetVersion>$(AssemblyVersion)</NuGetVersion>
|
||||
</PropertyGroup>
|
||||
</When>
|
||||
|
||||
<Otherwise>
|
||||
<PropertyGroup>
|
||||
<NuGetVersion>$(AssemblyVersion)-$(NuGetVersionSuffix)</NuGetVersion>
|
||||
</PropertyGroup>
|
||||
</Otherwise>
|
||||
</Choose>
|
||||
</Project>
|
|
@ -1,20 +0,0 @@
|
|||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<!-- Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -->
|
||||
|
||||
<PropertyGroup>
|
||||
<XUnitTestResultsDirectory>$(OutDir)\xUnitResults</XUnitTestResultsDirectory>
|
||||
<XUnitArguments>"$(OutDir)\$(AssemblyName).dll" -html "$(XUnitTestResultsDirectory)\$(AssemblyName).html" -noshadow</XUnitArguments>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="Test" DependsOnTargets="Build">
|
||||
<MakeDir Directories="$(XUnitTestResultsDirectory)" />
|
||||
<Exec Command=""$(XUnitConsoleRunnerExeFilePath)" $(XUnitArguments)" />
|
||||
</Target>
|
||||
|
||||
<PropertyGroup>
|
||||
<StartAction Condition="'$(StartActions)' == ''">Program</StartAction>
|
||||
<StartProgram Condition="'$(StartProgram)' == ''">$(XUnitConsoleRunnerExeFilePath)</StartProgram>
|
||||
<StartArguments Condition="'$(StartArguments)' == ''">$(XUnitArguments)</StartArguments>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
|
@ -1,17 +0,0 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"MicroBuild.Core": "0.2.0",
|
||||
"MicroBuild.Core.Sentinel": "1.0.0",
|
||||
"MicroBuild.Plugins.SwixBuild": "1.0.101",
|
||||
"Microsoft.Net.Compilers": "2.0.0-rc3-61228-03",
|
||||
"RoslynTools.Microsoft.LocateVS": "0.2.1-beta",
|
||||
"RoslynTools.Microsoft.SignTool": "0.2.1-beta",
|
||||
"xunit.runner.console": "2.2.0-beta3-build3402"
|
||||
},
|
||||
"frameworks": {
|
||||
"net461": {}
|
||||
},
|
||||
"runtimes": {
|
||||
"win": {}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
<!-- Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<!-- This repo version -->
|
||||
<VersionBase>1.2.0</VersionBase>
|
||||
<PreReleaseVersionLabel>beta1</PreReleaseVersionLabel>
|
||||
|
||||
<!-- Toolset -->
|
||||
<RoslynToolsMicrosoftRepoToolsetVersion>1.0.0-alpha14</RoslynToolsMicrosoftRepoToolsetVersion>
|
||||
<RoslynToolsMicrosoftXUnitLoggerVersion>1.0.0-alpha1</RoslynToolsMicrosoftXUnitLoggerVersion>
|
||||
<RoslynToolsMicrosoftSignToolVersion>0.3.2-beta</RoslynToolsMicrosoftSignToolVersion>
|
||||
<DotNetCliVersion>1.0.0-rc4-004777</DotNetCliVersion>
|
||||
<MicroBuildCoreVersion>0.2.0</MicroBuildCoreVersion>
|
||||
<MicroBuildPluginsSwixBuildVersion>1.0.101</MicroBuildPluginsSwixBuildVersion>
|
||||
<MicrosoftNetCompilersVersion>2.0.1</MicrosoftNetCompilersVersion>
|
||||
|
||||
<!-- Tests -->
|
||||
<MicrosoftNETTestSdkVersion>15.0.0-preview-20170125-04</MicrosoftNETTestSdkVersion>
|
||||
<XUnitVersion>2.2.0-beta4-build3444</XUnitVersion>
|
||||
<XUnitRunnerVisualStudioVersion>2.2.0-beta4-build1194</XUnitRunnerVisualStudioVersion>
|
||||
|
||||
<!-- symreader -->
|
||||
<MicrosoftDiaSymReaderVersion>1.1.0</MicrosoftDiaSymReaderVersion>
|
||||
<MicrosoftDiaSymReaderNativeVersion>1.5.0</MicrosoftDiaSymReaderNativeVersion>
|
||||
|
||||
<!-- CoreFX -->
|
||||
<SystemCollectionsImmutableVersion>1.3.1</SystemCollectionsImmutableVersion>
|
||||
<SystemReflectionMetadataVersion>1.4.2</SystemReflectionMetadataVersion>
|
||||
<SystemValueTupleVersion>4.3.0</SystemValueTupleVersion>
|
||||
|
||||
<!-- Needs these to build a custom nuspec -->
|
||||
<SystemCollectionsVersion>4.3.0</SystemCollectionsVersion>
|
||||
<SystemDiagnosticsDebugVersion>4.3.0</SystemDiagnosticsDebugVersion>
|
||||
<SystemGlobalizationVersion>4.3.0</SystemGlobalizationVersion>
|
||||
<SystemIOVersion>4.3.0</SystemIOVersion>
|
||||
<SystemLinqVersion>4.3.0</SystemLinqVersion>
|
||||
<SystemReflectionVersion>4.3.0</SystemReflectionVersion>
|
||||
<SystemReflectionPrimitivesVersion>4.3.0</SystemReflectionPrimitivesVersion>
|
||||
<SystemRuntimeVersion>4.3.0</SystemRuntimeVersion>
|
||||
<SystemRuntimeExtensionsVersion>4.3.0</SystemRuntimeExtensionsVersion>
|
||||
<SystemRuntimeInteropServicesVersion>4.3.0</SystemRuntimeInteropServicesVersion>
|
||||
<SystemTextEncodingVersion>4.3.0</SystemTextEncodingVersion>
|
||||
<SystemThreadingVersion>4.3.0</SystemThreadingVersion>
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -0,0 +1,25 @@
|
|||
<Project DefaultTargets="Build" TreatAsLocalProperty="SolutionPath">
|
||||
<!--
|
||||
Optional parameters:
|
||||
SolutionPath Path to the solution to build
|
||||
Configuration Build configuration: "Debug", "Release", etc.
|
||||
CIBuild "true" if building on CI server
|
||||
Restore "true" to restore toolset and solution
|
||||
Build "true" to build solution
|
||||
Test "true" to run tests
|
||||
Sign "true" to sign built binaries
|
||||
Pack "true" to build NuGet packages
|
||||
-->
|
||||
<PropertyGroup>
|
||||
<SolutionPath Condition="'$(SolutionPath)' == ''">$(MSBuildThisFileDirectory)..\SymReaderPortable.sln</SolutionPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="..\Directory.build.props"/>
|
||||
|
||||
<Target Name="Build">
|
||||
<MSBuild Projects="Toolset.proj" Targets="Restore" Condition="'$(Restore)' == 'true'"/>
|
||||
|
||||
<MSBuild Projects="$(RepoToolsetDir)Build.proj"
|
||||
Properties="SolutionPath=$(SolutionPath);Configuration=$(Configuration);CIBuild=$(CIBuild);Restore=$(Restore);Build=$(Build);Test=$(Test);Sign=$(Sign);Pack=$(Pack)" />
|
||||
</Target>
|
||||
</Project>
|
|
@ -0,0 +1,75 @@
|
|||
[CmdletBinding(PositionalBinding=$false)]
|
||||
Param(
|
||||
[string] $configuration = "Debug",
|
||||
[string] $solution = "",
|
||||
[string] $verbosity = "normal",
|
||||
[switch] $restore,
|
||||
[switch] $build,
|
||||
[switch] $test,
|
||||
[switch] $sign,
|
||||
[switch] $pack,
|
||||
[switch] $ci
|
||||
)
|
||||
|
||||
set-strictmode -version 2.0
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$RepoRoot = Join-Path $PSScriptRoot "..\"
|
||||
$DotNetRoot = Join-Path $RepoRoot ".dotnet"
|
||||
$DotNetExe = Join-Path $DotNetRoot "dotnet.exe"
|
||||
$BuildProj = Join-Path $PSScriptRoot "build.proj"
|
||||
$DependenciesProps = Join-Path $PSScriptRoot "Versions.props"
|
||||
$ArtifactsDir = Join-Path $RepoRoot "artifacts"
|
||||
$LogDir = Join-Path $ArtifactsDir "log"
|
||||
$TempDir = Join-Path (Join-Path $ArtifactsDir $configuration) "tmp"
|
||||
|
||||
function Create-Directory([string[]] $path) {
|
||||
if (!(Test-Path -path $path)) {
|
||||
New-Item -path $path -force -itemType "Directory" | Out-Null
|
||||
}
|
||||
}
|
||||
|
||||
function GetDotNetCliVersion {
|
||||
[xml]$xml = Get-Content $DependenciesProps
|
||||
return $xml.Project.PropertyGroup.DotNetCliVersion
|
||||
}
|
||||
|
||||
function InstallDotNetCli {
|
||||
|
||||
Create-Directory $DotNetRoot
|
||||
$dotnetCliVersion = GetDotNetCliVersion
|
||||
|
||||
$installScript="https://raw.githubusercontent.com/dotnet/cli/rel/1.0.0/scripts/obtain/dotnet-install.ps1"
|
||||
Invoke-WebRequest $installScript -OutFile "$DotNetRoot\dotnet-install.ps1"
|
||||
|
||||
& "$DotNetRoot\dotnet-install.ps1" -Version $dotnetCliVersion -InstallDir $DotNetRoot
|
||||
if ($lastExitCode -ne 0) {
|
||||
throw "Failed to install dotnet cli (exit code '$lastExitCode')."
|
||||
}
|
||||
}
|
||||
|
||||
function Build {
|
||||
$summaryLog = Join-Path $LogDir "Build.log"
|
||||
$warningLog = Join-Path $LogDir "Build.wrn"
|
||||
$errorLog = Join-Path $LogDir "Build.err"
|
||||
|
||||
Create-Directory($logDir)
|
||||
|
||||
& $DotNetExe msbuild $BuildProj /p:Configuration=$configuration /p:SolutionPath=$solution /p:Restore=$restore /p:Build=$build /p:Test=$test /p:Sign=$sign /p:Pack=$pack /p:CIBuild=$ci /v:$verbosity /flp1:Summary`;Verbosity=diagnostic`;Encoding=UTF-8`;LogFile=$summaryLog /flp2:WarningsOnly`;Verbosity=diagnostic`;Encoding=UTF-8`;LogFile=$warningLog /flp3:ErrorsOnly`;Verbosity=diagnostic`;Encoding=UTF-8`;LogFile=$errorLog
|
||||
|
||||
if ($lastExitCode -ne 0) {
|
||||
throw "Build failed (exit code '$lastExitCode')."
|
||||
}
|
||||
}
|
||||
|
||||
if ($ci) {
|
||||
Create-Directory $TempDir
|
||||
$env:TEMP = $TempDir
|
||||
$env:TMP = $TempDir
|
||||
}
|
||||
|
||||
if ($restore) {
|
||||
InstallDotNetCli
|
||||
}
|
||||
|
||||
Build
|
180
netci.groovy
180
netci.groovy
|
@ -3,8 +3,8 @@
|
|||
|
||||
import jobs.generation.Utilities;
|
||||
|
||||
static getJobName(def opsysName, def configName, def testName) {
|
||||
return "${opsysName}_${configName}_${testName}"
|
||||
static getJobName(def opsysName, def configName) {
|
||||
return "${opsysName}_${configName}"
|
||||
}
|
||||
|
||||
static addArchival(def job, def filesToArchive, def filesToExclude) {
|
||||
|
@ -14,133 +14,28 @@ static addArchival(def job, def filesToArchive, def filesToExclude) {
|
|||
Utilities.addArchival(job, filesToArchive, filesToExclude, doNotFailIfNothingArchived, archiveOnlyIfSuccessful)
|
||||
}
|
||||
|
||||
static addGithubPRTriggerForBranch(def job, def branchName, def jobName, def testName) {
|
||||
static addGithubPRTriggerForBranch(def job, def branchName, def jobName) {
|
||||
def prContext = "prtest/${jobName.replace('_', '/')}"
|
||||
def triggerPhrase = "(?i)^\\s*(@?dotnet-bot\\s+)?(re)?test\\s+(${prContext})(\\s+please)?\\s*\$"
|
||||
def triggerOnPhraseOnly = (testName != 'build')
|
||||
def triggerOnPhraseOnly = false
|
||||
|
||||
Utilities.addGithubPRTriggerForBranch(job, branchName, prContext, triggerPhrase, triggerOnPhraseOnly)
|
||||
}
|
||||
|
||||
static addGithubPRCommitStatusForBranch(def job, def branchName, def jobName, def testName) {
|
||||
def prContext = "prtest/${jobName.replace('_', '/')}"
|
||||
|
||||
job.with {
|
||||
wrappers {
|
||||
downstreamCommitStatus {
|
||||
context(prContext)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static addXUnitDotNETResults(def job, def configName) {
|
||||
def resultFilePattern = "**/artifacts/${configName}/log/xUnit-*.xml"
|
||||
def resultFilePattern = "**/artifacts/${configName}/TestResults/*.xml"
|
||||
def skipIfNoTestFiles = false
|
||||
|
||||
|
||||
Utilities.addXUnitDotNETResults(job, resultFilePattern, skipIfNoTestFiles)
|
||||
}
|
||||
|
||||
static addExtendedEmailPublisher(def job) {
|
||||
job.with {
|
||||
publishers {
|
||||
extendedEmail {
|
||||
defaultContent('$DEFAULT_CONTENT')
|
||||
defaultSubject('$DEFAULT_SUBJECT')
|
||||
recipientList('$DEFAULT_RECIPIENTS, cc:tomat@microsoft.com')
|
||||
triggers {
|
||||
aborted {
|
||||
content('$PROJECT_DEFAULT_CONTENT')
|
||||
sendTo {
|
||||
culprits()
|
||||
developers()
|
||||
recipientList()
|
||||
requester()
|
||||
}
|
||||
subject('$PROJECT_DEFAULT_SUBJECT')
|
||||
}
|
||||
failure {
|
||||
content('$PROJECT_DEFAULT_CONTENT')
|
||||
sendTo {
|
||||
culprits()
|
||||
developers()
|
||||
recipientList()
|
||||
requester()
|
||||
}
|
||||
subject('$PROJECT_DEFAULT_SUBJECT')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static addBuildSteps(def job, def projectName, def opsysName, def configName, def isPR) {
|
||||
def unit32JobName = getJobName(opsysName, configName, 'unit32')
|
||||
def unit32FullJobName = Utilities.getFullJobName(projectName, unit32JobName, isPR)
|
||||
|
||||
def unit64JobName = getJobName(opsysName, configName, 'unit64')
|
||||
def unit64FullJobName = Utilities.getFullJobName(projectName, unit64JobName, isPR)
|
||||
|
||||
def coreJobName = getJobName(opsysName, configName, 'core')
|
||||
def coreFullJobName = Utilities.getFullJobName(projectName, coreJobName, isPR)
|
||||
|
||||
def downstreamFullJobNames = "${unit32FullJobName}, ${unit64FullJobName}, ${coreFullJobName}"
|
||||
|
||||
def officialSwitch = ''
|
||||
|
||||
if (!isPR) {
|
||||
officialSwitch = '-Official'
|
||||
}
|
||||
|
||||
job.with {
|
||||
steps {
|
||||
batchFile("""set TEMP=%WORKSPACE%\\artifacts\\${configName}\\tmp
|
||||
mkdir %TEMP%
|
||||
set TMP=%TEMP%
|
||||
.\\Build.cmd -Configuration ${configName} -msbuildVersion '15.0' ${officialSwitch} -SkipDeploy -SkipTest
|
||||
""")
|
||||
publishers {
|
||||
downstreamParameterized {
|
||||
trigger(downstreamFullJobNames) {
|
||||
condition('UNSTABLE_OR_BETTER')
|
||||
parameters {
|
||||
currentBuild()
|
||||
gitRevision()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static addTestSteps(def job, def projectName, def opsysName, def configName, def testName, def isPR, def filesToArchive, def filesToExclude) {
|
||||
def buildJobName = getJobName(opsysName, configName, 'build')
|
||||
def buildJobName = getJobName(opsysName, configName)
|
||||
def buildFullJobName = Utilities.getFullJobName(projectName, buildJobName, isPR)
|
||||
|
||||
def officialSwitch = ''
|
||||
|
||||
if (!isPR) {
|
||||
officialSwitch = '-Official'
|
||||
}
|
||||
|
||||
job.with {
|
||||
steps {
|
||||
copyArtifacts(buildFullJobName) {
|
||||
includePatterns(filesToArchive)
|
||||
excludePatterns(filesToExclude)
|
||||
buildSelector {
|
||||
upstreamBuild {
|
||||
fallbackToLastSuccessful(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
batchFile("""set TEMP=%WORKSPACE%\\artifacts\\${configName}\\tmp
|
||||
mkdir %TEMP%
|
||||
set TMP=%TEMP%
|
||||
.\\Build.cmd -Configuration ${configName} -msbuildVersion '15.0' ${officialSwitch} -SkipBuild ${testName == 'unit32' ? '-SkipTest64 -SkipTestCore' : (testName == 'core' ? '-SkipTest32 -SkipTest64' : '-SkipTest32 -SkipTestCore')}
|
||||
""")
|
||||
batchFile(""".\\CIBuild.cmd -configuration ${configName}""")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -148,50 +43,31 @@ set TMP=%TEMP%
|
|||
[true, false].each { isPR ->
|
||||
['windows'].each { opsysName ->
|
||||
['debug', 'release'].each { configName ->
|
||||
['build', 'unit32', 'unit64', 'core'].each { testName ->
|
||||
def projectName = GithubProject
|
||||
def projectName = GithubProject
|
||||
|
||||
def branchName = GithubBranchName
|
||||
def branchName = GithubBranchName
|
||||
|
||||
def filesToArchive = "**/artifacts/${configName}/**"
|
||||
def filesToExclude = "**/artifacts/${configName}/obj/**"
|
||||
def filesToArchive = "**/artifacts/${configName}/**"
|
||||
def filesToExclude = "**/artifacts/${configName}/obj/**"
|
||||
|
||||
def jobName = getJobName(opsysName, configName, testName)
|
||||
def fullJobName = Utilities.getFullJobName(projectName, jobName, isPR)
|
||||
def myJob = job(fullJobName)
|
||||
def jobName = getJobName(opsysName, configName)
|
||||
def fullJobName = Utilities.getFullJobName(projectName, jobName, isPR)
|
||||
def myJob = job(fullJobName)
|
||||
|
||||
Utilities.standardJobSetup(myJob, projectName, isPR, "*/${branchName}")
|
||||
Utilities.standardJobSetup(myJob, projectName, isPR, "*/${branchName}")
|
||||
|
||||
if (testName == 'build') {
|
||||
if (isPR) {
|
||||
addGithubPRTriggerForBranch(myJob, branchName, jobName, testName)
|
||||
} else {
|
||||
Utilities.addGithubPushTrigger(myJob)
|
||||
}
|
||||
} else {
|
||||
if (isPR) {
|
||||
addGithubPRCommitStatusForBranch(myJob, branchName, jobName, testName)
|
||||
}
|
||||
}
|
||||
|
||||
addArchival(myJob, filesToArchive, filesToExclude)
|
||||
|
||||
if (testName != 'build') {
|
||||
addXUnitDotNETResults(myJob, configName)
|
||||
}
|
||||
|
||||
Utilities.setMachineAffinity(myJob, 'Windows_NT', 'latest-or-auto-dev15-rc')
|
||||
|
||||
if (!isPR) {
|
||||
addExtendedEmailPublisher(myJob)
|
||||
}
|
||||
|
||||
if (testName == 'build') {
|
||||
addBuildSteps(myJob, projectName, opsysName, configName, isPR)
|
||||
} else {
|
||||
addTestSteps(myJob, projectName, opsysName, configName, testName, isPR, filesToArchive, filesToExclude)
|
||||
}
|
||||
if (isPR) {
|
||||
addGithubPRTriggerForBranch(myJob, branchName, jobName)
|
||||
} else {
|
||||
Utilities.addGithubPushTrigger(myJob)
|
||||
}
|
||||
|
||||
addArchival(myJob, filesToArchive, filesToExclude)
|
||||
addXUnitDotNETResults(myJob, configName)
|
||||
|
||||
Utilities.setMachineAffinity(myJob, 'Windows_NT', 'latest-or-auto-dev15-rc')
|
||||
|
||||
addBuildSteps(myJob, projectName, opsysName, configName, isPR)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
12
repo.json
12
repo.json
|
@ -1,12 +0,0 @@
|
|||
{
|
||||
"generate": {
|
||||
"msbuild": {
|
||||
"path": "build\\Targets\\Dependencies.props",
|
||||
"values": [
|
||||
"Microsoft.Dia.*",
|
||||
"System.*",
|
||||
"xunit",
|
||||
]
|
||||
}
|
||||
},
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
class C { public static void Main() { } }
|
|
@ -1,44 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -->
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<OutDirName>CoreTests</OutDirName>
|
||||
</PropertyGroup>
|
||||
<ImportGroup Label="Settings">
|
||||
<Import Project="..\..\build\Targets\Settings.targets" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">x64</Platform>
|
||||
<ProjectGuid>{59BABFC3-C19B-4472-A93D-3DD3835BC219}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<AssemblyName>DeployCoreClrTestRuntime_DoNotUse</AssemblyName>
|
||||
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<TargetFrameworkIdentifier>.NETPortable</TargetFrameworkIdentifier>
|
||||
<TargetFrameworkVersion>v5.0</TargetFrameworkVersion>
|
||||
<!-- Misspelling, bug in NuGet targets -->
|
||||
<NuGetRuntimeIdentifier>win7-x64</NuGetRuntimeIdentifier>
|
||||
<NoStdLib>true</NoStdLib>
|
||||
<!-- To suppress msbuild warnings -->
|
||||
<AutoGenerateBindingRedirects>True</AutoGenerateBindingRedirects>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" />
|
||||
<ItemGroup>
|
||||
<Compile Include="Class1.cs" />
|
||||
<None Include="project.json" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Microsoft.DiaSymReader.PortablePdb.Tests\Microsoft.DiaSymReader.PortablePdb.UnitTests.csproj">
|
||||
<Project>{DEB3D675-5A3C-46DA-8945-F2EFAB135EA0}</Project>
|
||||
<Name>Microsoft.DiaSymReader.PortablePdb.UnitTests</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Microsoft.DiaSymReader.Converter.Tests\Microsoft.DiaSymReader.Converter.UnitTests.csproj">
|
||||
<Project>{12421910-7B1F-457A-8958-84DE13734F9B}</Project>
|
||||
<Name>Microsoft.DiaSymReader.Converter.UnitTests</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ImportGroup Label="Targets">
|
||||
<Import Project="..\..\build\Targets\Imports.targets" />
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -1,59 +0,0 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"xunit.console.netcore": "1.0.2-prerelease-00104",
|
||||
"Microsoft.NETCore.Portable.Compatibility": "1.0.1",
|
||||
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||
"Microsoft.NETCore.Runtime.CoreCLR": "1.1.0",
|
||||
"Microsoft.NETCore.TestHost": "1.1.0",
|
||||
"System.AppContext": "4.3.0",
|
||||
"System.Collections": "4.3.0",
|
||||
"System.Collections.Concurrent": "4.3.0",
|
||||
"System.Collections.Immutable": "1.3.1",
|
||||
"System.Console": "4.3.0",
|
||||
"System.Diagnostics.Debug": "4.3.0",
|
||||
"System.Diagnostics.FileVersionInfo": "4.3.0",
|
||||
"System.Diagnostics.Process": "4.3.0",
|
||||
"System.Diagnostics.StackTrace": "4.3.0",
|
||||
"System.Diagnostics.Tools": "4.3.0",
|
||||
"System.Dynamic.Runtime": "4.3.0",
|
||||
"System.Globalization": "4.3.0",
|
||||
"System.IO.Compression": "4.3.0",
|
||||
"System.IO.FileSystem": "4.3.0",
|
||||
"System.IO.FileSystem.Primitives": "4.3.0",
|
||||
"System.IO.FileSystem.Watcher": "4.3.0",
|
||||
"System.IO.Pipes": "4.3.0",
|
||||
"System.Linq": "4.3.0",
|
||||
"System.Linq.Expressions": "4.3.0",
|
||||
"System.Net.NameResolution": "4.3.0",
|
||||
"System.Net.Sockets": "4.3.0",
|
||||
"System.Reflection": "4.3.0",
|
||||
"System.Reflection.Primitives": "4.3.0",
|
||||
"System.Resources.ResourceManager": "4.3.0",
|
||||
"System.Runtime": "4.3.0",
|
||||
"System.Runtime.Extensions": "4.3.0",
|
||||
"System.Runtime.Handles": "4.3.0",
|
||||
"System.Runtime.InteropServices": "4.3.0",
|
||||
"System.Runtime.Loader": "4.3.0",
|
||||
"System.Runtime.Numerics": "4.3.0",
|
||||
"System.Security.Cryptography.Algorithms": "4.3.0",
|
||||
"System.Security.Cryptography.Encoding": "4.3.0",
|
||||
"System.Security.Cryptography.X509Certificates": "4.3.0",
|
||||
"System.Text.Encoding": "4.3.0",
|
||||
"System.Text.Encoding.CodePages": "4.3.0",
|
||||
"System.Text.Encoding.Extensions": "4.3.0",
|
||||
"System.Threading": "4.3.0",
|
||||
"System.Threading.Tasks": "4.3.0",
|
||||
"System.Threading.Tasks.Parallel": "4.3.0",
|
||||
"System.Threading.Thread": "4.3.0",
|
||||
},
|
||||
"frameworks": {
|
||||
"netcoreapp1.0": {
|
||||
"imports": [ "portable-net452", "dotnet" ]
|
||||
}
|
||||
},
|
||||
"runtimes": {
|
||||
"win7-x64": { },
|
||||
"ubuntu.14.04-x64": { },
|
||||
"osx.10.10-x64": {}
|
||||
}
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -->
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<OutDirName>DesktopTests</OutDirName>
|
||||
</PropertyGroup>
|
||||
<ImportGroup Label="Settings">
|
||||
<Import Project="..\..\build\Targets\Settings.targets" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup>
|
||||
<Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
|
||||
<Platform Condition="'$(Platform)' == ''">AnyCPU</Platform>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<ProjectGuid>{23683607-168A-4189-955E-908F0E80E60D}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AssemblyName>DeplyDesktopTestRuntime_DoNotUse</AssemblyName>
|
||||
<Nonshipping>true</Nonshipping>
|
||||
<SolutionDir Condition="'$(SolutionDir)' == '' OR '$(SolutionDir)' == '*Undefined*'">..\..\..\</SolutionDir>
|
||||
<RestorePackages>true</RestorePackages>
|
||||
<TargetFrameworkIdentifier />
|
||||
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
|
||||
<CopyNuGetImplementations>true</CopyNuGetImplementations>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<None Include="project.json" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Microsoft.DiaSymReader.PortablePdb.Tests\Microsoft.DiaSymReader.PortablePdb.UnitTests.csproj">
|
||||
<Project>{DEB3D675-5A3C-46DA-8945-F2EFAB135EA0}</Project>
|
||||
<Name>Microsoft.DiaSymReader.PortablePdb.UnitTests</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Microsoft.DiaSymReader.Converter.Tests\Microsoft.DiaSymReader.Converter.UnitTests.csproj">
|
||||
<Project>{12421910-7B1F-457A-8958-84DE13734F9B}</Project>
|
||||
<Name>Microsoft.DiaSymReader.Converter.UnitTests</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ImportGroup Label="Targets">
|
||||
<Import Project="..\..\build\Targets\Imports.targets" />
|
||||
</ImportGroup>
|
||||
<!--
|
||||
VS test runners run tests from the output directory of the test project.
|
||||
We need to copy xUnit dependencies and Desktop FX facades to all test project out directories.
|
||||
Under some circumstances, xUnit files will be locked by VS so we retry just once and only warn on error.
|
||||
-->
|
||||
<Target Name="DeployCopyForVSTests" AfterTargets="CopyFilesToOutputDirectory">
|
||||
<ItemGroup>
|
||||
<CopyForVSTests Include="$(OutDir)\*.dll" />
|
||||
</ItemGroup>
|
||||
<Copy SourceFiles="@(CopyForVSTests)" DestinationFolder="$(OutDirBase)\Microsoft.DiaSymReader.PortablePdb.Tests" Retries="1" ContinueOnError="WarnAndContinue" SkipUnchangedFiles="true" />
|
||||
<Copy SourceFiles="@(CopyForVSTests)" DestinationFolder="$(OutDirBase)\Microsoft.DiaSymReader.Converter.Tests" Retries="1" ContinueOnError="WarnAndContinue" SkipUnchangedFiles="true" />
|
||||
</Target>
|
||||
<Target Name="DeployConfigFiles" AfterTargets="CopyFilesToOutputDirectory">
|
||||
<Copy SourceFiles="$(OutDirBase)\Microsoft.DiaSymReader.PortablePdb.Tests\Microsoft.DiaSymReader.PortablePdb.UnitTests.dll.config" DestinationFolder="$(OutDir)" Retries="1" ContinueOnError="WarnAndContinue" SkipUnchangedFiles="true" />
|
||||
<Copy SourceFiles="$(OutDirBase)\Microsoft.DiaSymReader.Converter.Tests\Microsoft.DiaSymReader.Converter.UnitTests.dll.config" DestinationFolder="$(OutDir)" Retries="1" ContinueOnError="WarnAndContinue" SkipUnchangedFiles="true" />
|
||||
</Target>
|
||||
</Project>
|
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"System.IO.Compression": "4.3.0"
|
||||
},
|
||||
"frameworks": {
|
||||
"net46": { }
|
||||
},
|
||||
"runtimes": {
|
||||
"win": { }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<!-- Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -->
|
||||
<Project>
|
||||
<Import Project="..\Directory.Build.props"/>
|
||||
|
||||
<!-- This file is imported by all projects at the beginning of the project files -->
|
||||
<Import Project="$(RepoToolsetDir)Settings.props" />
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
|
||||
<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
|
||||
<DebugType>full</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
|
||||
<DebugType>full</DebugType>
|
||||
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -0,0 +1,7 @@
|
|||
<!-- Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -->
|
||||
<Project>
|
||||
<!-- This file is imported by all projects at the end of the project files -->
|
||||
<Import Project="$(RepoToolsetDir)Imports.targets" />
|
||||
<!-- Custom nuspec file support -->
|
||||
<Import Project="$(RepoToolsetDir)GenerateNuspecProperties.targets" />
|
||||
</Project>
|
|
@ -1,23 +0,0 @@
|
|||
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.CodeAnalysis.Debugging
|
||||
{
|
||||
/// <summary>
|
||||
/// Constants for producing and consuming streams of binary custom debug info.
|
||||
/// </summary>
|
||||
internal static class CustomDebugInfoConstants
|
||||
{
|
||||
// The version number of the custom debug info binary format.
|
||||
// CDIVERSION in Dev10
|
||||
internal const byte Version = 4;
|
||||
|
||||
// The number of bytes at the beginning of the byte array that contain global header information.
|
||||
// start after header (version byte + size byte + dword padding)
|
||||
internal const int GlobalHeaderSize = 4;
|
||||
|
||||
// The number of bytes at the beginning of each custom debug info record that contain header information
|
||||
// common to all record types (i.e. byte, kind, size).
|
||||
// version byte + kind byte + two bytes padding + size dword
|
||||
internal const int RecordHeaderSize = 8;
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
namespace Microsoft.CodeAnalysis.Debugging
|
||||
{
|
||||
/// <summary>
|
||||
/// The kinds of custom debug info that we know how to interpret.
|
||||
/// The values correspond to possible values of the "kind" byte
|
||||
/// in the record header.
|
||||
/// </summary>
|
||||
internal enum CustomDebugInfoKind : byte
|
||||
{
|
||||
UsingInfo = 0,
|
||||
ForwardInfo = 1,
|
||||
ForwardToModuleInfo = 2,
|
||||
StateMachineHoistedLocalScopes = 3,
|
||||
ForwardIterator = 4,
|
||||
DynamicLocals = 5,
|
||||
EditAndContinueLocalSlotMap = 6,
|
||||
EditAndContinueLambdaMap = 7,
|
||||
}
|
||||
}
|
|
@ -1,819 +0,0 @@
|
|||
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using Microsoft.CodeAnalysis.Collections;
|
||||
|
||||
#pragma warning disable RS0010 // Avoid using cref tags with a prefix
|
||||
|
||||
namespace Microsoft.CodeAnalysis.Debugging
|
||||
{
|
||||
/// <summary>
|
||||
/// A collection of utility method for consuming custom debug info from a PDB.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is not a public API, so we're just going to let bad offsets fail on their own.
|
||||
/// </remarks>
|
||||
internal static class CustomDebugInfoReader
|
||||
{
|
||||
/// <summary>
|
||||
/// This is the first header in the custom debug info blob.
|
||||
/// </summary>
|
||||
private static void ReadGlobalHeader(byte[] bytes, ref int offset, out byte version, out byte count)
|
||||
{
|
||||
version = bytes[offset + 0];
|
||||
count = bytes[offset + 1];
|
||||
offset += CustomDebugInfoConstants.GlobalHeaderSize;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// After the global header (see <see cref="ReadGlobalHeader"/> comes list of custom debug info record.
|
||||
/// Each record begins with a standard header.
|
||||
/// </summary>
|
||||
private static void ReadRecordHeader(byte[] bytes, ref int offset, out byte version, out CustomDebugInfoKind kind, out int size, out int alignmentSize)
|
||||
{
|
||||
version = bytes[offset + 0];
|
||||
kind = (CustomDebugInfoKind)bytes[offset + 1];
|
||||
alignmentSize = bytes[offset + 3];
|
||||
|
||||
// two bytes of padding after kind
|
||||
size = BitConverter.ToInt32(bytes, offset + 4);
|
||||
|
||||
offset += CustomDebugInfoConstants.RecordHeaderSize;
|
||||
}
|
||||
|
||||
/// <exception cref="InvalidOperationException"></exception>
|
||||
public static ImmutableArray<byte> TryGetCustomDebugInfoRecord(byte[] customDebugInfo, CustomDebugInfoKind recordKind)
|
||||
{
|
||||
foreach (var record in GetCustomDebugInfoRecords(customDebugInfo))
|
||||
{
|
||||
if (record.Kind == recordKind)
|
||||
{
|
||||
return record.Data;
|
||||
}
|
||||
}
|
||||
|
||||
return default(ImmutableArray<byte>);
|
||||
}
|
||||
|
||||
/// <remarks>
|
||||
/// Exposed for <see cref="T:Roslyn.Test.PdbUtilities.PdbToXmlConverter"/>.
|
||||
/// </remarks>
|
||||
/// <exception cref="InvalidOperationException"></exception>
|
||||
public static IEnumerable<CustomDebugInfoRecord> GetCustomDebugInfoRecords(byte[] customDebugInfo)
|
||||
{
|
||||
if (customDebugInfo.Length < CustomDebugInfoConstants.GlobalHeaderSize)
|
||||
{
|
||||
throw new InvalidOperationException("Invalid header.");
|
||||
}
|
||||
|
||||
int offset = 0;
|
||||
|
||||
byte globalVersion;
|
||||
byte globalCount;
|
||||
ReadGlobalHeader(customDebugInfo, ref offset, out globalVersion, out globalCount);
|
||||
|
||||
if (globalVersion != CustomDebugInfoConstants.Version)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
while (offset <= customDebugInfo.Length - CustomDebugInfoConstants.RecordHeaderSize)
|
||||
{
|
||||
byte version;
|
||||
CustomDebugInfoKind kind;
|
||||
int size;
|
||||
int alignmentSize;
|
||||
|
||||
ReadRecordHeader(customDebugInfo, ref offset, out version, out kind, out size, out alignmentSize);
|
||||
if (size < CustomDebugInfoConstants.RecordHeaderSize)
|
||||
{
|
||||
throw new InvalidOperationException("Invalid header.");
|
||||
}
|
||||
|
||||
if (kind != CustomDebugInfoKind.EditAndContinueLambdaMap &&
|
||||
kind != CustomDebugInfoKind.EditAndContinueLocalSlotMap)
|
||||
{
|
||||
// ignore alignment for CDIs that don't support it
|
||||
alignmentSize = 0;
|
||||
}
|
||||
|
||||
int bodySize = size - CustomDebugInfoConstants.RecordHeaderSize;
|
||||
if (offset > customDebugInfo.Length - bodySize || alignmentSize > 3 || alignmentSize > bodySize)
|
||||
{
|
||||
throw new InvalidOperationException("Invalid header.");
|
||||
}
|
||||
|
||||
yield return new CustomDebugInfoRecord(kind, version, ImmutableArray.Create(customDebugInfo, offset, bodySize - alignmentSize));
|
||||
offset += bodySize;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// For each namespace declaration enclosing a method (innermost-to-outermost), there is a count
|
||||
/// of the number of imports in that declaration.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// There's always at least one entry (for the global namespace).
|
||||
/// Exposed for <see cref="T:Roslyn.Test.PdbUtilities.PdbToXmlConverter"/>.
|
||||
/// </remarks>
|
||||
public static ImmutableArray<short> DecodeUsingRecord(ImmutableArray<byte> bytes)
|
||||
{
|
||||
int offset = 0;
|
||||
var numCounts = ReadInt16(bytes, ref offset);
|
||||
|
||||
var builder = ArrayBuilder<short>.GetInstance(numCounts);
|
||||
for (int i = 0; i < numCounts; i++)
|
||||
{
|
||||
builder.Add(ReadInt16(bytes, ref offset));
|
||||
}
|
||||
|
||||
return builder.ToImmutableAndFree();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This indicates that further information can be obtained by looking at the custom debug
|
||||
/// info of another method (specified by token).
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Appears when multiple method would otherwise have identical using records (see <see cref="DecodeUsingRecord"/>).
|
||||
/// Exposed for <see cref="T:Roslyn.Test.PdbUtilities.PdbToXmlConverter"/>.
|
||||
/// </remarks>
|
||||
public static int DecodeForwardRecord(ImmutableArray<byte> bytes)
|
||||
{
|
||||
int offset = 0;
|
||||
return ReadInt32(bytes, ref offset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This indicates that further information can be obtained by looking at the custom debug
|
||||
/// info of another method (specified by token).
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Appears when there are extern aliases and edit-and-continue is disabled.
|
||||
/// Exposed for <see cref="T:Roslyn.Test.PdbUtilities.PdbToXmlConverter"/>.
|
||||
/// </remarks>
|
||||
public static int DecodeForwardToModuleRecord(ImmutableArray<byte> bytes)
|
||||
{
|
||||
int offset = 0;
|
||||
return ReadInt32(bytes, ref offset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scopes of state machine hoisted local variables.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Exposed for <see cref="T:Roslyn.Test.PdbUtilities.PdbToXmlConverter"/>.
|
||||
/// </remarks>
|
||||
public static ImmutableArray<StateMachineHoistedLocalScope> DecodeStateMachineHoistedLocalScopesRecord(ImmutableArray<byte> bytes)
|
||||
{
|
||||
int offset = 0;
|
||||
|
||||
var bucketCount = ReadInt32(bytes, ref offset);
|
||||
|
||||
var builder = ArrayBuilder<StateMachineHoistedLocalScope>.GetInstance(bucketCount);
|
||||
for (int i = 0; i < bucketCount; i++)
|
||||
{
|
||||
int startOffset = ReadInt32(bytes, ref offset);
|
||||
int endOffset = ReadInt32(bytes, ref offset);
|
||||
|
||||
builder.Add(new StateMachineHoistedLocalScope(startOffset, endOffset));
|
||||
}
|
||||
|
||||
return builder.ToImmutableAndFree();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that this method is the iterator state machine for the method named in the record.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Appears when are iterator methods.
|
||||
/// Exposed for <see cref="T:Roslyn.Test.PdbUtilities.PdbToXmlConverter"/>.
|
||||
/// </remarks>
|
||||
public static string DecodeForwardIteratorRecord(ImmutableArray<byte> bytes)
|
||||
{
|
||||
int offset = 0;
|
||||
|
||||
var pooled = PooledStringBuilder.GetInstance();
|
||||
var builder = pooled.Builder;
|
||||
while (true)
|
||||
{
|
||||
char ch = (char)ReadInt16(bytes, ref offset);
|
||||
if (ch == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
builder.Append(ch);
|
||||
}
|
||||
|
||||
return pooled.ToStringAndFree();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Does for locals what System.Runtime.CompilerServices.DynamicAttribute does for parameters, return types, and fields.
|
||||
/// In particular, indicates which occurrences of <see cref="object"/> in the signature are really dynamic.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Appears when there are dynamic locals.
|
||||
/// Exposed for <see cref="T:Roslyn.Test.PdbUtilities.PdbToXmlConverter"/>.
|
||||
/// </remarks>
|
||||
/// <exception cref="InvalidOperationException">Bad data.</exception>
|
||||
public static ImmutableArray<DynamicLocalInfo> DecodeDynamicLocalsRecord(ImmutableArray<byte> bytes)
|
||||
{
|
||||
int offset = 0;
|
||||
int bucketCount = ReadInt32(bytes, ref offset);
|
||||
|
||||
var builder = ArrayBuilder<DynamicLocalInfo>.GetInstance(bucketCount);
|
||||
for (int i = 0; i < bucketCount; i++)
|
||||
{
|
||||
const int FlagBytesCount = 64;
|
||||
|
||||
ulong flags = 0UL;
|
||||
for (int j = 0; j < FlagBytesCount; j++)
|
||||
{
|
||||
var flag = ReadByte(bytes, ref offset) != 0;
|
||||
if (flag)
|
||||
{
|
||||
flags |= 1UL << j;
|
||||
}
|
||||
}
|
||||
|
||||
int flagCount = ReadInt32(bytes, ref offset);
|
||||
int slotId = ReadInt32(bytes, ref offset);
|
||||
|
||||
const int NameBytesCount = 128;
|
||||
var pooled = PooledStringBuilder.GetInstance();
|
||||
var nameBuilder = pooled.Builder;
|
||||
|
||||
int nameEnd = offset + NameBytesCount;
|
||||
while (offset < nameEnd)
|
||||
{
|
||||
char ch = (char)ReadInt16(bytes, ref offset);
|
||||
if (ch == 0)
|
||||
{
|
||||
// The Identifier name takes 64 WCHAR no matter how big its actual length is.
|
||||
offset = nameEnd;
|
||||
break;
|
||||
}
|
||||
|
||||
nameBuilder.Append(ch);
|
||||
}
|
||||
|
||||
var name = pooled.ToStringAndFree();
|
||||
|
||||
builder.Add(new DynamicLocalInfo(flagCount, flags, slotId, name));
|
||||
}
|
||||
|
||||
return builder.ToImmutableAndFree();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the raw bytes of a record.
|
||||
/// </summary>
|
||||
private static void ReadRawRecordBody(byte[] bytes, ref int offset, int size, out ImmutableArray<byte> body)
|
||||
{
|
||||
int bodySize = size - CustomDebugInfoConstants.RecordHeaderSize;
|
||||
body = ImmutableArray.Create(bytes, offset, bodySize);
|
||||
offset += bodySize;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Skips past a record.
|
||||
/// </summary>
|
||||
private static void SkipRecord(byte[] bytes, ref int offset, int size)
|
||||
{
|
||||
offset += size - CustomDebugInfoConstants.RecordHeaderSize;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the import strings for a given method, following forward pointers as necessary.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// For each namespace enclosing the method, a list of import strings, innermost to outermost.
|
||||
/// There should always be at least one entry, for the global namespace.
|
||||
/// </returns>
|
||||
public static ImmutableArray<ImmutableArray<string>> GetCSharpGroupedImportStrings<TArg>(
|
||||
int methodToken,
|
||||
TArg arg,
|
||||
Func<int, TArg, byte[]> getMethodCustomDebugInfo,
|
||||
Func<int, TArg, ImmutableArray<string>> getMethodImportStrings,
|
||||
out ImmutableArray<string> externAliasStrings)
|
||||
{
|
||||
externAliasStrings = default(ImmutableArray<string>);
|
||||
|
||||
ImmutableArray<short> groupSizes = default(ImmutableArray<short>);
|
||||
bool seenForward = false;
|
||||
|
||||
RETRY:
|
||||
byte[] bytes = getMethodCustomDebugInfo(methodToken, arg);
|
||||
if (bytes == null)
|
||||
{
|
||||
return default(ImmutableArray<ImmutableArray<string>>);
|
||||
}
|
||||
|
||||
foreach (var record in GetCustomDebugInfoRecords(bytes))
|
||||
{
|
||||
switch (record.Kind)
|
||||
{
|
||||
case CustomDebugInfoKind.UsingInfo:
|
||||
if (!groupSizes.IsDefault)
|
||||
{
|
||||
throw new InvalidOperationException(string.Format("Expected at most one Using record for method {0}", FormatMethodToken(methodToken)));
|
||||
}
|
||||
|
||||
groupSizes = DecodeUsingRecord(record.Data);
|
||||
break;
|
||||
|
||||
case CustomDebugInfoKind.ForwardInfo:
|
||||
if (!externAliasStrings.IsDefault)
|
||||
{
|
||||
throw new InvalidOperationException(string.Format("Did not expect both Forward and ForwardToModule records for method {0}", FormatMethodToken(methodToken)));
|
||||
}
|
||||
|
||||
methodToken = DecodeForwardRecord(record.Data);
|
||||
|
||||
// Follow at most one forward link (as in FUNCBRECEE::ensureNamespaces).
|
||||
// NOTE: Dev11 may produce chains of forward links (e.g. for System.Collections.Immutable).
|
||||
if (!seenForward)
|
||||
{
|
||||
seenForward = true;
|
||||
goto RETRY;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case CustomDebugInfoKind.ForwardToModuleInfo:
|
||||
if (!externAliasStrings.IsDefault)
|
||||
{
|
||||
throw new InvalidOperationException(string.Format("Expected at most one ForwardToModule record for method {0}", FormatMethodToken(methodToken)));
|
||||
}
|
||||
|
||||
int moduleInfoMethodToken = DecodeForwardToModuleRecord(record.Data);
|
||||
|
||||
ImmutableArray<string> allModuleInfoImportStrings = getMethodImportStrings(moduleInfoMethodToken, arg);
|
||||
Debug.Assert(!allModuleInfoImportStrings.IsDefault);
|
||||
|
||||
var externAliasBuilder = ArrayBuilder<string>.GetInstance();
|
||||
|
||||
foreach (string importString in allModuleInfoImportStrings)
|
||||
{
|
||||
if (IsCSharpExternAliasInfo(importString))
|
||||
{
|
||||
externAliasBuilder.Add(importString);
|
||||
}
|
||||
}
|
||||
|
||||
externAliasStrings = externAliasBuilder.ToImmutableAndFree();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (groupSizes.IsDefault)
|
||||
{
|
||||
// This can happen in malformed PDBs (e.g. chains of forwards).
|
||||
return default(ImmutableArray<ImmutableArray<string>>);
|
||||
}
|
||||
|
||||
ImmutableArray<string> importStrings = getMethodImportStrings(methodToken, arg);
|
||||
Debug.Assert(!importStrings.IsDefault);
|
||||
|
||||
var resultBuilder = ArrayBuilder<ImmutableArray<string>>.GetInstance(groupSizes.Length);
|
||||
var groupBuilder = ArrayBuilder<string>.GetInstance();
|
||||
int pos = 0;
|
||||
|
||||
foreach (short groupSize in groupSizes)
|
||||
{
|
||||
for (int i = 0; i < groupSize; i++, pos++)
|
||||
{
|
||||
if (pos >= importStrings.Length)
|
||||
{
|
||||
throw new InvalidOperationException(string.Format("Group size indicates more imports than there are import strings (method {0}).", FormatMethodToken(methodToken)));
|
||||
}
|
||||
|
||||
string importString = importStrings[pos];
|
||||
if (IsCSharpExternAliasInfo(importString))
|
||||
{
|
||||
throw new InvalidOperationException(string.Format("Encountered extern alias info before all import strings were consumed (method {0}).", FormatMethodToken(methodToken)));
|
||||
}
|
||||
|
||||
groupBuilder.Add(importString);
|
||||
}
|
||||
|
||||
resultBuilder.Add(groupBuilder.ToImmutable());
|
||||
groupBuilder.Clear();
|
||||
}
|
||||
|
||||
if (externAliasStrings.IsDefault)
|
||||
{
|
||||
Debug.Assert(groupBuilder.Count == 0);
|
||||
|
||||
// Extern alias detail strings (prefix "Z") are not included in the group counts.
|
||||
for (; pos < importStrings.Length; pos++)
|
||||
{
|
||||
string importString = importStrings[pos];
|
||||
if (!IsCSharpExternAliasInfo(importString))
|
||||
{
|
||||
throw new InvalidOperationException(string.Format("Expected only extern alias info strings after consuming the indicated number of imports (method {0}).", FormatMethodToken(methodToken)));
|
||||
}
|
||||
|
||||
groupBuilder.Add(importString);
|
||||
}
|
||||
|
||||
externAliasStrings = groupBuilder.ToImmutableAndFree();
|
||||
}
|
||||
else
|
||||
{
|
||||
groupBuilder.Free();
|
||||
|
||||
if (pos < importStrings.Length)
|
||||
{
|
||||
throw new InvalidOperationException(string.Format("Group size indicates fewer imports than there are import strings (method {0}).", FormatMethodToken(methodToken)));
|
||||
}
|
||||
}
|
||||
|
||||
return resultBuilder.ToImmutableAndFree();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the import strings for a given method, following forward pointers as necessary.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A list of import strings. There should always be at least one entry, for the global namespace.
|
||||
/// </returns>
|
||||
public static ImmutableArray<string> GetVisualBasicImportStrings<TArg>(
|
||||
int methodToken,
|
||||
TArg arg,
|
||||
Func<int, TArg, ImmutableArray<string>> getMethodImportStrings)
|
||||
{
|
||||
ImmutableArray<string> importStrings = getMethodImportStrings(methodToken, arg);
|
||||
Debug.Assert(!importStrings.IsDefault);
|
||||
|
||||
if (importStrings.IsEmpty)
|
||||
{
|
||||
return ImmutableArray<string>.Empty;
|
||||
}
|
||||
|
||||
// Follow at most one forward link.
|
||||
// As in PdbUtil::GetRawNamespaceListCore, we consider only the first string when
|
||||
// checking for forwarding.
|
||||
string importString = importStrings[0];
|
||||
if (importString.Length >= 2 && importString[0] == '@')
|
||||
{
|
||||
char ch1 = importString[1];
|
||||
if ('0' <= ch1 && ch1 <= '9')
|
||||
{
|
||||
int tempMethodToken;
|
||||
if (int.TryParse(importString.Substring(1), NumberStyles.None, CultureInfo.InvariantCulture, out tempMethodToken))
|
||||
{
|
||||
importStrings = getMethodImportStrings(tempMethodToken, arg);
|
||||
Debug.Assert(!importStrings.IsDefault);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return importStrings;
|
||||
}
|
||||
|
||||
private static void CheckVersion(byte globalVersion, int methodToken)
|
||||
{
|
||||
if (globalVersion != CustomDebugInfoConstants.Version)
|
||||
{
|
||||
throw new InvalidOperationException(string.Format("Method {0}: Expected version {1}, but found version {2}.", FormatMethodToken(methodToken), CustomDebugInfoConstants.Version, globalVersion));
|
||||
}
|
||||
}
|
||||
|
||||
private static int ReadInt32(ImmutableArray<byte> bytes, ref int offset)
|
||||
{
|
||||
int i = offset;
|
||||
if (i + sizeof(int) > bytes.Length)
|
||||
{
|
||||
throw new InvalidOperationException("Read out of buffer.");
|
||||
}
|
||||
|
||||
offset += sizeof(int);
|
||||
return bytes[i] | (bytes[i + 1] << 8) | (bytes[i + 2] << 16) | (bytes[i + 3] << 24);
|
||||
}
|
||||
|
||||
private static short ReadInt16(ImmutableArray<byte> bytes, ref int offset)
|
||||
{
|
||||
int i = offset;
|
||||
if (i + sizeof(short) > bytes.Length)
|
||||
{
|
||||
throw new InvalidOperationException("Read out of buffer.");
|
||||
}
|
||||
|
||||
offset += sizeof(short);
|
||||
return (short)(bytes[i] | (bytes[i + 1] << 8));
|
||||
}
|
||||
|
||||
private static byte ReadByte(ImmutableArray<byte> bytes, ref int offset)
|
||||
{
|
||||
int i = offset;
|
||||
if (i + sizeof(byte) > bytes.Length)
|
||||
{
|
||||
throw new InvalidOperationException("Read out of buffer.");
|
||||
}
|
||||
|
||||
offset += sizeof(byte);
|
||||
return bytes[i];
|
||||
}
|
||||
|
||||
private static bool IsCSharpExternAliasInfo(string import)
|
||||
{
|
||||
return import.Length > 0 && import[0] == 'Z';
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse a string representing a C# using (or extern alias) directive.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <![CDATA[
|
||||
/// For C#:
|
||||
/// "USystem" -> <namespace name="System" />
|
||||
/// "AS USystem" -> <alias name="S" target="System" kind="namespace" />
|
||||
/// "AC TSystem.Console" -> <alias name="C" target="System.Console" kind="type" />
|
||||
/// "AS ESystem alias" -> <alias name="S" qualifier="alias" target="System" kind="type" />
|
||||
/// "XOldLib" -> <extern alias="OldLib" />
|
||||
/// "ZOldLib assembly" -> <externinfo name="OldLib" assembly="assembly" />
|
||||
/// "ESystem alias" -> <namespace qualifier="alias" name="System" />
|
||||
/// "TSystem.Math" -> <type name="System.Math" />
|
||||
/// ]]>
|
||||
/// </remarks>
|
||||
public static bool TryParseCSharpImportString(string import, out string alias, out string externAlias, out string target, out ImportTargetKind kind)
|
||||
{
|
||||
alias = null;
|
||||
externAlias = null;
|
||||
target = null;
|
||||
kind = default(ImportTargetKind);
|
||||
|
||||
if (string.IsNullOrEmpty(import))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (import[0])
|
||||
{
|
||||
case 'U': // C# (namespace) using
|
||||
alias = null;
|
||||
externAlias = null;
|
||||
target = import.Substring(1);
|
||||
kind = ImportTargetKind.Namespace;
|
||||
return true;
|
||||
|
||||
case 'E': // C# (namespace) using
|
||||
// NOTE: Dev12 has related cases "I" and "O" in EMITTER::ComputeDebugNamespace,
|
||||
// but they were probably implementation details that do not affect Roslyn.
|
||||
if (!TrySplit(import, 1, ' ', out target, out externAlias))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
alias = null;
|
||||
kind = ImportTargetKind.Namespace;
|
||||
return true;
|
||||
|
||||
case 'T': // C# (type) using
|
||||
alias = null;
|
||||
externAlias = null;
|
||||
target = import.Substring(1);
|
||||
kind = ImportTargetKind.Type;
|
||||
return true;
|
||||
|
||||
case 'A': // C# type or namespace alias
|
||||
if (!TrySplit(import, 1, ' ', out alias, out target))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (target[0])
|
||||
{
|
||||
case 'U':
|
||||
kind = ImportTargetKind.Namespace;
|
||||
target = target.Substring(1);
|
||||
externAlias = null;
|
||||
return true;
|
||||
|
||||
case 'T':
|
||||
kind = ImportTargetKind.Type;
|
||||
target = target.Substring(1);
|
||||
externAlias = null;
|
||||
return true;
|
||||
|
||||
case 'E':
|
||||
kind = ImportTargetKind.Namespace; // Never happens for types.
|
||||
if (!TrySplit(target, 1, ' ', out target, out externAlias))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
case 'X': // C# extern alias (in file)
|
||||
externAlias = null;
|
||||
alias = import.Substring(1); // For consistency with the portable format, store it in alias, rather than externAlias.
|
||||
target = null;
|
||||
kind = ImportTargetKind.Assembly;
|
||||
return true;
|
||||
|
||||
case 'Z': // C# extern alias (module-level)
|
||||
// For consistency with the portable format, store it in alias, rather than externAlias.
|
||||
if (!TrySplit(import, 1, ' ', out alias, out target))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
externAlias = null;
|
||||
kind = ImportTargetKind.Assembly;
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse a string representing a VB import statement.
|
||||
/// </summary>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="import"/> is null.</exception>
|
||||
/// <exception cref="ArgumentException">Format of <paramref name="import"/> is not valid.</exception>
|
||||
public static bool TryParseVisualBasicImportString(string import, out string alias, out string target, out ImportTargetKind kind, out VBImportScopeKind scope)
|
||||
{
|
||||
alias = null;
|
||||
target = null;
|
||||
kind = default(ImportTargetKind);
|
||||
scope = default(VBImportScopeKind);
|
||||
|
||||
if (import == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// VB current namespace
|
||||
if (import.Length == 0)
|
||||
{
|
||||
alias = null;
|
||||
target = import;
|
||||
kind = ImportTargetKind.CurrentNamespace;
|
||||
scope = VBImportScopeKind.Unspecified;
|
||||
return true;
|
||||
}
|
||||
|
||||
int pos = 0;
|
||||
switch (import[pos])
|
||||
{
|
||||
case '&':
|
||||
// Indicates the presence of embedded PIA types from a given assembly. No longer required (as of Roslyn).
|
||||
case '$':
|
||||
case '#':
|
||||
// From ProcedureContext::LoadImportsAndDefaultNamespaceNormal:
|
||||
// "Module Imports and extension types are no longer needed since we are not doing custom name lookup"
|
||||
alias = null;
|
||||
target = import;
|
||||
kind = ImportTargetKind.Defunct;
|
||||
scope = VBImportScopeKind.Unspecified;
|
||||
return true;
|
||||
case '*': // VB default namespace
|
||||
// see PEBuilder.cpp in vb\language\CodeGen
|
||||
pos++;
|
||||
alias = null;
|
||||
target = import.Substring(pos);
|
||||
kind = ImportTargetKind.DefaultNamespace;
|
||||
scope = VBImportScopeKind.Unspecified;
|
||||
return true;
|
||||
case '@': // VB cases other than default and current namespace
|
||||
// see PEBuilder.cpp in vb\language\CodeGen
|
||||
pos++;
|
||||
if (pos >= import.Length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
scope = VBImportScopeKind.Unspecified;
|
||||
switch (import[pos])
|
||||
{
|
||||
case 'F':
|
||||
scope = VBImportScopeKind.File;
|
||||
pos++;
|
||||
break;
|
||||
case 'P':
|
||||
scope = VBImportScopeKind.Project;
|
||||
pos++;
|
||||
break;
|
||||
}
|
||||
|
||||
if (pos >= import.Length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (import[pos])
|
||||
{
|
||||
case 'A':
|
||||
pos++;
|
||||
|
||||
if (import[pos] != ':')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
pos++;
|
||||
|
||||
if (!TrySplit(import, pos, '=', out alias, out target))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
kind = ImportTargetKind.NamespaceOrType;
|
||||
return true;
|
||||
|
||||
case 'X':
|
||||
pos++;
|
||||
|
||||
if (import[pos] != ':')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
pos++;
|
||||
|
||||
if (!TrySplit(import, pos, '=', out alias, out target))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
kind = ImportTargetKind.XmlNamespace;
|
||||
return true;
|
||||
|
||||
case 'T':
|
||||
pos++;
|
||||
|
||||
if (import[pos] != ':')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
pos++;
|
||||
|
||||
alias = null;
|
||||
target = import.Substring(pos);
|
||||
kind = ImportTargetKind.Type;
|
||||
return true;
|
||||
|
||||
case ':':
|
||||
pos++;
|
||||
alias = null;
|
||||
target = import.Substring(pos);
|
||||
kind = ImportTargetKind.Namespace;
|
||||
return true;
|
||||
|
||||
default:
|
||||
alias = null;
|
||||
target = import.Substring(pos);
|
||||
kind = ImportTargetKind.MethodToken;
|
||||
return true;
|
||||
}
|
||||
|
||||
default:
|
||||
// VB current namespace
|
||||
alias = null;
|
||||
target = import;
|
||||
kind = ImportTargetKind.CurrentNamespace;
|
||||
scope = VBImportScopeKind.Unspecified;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool TrySplit(string input, int offset, char separator, out string before, out string after)
|
||||
{
|
||||
int separatorPos = input.IndexOf(separator, offset);
|
||||
|
||||
// Allow zero-length before for the global namespace (empty string).
|
||||
// Allow zero-length after for an XML alias in VB ("@PX:="). Not sure what it means.
|
||||
if (offset <= separatorPos && separatorPos < input.Length)
|
||||
{
|
||||
before = input.Substring(offset, separatorPos - offset);
|
||||
after = separatorPos + 1 == input.Length
|
||||
? ""
|
||||
: input.Substring(separatorPos + 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
before = null;
|
||||
after = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static string FormatMethodToken(int methodToken)
|
||||
{
|
||||
return string.Format("0x{0:x8}", methodToken);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Immutable;
|
||||
|
||||
namespace Microsoft.CodeAnalysis.Debugging
|
||||
{
|
||||
internal struct CustomDebugInfoRecord
|
||||
{
|
||||
public readonly CustomDebugInfoKind Kind;
|
||||
public readonly byte Version;
|
||||
public readonly ImmutableArray<byte> Data;
|
||||
|
||||
public CustomDebugInfoRecord(CustomDebugInfoKind kind, byte version, ImmutableArray<byte> data)
|
||||
{
|
||||
Kind = kind;
|
||||
Version = version;
|
||||
Data = data;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.CodeAnalysis.Debugging
|
||||
{
|
||||
internal struct DynamicLocalInfo
|
||||
{
|
||||
public readonly int FlagCount;
|
||||
public readonly ulong Flags;
|
||||
public readonly int SlotId;
|
||||
public readonly string Name;
|
||||
|
||||
public DynamicLocalInfo(int flagCount, ulong flags, int slotId, string name)
|
||||
{
|
||||
FlagCount = flagCount;
|
||||
Flags = flags;
|
||||
SlotId = slotId;
|
||||
Name = name;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.CodeAnalysis.Debugging
|
||||
{
|
||||
internal enum ImportTargetKind
|
||||
{
|
||||
/// <summary>
|
||||
/// C# or VB namespace import.
|
||||
/// </summary>
|
||||
Namespace,
|
||||
|
||||
/// <summary>
|
||||
/// C# or VB type import.
|
||||
/// </summary>
|
||||
Type,
|
||||
|
||||
/// <summary>
|
||||
/// VB namespace or type alias target (not specified).
|
||||
/// </summary>
|
||||
NamespaceOrType,
|
||||
|
||||
/// <summary>
|
||||
/// C# extern alias.
|
||||
/// </summary>
|
||||
Assembly,
|
||||
|
||||
/// <summary>
|
||||
/// VB XML import.
|
||||
/// </summary>
|
||||
XmlNamespace,
|
||||
|
||||
/// <summary>
|
||||
/// VB forwarding information (i.e. another method has the imports for this one).
|
||||
/// </summary>
|
||||
MethodToken,
|
||||
|
||||
/// <summary>
|
||||
/// VB containing namespace (not an import).
|
||||
/// </summary>
|
||||
CurrentNamespace,
|
||||
|
||||
/// <summary>
|
||||
/// VB root namespace (not an import).
|
||||
/// </summary>
|
||||
DefaultNamespace,
|
||||
|
||||
/// <summary>
|
||||
/// A kind that is no longer used.
|
||||
/// </summary>
|
||||
Defunct,
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
|
||||
<HasSharedItems>true</HasSharedItems>
|
||||
<SharedGUID>d73adf7d-2c1c-42ae-b2ab-edc9497e4b71</SharedGUID>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration">
|
||||
<Import_RootNamespace>Microsoft.CodeAnalysis.Metadata</Import_RootNamespace>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)CustomDebugInfoConstants.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)CustomDebugInfoKind.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)CustomDebugInfoReader.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)CustomDebugInfoRecord.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)DynamicLocalInfo.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)ImportTargetKind.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)PortableCustomDebugInfoKinds.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)StateMachineHoistedLocalScope.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)VBImportScopeKind.cs" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -1,13 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>d73adf7d-2c1c-42ae-b2ab-edc9497e4b71</ProjectGuid>
|
||||
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.Default.props" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.props" />
|
||||
<PropertyGroup />
|
||||
<Import Project="Microsoft.CodeAnalysis.Metadata.projitems" Label="Shared" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.CSharp.targets" />
|
||||
</Project>
|
|
@ -1,16 +0,0 @@
|
|||
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
|
||||
namespace Microsoft.CodeAnalysis.Debugging
|
||||
{
|
||||
internal static class PortableCustomDebugInfoKinds
|
||||
{
|
||||
public static readonly Guid AsyncMethodSteppingInformationBlob = new Guid("54FD2AC5-E925-401A-9C2A-F94F171072F8");
|
||||
public static readonly Guid StateMachineHoistedLocalScopes = new Guid("6DA9A61E-F8C7-4874-BE62-68BC5630DF71");
|
||||
public static readonly Guid DynamicLocalVariables = new Guid("83C563C4-B4F3-47D5-B824-BA5441477EA8");
|
||||
public static readonly Guid DefaultNamespace = new Guid("58b2eab6-209f-4e4e-a22c-b2d0f910c782");
|
||||
public static readonly Guid EncLocalSlotMap = new Guid("755F52A8-91C5-45BE-B4B8-209571E552BD");
|
||||
public static readonly Guid EncLambdaAndClosureMap = new Guid("A643004C-0240-496F-A783-30D64F4979DE");
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.CodeAnalysis.Debugging
|
||||
{
|
||||
internal struct StateMachineHoistedLocalScope
|
||||
{
|
||||
public readonly int StartOffset;
|
||||
public readonly int EndOffset;
|
||||
|
||||
public StateMachineHoistedLocalScope(int startoffset, int endOffset)
|
||||
{
|
||||
StartOffset = startoffset;
|
||||
EndOffset = endOffset;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.CodeAnalysis.Debugging
|
||||
{
|
||||
internal enum VBImportScopeKind
|
||||
{
|
||||
Unspecified,
|
||||
File,
|
||||
Project,
|
||||
}
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.CodeAnalysis
|
||||
{
|
||||
internal partial class ArrayBuilder<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// struct enumerator used in foreach.
|
||||
/// </summary>
|
||||
internal struct Enumerator : IEnumerator<T>
|
||||
{
|
||||
private readonly ArrayBuilder<T> _builder;
|
||||
private int _index;
|
||||
|
||||
public Enumerator(ArrayBuilder<T> builder)
|
||||
{
|
||||
_builder = builder;
|
||||
_index = -1;
|
||||
}
|
||||
|
||||
public T Current
|
||||
{
|
||||
get
|
||||
{
|
||||
return _builder[_index];
|
||||
}
|
||||
}
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
_index++;
|
||||
return _index < _builder.Count;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
object System.Collections.IEnumerator.Current
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Current;
|
||||
}
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
_index = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,499 +0,0 @@
|
|||
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics;
|
||||
using Roslyn.Utilities;
|
||||
using Microsoft.CodeAnalysis.Collections;
|
||||
|
||||
namespace Microsoft.CodeAnalysis
|
||||
{
|
||||
[DebuggerDisplay("Count = {Count,nq}")]
|
||||
[DebuggerTypeProxy(typeof(ArrayBuilder<>.DebuggerProxy))]
|
||||
internal sealed partial class ArrayBuilder<T> : IReadOnlyCollection<T>, IReadOnlyList<T>
|
||||
{
|
||||
#region DebuggerProxy
|
||||
|
||||
private sealed class DebuggerProxy
|
||||
{
|
||||
private readonly ArrayBuilder<T> _builder;
|
||||
|
||||
public DebuggerProxy(ArrayBuilder<T> builder)
|
||||
{
|
||||
_builder = builder;
|
||||
}
|
||||
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
|
||||
public T[] A
|
||||
{
|
||||
get
|
||||
{
|
||||
var result = new T[_builder.Count];
|
||||
for (int i = 0; i < result.Length; i++)
|
||||
{
|
||||
result[i] = _builder[i];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private readonly ImmutableArray<T>.Builder _builder;
|
||||
|
||||
private readonly ObjectPool<ArrayBuilder<T>> _pool;
|
||||
|
||||
public ArrayBuilder(int size)
|
||||
{
|
||||
_builder = ImmutableArray.CreateBuilder<T>(size);
|
||||
}
|
||||
|
||||
public ArrayBuilder() :
|
||||
this(8)
|
||||
{ }
|
||||
|
||||
private ArrayBuilder(ObjectPool<ArrayBuilder<T>> pool) :
|
||||
this()
|
||||
{
|
||||
_pool = pool;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Realizes the array.
|
||||
/// </summary>
|
||||
public ImmutableArray<T> ToImmutable()
|
||||
{
|
||||
return _builder.ToImmutable();
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
return _builder.Count;
|
||||
}
|
||||
}
|
||||
|
||||
public T this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
return _builder[index];
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
_builder[index] = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write <paramref name="value"/> to slot <paramref name="index"/>.
|
||||
/// Fills in unallocated slots preceding the <paramref name="index"/>, if any.
|
||||
/// </summary>
|
||||
public void SetItem(int index, T value)
|
||||
{
|
||||
while (index > _builder.Count)
|
||||
{
|
||||
_builder.Add(default(T));
|
||||
}
|
||||
|
||||
if (index == _builder.Count)
|
||||
{
|
||||
_builder.Add(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
_builder[index] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public void Add(T item)
|
||||
{
|
||||
_builder.Add(item);
|
||||
}
|
||||
|
||||
public void Insert(int index, T item)
|
||||
{
|
||||
_builder.Insert(index, item);
|
||||
}
|
||||
|
||||
public void EnsureCapacity(int capacity)
|
||||
{
|
||||
if (_builder.Capacity < capacity)
|
||||
{
|
||||
_builder.Capacity = capacity;
|
||||
}
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
_builder.Clear();
|
||||
}
|
||||
|
||||
public bool Contains(T item)
|
||||
{
|
||||
return _builder.Contains(item);
|
||||
}
|
||||
|
||||
public int IndexOf(T item)
|
||||
{
|
||||
return _builder.IndexOf(item);
|
||||
}
|
||||
|
||||
public int IndexOf(T item, IEqualityComparer<T> equalityComparer)
|
||||
{
|
||||
return _builder.IndexOf(item, 0, _builder.Count, equalityComparer);
|
||||
}
|
||||
|
||||
public int IndexOf(T item, int startIndex, int count)
|
||||
{
|
||||
return _builder.IndexOf(item, startIndex, count);
|
||||
}
|
||||
|
||||
public void RemoveAt(int index)
|
||||
{
|
||||
_builder.RemoveAt(index);
|
||||
}
|
||||
|
||||
public void RemoveLast()
|
||||
{
|
||||
_builder.RemoveAt(_builder.Count - 1);
|
||||
}
|
||||
|
||||
public void ReverseContents()
|
||||
{
|
||||
_builder.Reverse();
|
||||
}
|
||||
|
||||
public void Sort()
|
||||
{
|
||||
_builder.Sort();
|
||||
}
|
||||
|
||||
public void Sort(IComparer<T> comparer)
|
||||
{
|
||||
_builder.Sort(comparer);
|
||||
}
|
||||
|
||||
public void Sort(int startIndex, IComparer<T> comparer)
|
||||
{
|
||||
_builder.Sort(startIndex, _builder.Count - startIndex, comparer);
|
||||
}
|
||||
|
||||
public T[] ToArray()
|
||||
{
|
||||
return _builder.ToArray();
|
||||
}
|
||||
|
||||
public void CopyTo(T[] array, int start)
|
||||
{
|
||||
_builder.CopyTo(array, start);
|
||||
}
|
||||
|
||||
public T Last()
|
||||
{
|
||||
return _builder[_builder.Count - 1];
|
||||
}
|
||||
|
||||
public T First()
|
||||
{
|
||||
return _builder[0];
|
||||
}
|
||||
|
||||
public bool Any()
|
||||
{
|
||||
return _builder.Count > 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Realizes the array.
|
||||
/// </summary>
|
||||
public ImmutableArray<T> ToImmutableOrNull()
|
||||
{
|
||||
if (Count == 0)
|
||||
{
|
||||
return default(ImmutableArray<T>);
|
||||
}
|
||||
|
||||
return this.ToImmutable();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Realizes the array, downcasting each element to a derived type.
|
||||
/// </summary>
|
||||
public ImmutableArray<U> ToDowncastedImmutable<U>()
|
||||
where U : T
|
||||
{
|
||||
if (Count == 0)
|
||||
{
|
||||
return ImmutableArray<U>.Empty;
|
||||
}
|
||||
|
||||
var tmp = ArrayBuilder<U>.GetInstance(Count);
|
||||
foreach (var i in this)
|
||||
{
|
||||
tmp.Add((U)i);
|
||||
}
|
||||
|
||||
return tmp.ToImmutableAndFree();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Realizes the array and disposes the builder in one operation.
|
||||
/// </summary>
|
||||
public ImmutableArray<T> ToImmutableAndFree()
|
||||
{
|
||||
var result = this.ToImmutable();
|
||||
this.Free();
|
||||
return result;
|
||||
}
|
||||
|
||||
public T[] ToArrayAndFree()
|
||||
{
|
||||
var result = this.ToArray();
|
||||
this.Free();
|
||||
return result;
|
||||
}
|
||||
|
||||
#region Poolable
|
||||
|
||||
// To implement Poolable, you need two things:
|
||||
// 1) Expose Freeing primitive.
|
||||
public void Free()
|
||||
{
|
||||
var pool = _pool;
|
||||
if (pool != null)
|
||||
{
|
||||
// According to the statistics of a C# compiler self-build, the most commonly used builder size is 0. (808003 uses).
|
||||
// The distant second is the Count == 1 (455619), then 2 (106362) ...
|
||||
// After about 50 (just 67) we have a long tail of infrequently used builder sizes.
|
||||
// However we have builders with size up to 50K (just one such thing)
|
||||
//
|
||||
// We do not want to retain (potentially indefinitely) very large builders
|
||||
// while the chance that we will need their size is diminishingly small.
|
||||
// It makes sense to constrain the size to some "not too small" number.
|
||||
// Overall perf does not seem to be very sensitive to this number, so I picked 128 as a limit.
|
||||
if (this.Count < 128)
|
||||
{
|
||||
if (this.Count != 0)
|
||||
{
|
||||
this.Clear();
|
||||
}
|
||||
|
||||
pool.Free(this);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
pool.ForgetTrackedObject(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 2) Expose the pool or the way to create a pool or the way to get an instance.
|
||||
// for now we will expose both and figure which way works better
|
||||
private static readonly ObjectPool<ArrayBuilder<T>> s_poolInstance = CreatePool();
|
||||
public static ArrayBuilder<T> GetInstance()
|
||||
{
|
||||
var builder = s_poolInstance.Allocate();
|
||||
Debug.Assert(builder.Count == 0);
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static ArrayBuilder<T> GetInstance(int capacity)
|
||||
{
|
||||
var builder = GetInstance();
|
||||
builder.EnsureCapacity(capacity);
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static ArrayBuilder<T> GetInstance(int capacity, T fillWithValue)
|
||||
{
|
||||
var builder = GetInstance();
|
||||
builder.EnsureCapacity(capacity);
|
||||
|
||||
for (int i = 0; i < capacity; i++)
|
||||
{
|
||||
builder.Add(fillWithValue);
|
||||
}
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static ObjectPool<ArrayBuilder<T>> CreatePool()
|
||||
{
|
||||
return CreatePool(128); // we rarely need more than 10
|
||||
}
|
||||
|
||||
public static ObjectPool<ArrayBuilder<T>> CreatePool(int size)
|
||||
{
|
||||
ObjectPool<ArrayBuilder<T>> pool = null;
|
||||
pool = new ObjectPool<ArrayBuilder<T>>(() => new ArrayBuilder<T>(pool), size);
|
||||
return pool;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public Enumerator GetEnumerator()
|
||||
{
|
||||
return new Enumerator(this);
|
||||
}
|
||||
|
||||
IEnumerator<T> IEnumerable<T>.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
internal Dictionary<K, ImmutableArray<T>> ToDictionary<K>(Func<T, K> keySelector, IEqualityComparer<K> comparer = null)
|
||||
{
|
||||
if (this.Count == 1)
|
||||
{
|
||||
var dictionary1 = new Dictionary<K, ImmutableArray<T>>(1, comparer);
|
||||
T value = this[0];
|
||||
dictionary1.Add(keySelector(value), ImmutableArray.Create(value));
|
||||
return dictionary1;
|
||||
}
|
||||
|
||||
if (this.Count == 0)
|
||||
{
|
||||
return new Dictionary<K, ImmutableArray<T>>(comparer);
|
||||
}
|
||||
|
||||
// bucketize
|
||||
// prevent reallocation. it may not have 'count' entries, but it won't have more.
|
||||
var accumulator = new Dictionary<K, ArrayBuilder<T>>(Count, comparer);
|
||||
for (int i = 0; i < Count; i++)
|
||||
{
|
||||
var item = this[i];
|
||||
var key = keySelector(item);
|
||||
|
||||
ArrayBuilder<T> bucket;
|
||||
if (!accumulator.TryGetValue(key, out bucket))
|
||||
{
|
||||
bucket = ArrayBuilder<T>.GetInstance();
|
||||
accumulator.Add(key, bucket);
|
||||
}
|
||||
|
||||
bucket.Add(item);
|
||||
}
|
||||
|
||||
var dictionary = new Dictionary<K, ImmutableArray<T>>(accumulator.Count, comparer);
|
||||
|
||||
// freeze
|
||||
foreach (var pair in accumulator)
|
||||
{
|
||||
dictionary.Add(pair.Key, pair.Value.ToImmutableAndFree());
|
||||
}
|
||||
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
public void AddRange(ArrayBuilder<T> items)
|
||||
{
|
||||
_builder.AddRange(items._builder);
|
||||
}
|
||||
|
||||
public void AddRange<U>(ArrayBuilder<U> items) where U : T
|
||||
{
|
||||
_builder.AddRange(items._builder);
|
||||
}
|
||||
|
||||
public void AddRange(ImmutableArray<T> items)
|
||||
{
|
||||
_builder.AddRange(items);
|
||||
}
|
||||
|
||||
public void AddRange(ImmutableArray<T> items, int length)
|
||||
{
|
||||
_builder.AddRange(items, length);
|
||||
}
|
||||
|
||||
public void AddRange(T[] items, int start, int length)
|
||||
{
|
||||
for (int i = start, end = start + length; i < end; i++)
|
||||
{
|
||||
Add(items[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddRange(IEnumerable<T> items)
|
||||
{
|
||||
_builder.AddRange(items);
|
||||
}
|
||||
|
||||
public void AddRange(params T[] items)
|
||||
{
|
||||
_builder.AddRange(items);
|
||||
}
|
||||
|
||||
public void AddRange(T[] items, int length)
|
||||
{
|
||||
_builder.AddRange(items, length);
|
||||
}
|
||||
|
||||
public void Clip(int limit)
|
||||
{
|
||||
Debug.Assert(limit <= Count);
|
||||
_builder.Count = limit;
|
||||
}
|
||||
|
||||
public void ZeroInit(int count)
|
||||
{
|
||||
_builder.Clear();
|
||||
_builder.Count = count;
|
||||
}
|
||||
|
||||
public void AddMany(T item, int count)
|
||||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveDuplicates()
|
||||
{
|
||||
var set = PooledHashSet<T>.GetInstance();
|
||||
|
||||
int j = 0;
|
||||
for (int i = 0; i < Count; i++)
|
||||
{
|
||||
if (set.Add(this[i]))
|
||||
{
|
||||
this[j] = this[i];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
Clip(j);
|
||||
set.Free();
|
||||
}
|
||||
|
||||
public ImmutableArray<S> SelectDistinct<S>(Func<T, S> selector)
|
||||
{
|
||||
var result = ArrayBuilder<S>.GetInstance(Count);
|
||||
var set = PooledHashSet<S>.GetInstance();
|
||||
|
||||
foreach (var item in this)
|
||||
{
|
||||
var selected = selector(item);
|
||||
if (set.Add(selected))
|
||||
{
|
||||
result.Add(selected);
|
||||
}
|
||||
}
|
||||
|
||||
set.Free();
|
||||
return result.ToImmutableAndFree();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
|
||||
<HasSharedItems>true</HasSharedItems>
|
||||
<SharedGUID>c1930979-c824-496b-a630-70f5369a636f</SharedGUID>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration">
|
||||
<Import_RootNamespace>SharedCollections</Import_RootNamespace>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)ArrayBuilder.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)ArrayBuilder.Enumerator.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)ObjectPool`1.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)PooledDictionary.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)PooledHashSet.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)PooledStringBuilder.cs" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -1,21 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>c1930979-c824-496b-a630-70f5369a636f</ProjectGuid>
|
||||
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
|
||||
</PropertyGroup>
|
||||
<Import
|
||||
Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props"
|
||||
Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<Import
|
||||
Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.Default.props"
|
||||
Condition="Exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.Default.props')" />
|
||||
<Import
|
||||
Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.props"
|
||||
Condition="Exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.props')" />
|
||||
<PropertyGroup />
|
||||
<Import Project="Microsoft.CodeAnalysis.PooledObjects.projitems" Label="Shared" />
|
||||
<Import
|
||||
Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.CSharp.targets"
|
||||
Condition="Exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.CSharp.targets')" />
|
||||
</Project>
|
|
@ -1,279 +0,0 @@
|
|||
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
// define TRACE_LEAKS to get additional diagnostics that can lead to the leak sources. note: it will
|
||||
// make everything about 2-3x slower
|
||||
//
|
||||
// #define TRACE_LEAKS
|
||||
|
||||
// define DETECT_LEAKS to detect possible leaks
|
||||
// #if DEBUG
|
||||
// #define DETECT_LEAKS //for now always enable DETECT_LEAKS in debug.
|
||||
// #endif
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
|
||||
#if DETECT_LEAKS
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
#endif
|
||||
namespace Roslyn.Utilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Generic implementation of object pooling pattern with predefined pool size limit. The main
|
||||
/// purpose is that limited number of frequently used objects can be kept in the pool for
|
||||
/// further recycling.
|
||||
///
|
||||
/// Notes:
|
||||
/// 1) it is not the goal to keep all returned objects. Pool is not meant for storage. If there
|
||||
/// is no space in the pool, extra returned objects will be dropped.
|
||||
///
|
||||
/// 2) it is implied that if object was obtained from a pool, the caller will return it back in
|
||||
/// a relatively short time. Keeping checked out objects for long durations is ok, but
|
||||
/// reduces usefulness of pooling. Just new up your own.
|
||||
///
|
||||
/// Not returning objects to the pool in not detrimental to the pool's work, but is a bad practice.
|
||||
/// Rationale:
|
||||
/// If there is no intent for reusing the object, do not use pool - just use "new".
|
||||
/// </summary>
|
||||
internal class ObjectPool<T> where T : class
|
||||
{
|
||||
[DebuggerDisplay("{Value,nq}")]
|
||||
private struct Element
|
||||
{
|
||||
internal T Value;
|
||||
}
|
||||
|
||||
/// <remarks>
|
||||
/// Not using System.Func{T} because this file is linked into the (debugger) Formatter,
|
||||
/// which does not have that type (since it compiles against .NET 2.0).
|
||||
/// </remarks>
|
||||
internal delegate T Factory();
|
||||
|
||||
// Storage for the pool objects. The first item is stored in a dedicated field because we
|
||||
// expect to be able to satisfy most requests from it.
|
||||
private T _firstItem;
|
||||
private readonly Element[] _items;
|
||||
|
||||
// factory is stored for the lifetime of the pool. We will call this only when pool needs to
|
||||
// expand. compared to "new T()", Func gives more flexibility to implementers and faster
|
||||
// than "new T()".
|
||||
private readonly Factory _factory;
|
||||
|
||||
#if DETECT_LEAKS
|
||||
private static readonly ConditionalWeakTable<T, LeakTracker> leakTrackers = new ConditionalWeakTable<T, LeakTracker>();
|
||||
|
||||
private class LeakTracker : IDisposable
|
||||
{
|
||||
private volatile bool disposed;
|
||||
|
||||
#if TRACE_LEAKS
|
||||
internal volatile object Trace = null;
|
||||
#endif
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
disposed = true;
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
private string GetTrace()
|
||||
{
|
||||
#if TRACE_LEAKS
|
||||
return Trace == null ? "" : Trace.ToString();
|
||||
#else
|
||||
return "Leak tracing information is disabled. Define TRACE_LEAKS on ObjectPool`1.cs to get more info \n";
|
||||
#endif
|
||||
}
|
||||
|
||||
~LeakTracker()
|
||||
{
|
||||
if (!this.disposed && !Environment.HasShutdownStarted)
|
||||
{
|
||||
var trace = GetTrace();
|
||||
|
||||
// If you are seeing this message it means that object has been allocated from the pool
|
||||
// and has not been returned back. This is not critical, but turns pool into rather
|
||||
// inefficient kind of "new".
|
||||
Debug.WriteLine($"TRACEOBJECTPOOLLEAKS_BEGIN\nPool detected potential leaking of {typeof(T)}. \n Location of the leak: \n {GetTrace()} TRACEOBJECTPOOLLEAKS_END");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
internal ObjectPool(Factory factory)
|
||||
: this(factory, Environment.ProcessorCount * 2)
|
||||
{ }
|
||||
|
||||
internal ObjectPool(Factory factory, int size)
|
||||
{
|
||||
Debug.Assert(size >= 1);
|
||||
_factory = factory;
|
||||
_items = new Element[size - 1];
|
||||
}
|
||||
|
||||
private T CreateInstance()
|
||||
{
|
||||
var inst = _factory();
|
||||
return inst;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Produces an instance.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Search strategy is a simple linear probing which is chosen for it cache-friendliness.
|
||||
/// Note that Free will try to store recycled objects close to the start thus statistically
|
||||
/// reducing how far we will typically search.
|
||||
/// </remarks>
|
||||
internal T Allocate()
|
||||
{
|
||||
// PERF: Examine the first element. If that fails, AllocateSlow will look at the remaining elements.
|
||||
// Note that the initial read is optimistically not synchronized. That is intentional.
|
||||
// We will interlock only when we have a candidate. in a worst case we may miss some
|
||||
// recently returned objects. Not a big deal.
|
||||
T inst = _firstItem;
|
||||
if (inst == null || inst != Interlocked.CompareExchange(ref _firstItem, null, inst))
|
||||
{
|
||||
inst = AllocateSlow();
|
||||
}
|
||||
|
||||
#if DETECT_LEAKS
|
||||
var tracker = new LeakTracker();
|
||||
leakTrackers.Add(inst, tracker);
|
||||
|
||||
#if TRACE_LEAKS
|
||||
var frame = CaptureStackTrace();
|
||||
tracker.Trace = frame;
|
||||
#endif
|
||||
#endif
|
||||
return inst;
|
||||
}
|
||||
|
||||
private T AllocateSlow()
|
||||
{
|
||||
var items = _items;
|
||||
|
||||
for (int i = 0; i < items.Length; i++)
|
||||
{
|
||||
// Note that the initial read is optimistically not synchronized. That is intentional.
|
||||
// We will interlock only when we have a candidate. in a worst case we may miss some
|
||||
// recently returned objects. Not a big deal.
|
||||
T inst = items[i].Value;
|
||||
if (inst != null)
|
||||
{
|
||||
if (inst == Interlocked.CompareExchange(ref items[i].Value, null, inst))
|
||||
{
|
||||
return inst;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return CreateInstance();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns objects to the pool.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Search strategy is a simple linear probing which is chosen for it cache-friendliness.
|
||||
/// Note that Free will try to store recycled objects close to the start thus statistically
|
||||
/// reducing how far we will typically search in Allocate.
|
||||
/// </remarks>
|
||||
internal void Free(T obj)
|
||||
{
|
||||
Validate(obj);
|
||||
ForgetTrackedObject(obj);
|
||||
|
||||
if (_firstItem == null)
|
||||
{
|
||||
// Intentionally not using interlocked here.
|
||||
// In a worst case scenario two objects may be stored into same slot.
|
||||
// It is very unlikely to happen and will only mean that one of the objects will get collected.
|
||||
_firstItem = obj;
|
||||
}
|
||||
else
|
||||
{
|
||||
FreeSlow(obj);
|
||||
}
|
||||
}
|
||||
|
||||
private void FreeSlow(T obj)
|
||||
{
|
||||
var items = _items;
|
||||
for (int i = 0; i < items.Length; i++)
|
||||
{
|
||||
if (items[i].Value == null)
|
||||
{
|
||||
// Intentionally not using interlocked here.
|
||||
// In a worst case scenario two objects may be stored into same slot.
|
||||
// It is very unlikely to happen and will only mean that one of the objects will get collected.
|
||||
items[i].Value = obj;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes an object from leak tracking.
|
||||
///
|
||||
/// This is called when an object is returned to the pool. It may also be explicitly
|
||||
/// called if an object allocated from the pool is intentionally not being returned
|
||||
/// to the pool. This can be of use with pooled arrays if the consumer wants to
|
||||
/// return a larger array to the pool than was originally allocated.
|
||||
/// </summary>
|
||||
[Conditional("DEBUG")]
|
||||
internal void ForgetTrackedObject(T old, T replacement = null)
|
||||
{
|
||||
#if DETECT_LEAKS
|
||||
LeakTracker tracker;
|
||||
if (leakTrackers.TryGetValue(old, out tracker))
|
||||
{
|
||||
tracker.Dispose();
|
||||
leakTrackers.Remove(old);
|
||||
}
|
||||
else
|
||||
{
|
||||
var trace = CaptureStackTrace();
|
||||
Debug.WriteLine($"TRACEOBJECTPOOLLEAKS_BEGIN\nObject of type {typeof(T)} was freed, but was not from pool. \n Callstack: \n {trace} TRACEOBJECTPOOLLEAKS_END");
|
||||
}
|
||||
|
||||
if (replacement != null)
|
||||
{
|
||||
tracker = new LeakTracker();
|
||||
leakTrackers.Add(replacement, tracker);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if DETECT_LEAKS
|
||||
private static Lazy<Type> _stackTraceType = new Lazy<Type>(() => Type.GetType("System.Diagnostics.StackTrace"));
|
||||
|
||||
private static object CaptureStackTrace()
|
||||
{
|
||||
return Activator.CreateInstance(_stackTraceType.Value);
|
||||
}
|
||||
#endif
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
private void Validate(object obj)
|
||||
{
|
||||
Debug.Assert(obj != null, "freeing null?");
|
||||
|
||||
Debug.Assert(_firstItem != obj, "freeing twice?");
|
||||
|
||||
var items = _items;
|
||||
for (int i = 0; i < items.Length; i++)
|
||||
{
|
||||
var value = items[i].Value;
|
||||
if (value == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Assert(value != obj, "freeing twice?");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics;
|
||||
using Roslyn.Utilities;
|
||||
|
||||
namespace Microsoft.CodeAnalysis.Collections
|
||||
{
|
||||
// Dictionary that can be recycled via an object pool
|
||||
// NOTE: these dictionaries always have the default comparer.
|
||||
internal class PooledDictionary<K, V> : Dictionary<K, V>
|
||||
{
|
||||
private readonly ObjectPool<PooledDictionary<K, V>> _pool;
|
||||
|
||||
private PooledDictionary(ObjectPool<PooledDictionary<K, V>> pool)
|
||||
{
|
||||
_pool = pool;
|
||||
}
|
||||
|
||||
public ImmutableDictionary<K, V> ToImmutableDictionaryAndFree()
|
||||
{
|
||||
var result = this.ToImmutableDictionary();
|
||||
this.Free();
|
||||
return result;
|
||||
}
|
||||
|
||||
public void Free()
|
||||
{
|
||||
this.Clear();
|
||||
_pool?.Free(this);
|
||||
}
|
||||
|
||||
// global pool
|
||||
private static readonly ObjectPool<PooledDictionary<K, V>> s_poolInstance = CreatePool();
|
||||
|
||||
// if someone needs to create a pool;
|
||||
public static ObjectPool<PooledDictionary<K, V>> CreatePool()
|
||||
{
|
||||
ObjectPool<PooledDictionary<K, V>> pool = null;
|
||||
pool = new ObjectPool<PooledDictionary<K, V>>(() => new PooledDictionary<K, V>(pool), 128);
|
||||
return pool;
|
||||
}
|
||||
|
||||
public static PooledDictionary<K, V> GetInstance()
|
||||
{
|
||||
var instance = s_poolInstance.Allocate();
|
||||
Debug.Assert(instance.Count == 0);
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using Roslyn.Utilities;
|
||||
|
||||
namespace Microsoft.CodeAnalysis.Collections
|
||||
{
|
||||
// HashSet that can be recycled via an object pool
|
||||
// NOTE: these HashSets always have the default comparer.
|
||||
internal class PooledHashSet<T> : HashSet<T>
|
||||
{
|
||||
private readonly ObjectPool<PooledHashSet<T>> _pool;
|
||||
|
||||
private PooledHashSet(ObjectPool<PooledHashSet<T>> pool)
|
||||
{
|
||||
_pool = pool;
|
||||
}
|
||||
|
||||
public void Free()
|
||||
{
|
||||
this.Clear();
|
||||
_pool?.Free(this);
|
||||
}
|
||||
|
||||
// global pool
|
||||
private static readonly ObjectPool<PooledHashSet<T>> s_poolInstance = CreatePool();
|
||||
|
||||
// if someone needs to create a pool;
|
||||
public static ObjectPool<PooledHashSet<T>> CreatePool()
|
||||
{
|
||||
ObjectPool<PooledHashSet<T>> pool = null;
|
||||
pool = new ObjectPool<PooledHashSet<T>>(() => new PooledHashSet<T>(pool), 128);
|
||||
return pool;
|
||||
}
|
||||
|
||||
public static PooledHashSet<T> GetInstance()
|
||||
{
|
||||
var instance = s_poolInstance.Allocate();
|
||||
Debug.Assert(instance.Count == 0);
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,94 +0,0 @@
|
|||
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using Roslyn.Utilities;
|
||||
|
||||
namespace Microsoft.CodeAnalysis.Collections
|
||||
{
|
||||
/// <summary>
|
||||
/// The usage is:
|
||||
/// var inst = PooledStringBuilder.GetInstance();
|
||||
/// var sb = inst.builder;
|
||||
/// ... Do Stuff...
|
||||
/// ... sb.ToString() ...
|
||||
/// inst.Free();
|
||||
/// </summary>
|
||||
internal class PooledStringBuilder
|
||||
{
|
||||
public readonly StringBuilder Builder = new StringBuilder();
|
||||
private readonly ObjectPool<PooledStringBuilder> _pool;
|
||||
|
||||
private PooledStringBuilder(ObjectPool<PooledStringBuilder> pool)
|
||||
{
|
||||
Debug.Assert(pool != null);
|
||||
_pool = pool;
|
||||
}
|
||||
|
||||
public int Length
|
||||
{
|
||||
get { return this.Builder.Length; }
|
||||
}
|
||||
|
||||
public void Free()
|
||||
{
|
||||
var builder = this.Builder;
|
||||
|
||||
// do not store builders that are too large.
|
||||
if (builder.Capacity <= 1024)
|
||||
{
|
||||
builder.Clear();
|
||||
_pool.Free(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
_pool.ForgetTrackedObject(this);
|
||||
}
|
||||
}
|
||||
|
||||
[System.Obsolete("Consider calling ToStringAndFree instead.")]
|
||||
public new string ToString()
|
||||
{
|
||||
return this.Builder.ToString();
|
||||
}
|
||||
|
||||
public string ToStringAndFree()
|
||||
{
|
||||
string result = this.Builder.ToString();
|
||||
this.Free();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public string ToStringAndFree(int startIndex, int length)
|
||||
{
|
||||
string result = this.Builder.ToString(startIndex, length);
|
||||
this.Free();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// global pool
|
||||
private static readonly ObjectPool<PooledStringBuilder> s_poolInstance = CreatePool();
|
||||
|
||||
// if someone needs to create a private pool;
|
||||
public static ObjectPool<PooledStringBuilder> CreatePool()
|
||||
{
|
||||
ObjectPool<PooledStringBuilder> pool = null;
|
||||
pool = new ObjectPool<PooledStringBuilder>(() => new PooledStringBuilder(pool), 32);
|
||||
return pool;
|
||||
}
|
||||
|
||||
public static PooledStringBuilder GetInstance()
|
||||
{
|
||||
var builder = s_poolInstance.Allocate();
|
||||
Debug.Assert(builder.Builder.Length == 0);
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static implicit operator StringBuilder(PooledStringBuilder obj)
|
||||
{
|
||||
return obj.Builder;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -->
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ImportGroup>
|
||||
<Import Project="..\..\build\Targets\Settings.targets" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup>
|
||||
<ProjectGuid>{12421910-7B1F-457A-8958-84DE13734F9B}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<RootNamespace>Microsoft.DiaSymReader.Converter.UnitTests</RootNamespace>
|
||||
<AssemblyName>Microsoft.DiaSymReader.Converter.UnitTests</AssemblyName>
|
||||
<TargetFrameworkVersion>v5.0</TargetFrameworkVersion>
|
||||
<TargetFrameworkProfile>
|
||||
</TargetFrameworkProfile>
|
||||
<TargetFrameworkIdentifier>.NETPortable</TargetFrameworkIdentifier>
|
||||
<NuGetTargetMoniker>.NETStandard,Version=v1.3</NuGetTargetMoniker>
|
||||
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'" />
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Microsoft.DiaSymReader.PortablePdb\Microsoft.DiaSymReader.PortablePdb.csproj">
|
||||
<Project>{f83343ba-b4ea-451c-b6db-5d645e6171bc}</Project>
|
||||
<Name>Microsoft.DiaSymReader.PortablePdb</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Microsoft.DiaSymReader.Converter\Microsoft.DiaSymReader.Converter.csproj">
|
||||
<Project>{C0122B3F-86F0-4114-86F6-321535394C4E}</Project>
|
||||
<Name>Microsoft.DiaSymReader.Converter</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\Shared\App.config" />
|
||||
<None Include="project.json" />
|
||||
<None Include="Microsoft.DiaSymReader.Converter.UnitTests.xunit.runner.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="PdbConverterTests.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
|
||||
</ItemGroup>
|
||||
<ImportGroup>
|
||||
<Import Project="..\..\build\Targets\Imports.targets" />
|
||||
<Import Project="..\..\build\Toolset\XunitProjectRunAction.targets" />
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"shadowCopy": false
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.DiaSymReader.Tools.UnitTests
|
||||
{
|
||||
public class PdbConverterTests
|
||||
{
|
||||
[Fact]
|
||||
public void Convert()
|
||||
{
|
||||
Assert.Throws<ArgumentNullException>(() => PdbConverter.Convert(null, new MemoryStream(), new MemoryStream()));
|
||||
Assert.Throws<ArgumentNullException>(() => PdbConverter.Convert(new MemoryStream(), null, new MemoryStream()));
|
||||
Assert.Throws<ArgumentNullException>(() => PdbConverter.Convert(new MemoryStream(), new MemoryStream(), null));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"Microsoft.DiaSymReader.Native": "1.5.0-beta1",
|
||||
"Microsoft.NETCore.Portable.Compatibility": "1.0.1",
|
||||
"System.Collections": "4.3.0",
|
||||
"System.Diagnostics.Debug": "4.3.0",
|
||||
"System.IO.FileSystem": "4.3.0",
|
||||
"System.Runtime": "4.3.0",
|
||||
"System.Runtime.Extensions": "4.3.0",
|
||||
"System.Runtime.InteropServices": "4.3.0",
|
||||
"Microsoft.DiaSymReader.Native": "1.5.0-beta2-24728",
|
||||
"xunit": "2.2.0-beta4-build3444",
|
||||
"xunit.runner.console": "2.2.0-beta4-build3444",
|
||||
"xunit.runner.visualstudio": "2.2.0-beta4-build1194"
|
||||
},
|
||||
"frameworks": {
|
||||
"netstandard1.3": {
|
||||
"imports": [ "portable-net452", "dotnet5.4" ]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,132 +0,0 @@
|
|||
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Reflection.Metadata.Ecma335;
|
||||
using Roslyn.Utilities;
|
||||
|
||||
namespace Microsoft.DiaSymReader.Tools
|
||||
{
|
||||
internal sealed class ConstantSignatureConverter
|
||||
{
|
||||
public unsafe static void Convert(BlobBuilder builder, MetadataModel metadataModel, byte[] signature, object value)
|
||||
{
|
||||
fixed (byte* sigPtr = signature)
|
||||
{
|
||||
var sigReader = new BlobReader(sigPtr, signature.Length);
|
||||
|
||||
// copy custom modifiers over:
|
||||
byte rawTypeCode;
|
||||
while (true)
|
||||
{
|
||||
rawTypeCode = sigReader.ReadByte();
|
||||
if (rawTypeCode != (int)SignatureTypeCode.OptionalModifier && rawTypeCode != (int)SignatureTypeCode.RequiredModifier)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
builder.WriteByte(rawTypeCode);
|
||||
builder.WriteCompressedInteger(sigReader.ReadCompressedInteger());
|
||||
}
|
||||
|
||||
switch ((SignatureTypeCode)rawTypeCode)
|
||||
{
|
||||
case (SignatureTypeCode)SignatureTypeKind.Class:
|
||||
case (SignatureTypeCode)SignatureTypeKind.ValueType:
|
||||
int typeRefDefSpec = sigReader.ReadCompressedInteger();
|
||||
|
||||
if (value is decimal)
|
||||
{
|
||||
// GeneralConstant: VALUETYPE TypeDefOrRefOrSpecEncoded <decimal>
|
||||
builder.WriteByte((byte)SignatureTypeKind.ValueType);
|
||||
builder.WriteCompressedInteger(typeRefDefSpec);
|
||||
builder.WriteDecimal((decimal)value);
|
||||
}
|
||||
else if (value is DateTime)
|
||||
{
|
||||
// GeneralConstant: VALUETYPE TypeDefOrRefOrSpecEncoded <date-time>
|
||||
builder.WriteByte((byte)SignatureTypeKind.ValueType);
|
||||
builder.WriteCompressedInteger(typeRefDefSpec);
|
||||
builder.WriteDateTime((DateTime)value);
|
||||
}
|
||||
else if (value == null)
|
||||
{
|
||||
// GeneralConstant: CLASS TypeDefOrRefOrSpecEncoded
|
||||
builder.WriteByte(rawTypeCode);
|
||||
builder.WriteCompressedInteger(typeRefDefSpec);
|
||||
}
|
||||
else
|
||||
{
|
||||
// EnumConstant ::= EnumTypeCode EnumValue EnumType
|
||||
// EnumTypeCode ::= BOOLEAN | CHAR | I1 | U1 | I2 | U2 | I4 | U4 | I8 | U8
|
||||
// EnumType ::= TypeDefOrRefOrSpecEncoded
|
||||
|
||||
var enumTypeCode = MetadataHelpers.GetConstantTypeCode(value);
|
||||
builder.WriteByte((byte)enumTypeCode);
|
||||
builder.WriteConstant(value);
|
||||
builder.WriteCompressedInteger(typeRefDefSpec);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SignatureTypeCode.Object:
|
||||
// null:
|
||||
Debug.Assert(value == null);
|
||||
builder.WriteByte((byte)SignatureTypeCode.Object);
|
||||
break;
|
||||
|
||||
case SignatureTypeCode.Boolean:
|
||||
case SignatureTypeCode.Char:
|
||||
case SignatureTypeCode.SByte:
|
||||
case SignatureTypeCode.Byte:
|
||||
case SignatureTypeCode.Int16:
|
||||
case SignatureTypeCode.UInt16:
|
||||
case SignatureTypeCode.Int32:
|
||||
case SignatureTypeCode.UInt32:
|
||||
case SignatureTypeCode.Int64:
|
||||
case SignatureTypeCode.UInt64:
|
||||
case SignatureTypeCode.Single:
|
||||
case SignatureTypeCode.Double:
|
||||
case SignatureTypeCode.String:
|
||||
// PrimitiveConstant
|
||||
builder.WriteByte(rawTypeCode);
|
||||
builder.WriteConstant(value);
|
||||
break;
|
||||
|
||||
case SignatureTypeCode.SZArray:
|
||||
case SignatureTypeCode.Array:
|
||||
case SignatureTypeCode.GenericTypeInstance:
|
||||
Debug.Assert(value == null);
|
||||
|
||||
// Find an existing TypeSpec in metadata.
|
||||
// If there isn't one we can't represent the constant type in the Portable PDB, use Object.
|
||||
|
||||
// +1/-1 for the type code we already read.
|
||||
var spec = new byte[sigReader.RemainingBytes + 1];
|
||||
Buffer.BlockCopy(signature, sigReader.Offset - 1, spec, 0, spec.Length);
|
||||
|
||||
TypeSpecificationHandle typeSpec;
|
||||
if (metadataModel.TryResolveTypeSpecification(spec, out typeSpec))
|
||||
{
|
||||
builder.WriteCompressedInteger(CodedIndex.TypeDefOrRefOrSpec(typeSpec));
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: warning - can't translate const type
|
||||
builder.WriteByte((byte)SignatureTypeCode.Object);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SignatureTypeCode.GenericMethodParameter:
|
||||
case SignatureTypeCode.GenericTypeParameter:
|
||||
case SignatureTypeCode.FunctionPointer:
|
||||
case SignatureTypeCode.Pointer:
|
||||
// generic parameters, pointers are not valid types for constants:
|
||||
throw new BadImageFormatException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,161 +0,0 @@
|
|||
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Reflection.Metadata.Ecma335;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Microsoft.DiaSymReader.Tools
|
||||
{
|
||||
internal static class IMetadataImportExtensions
|
||||
{
|
||||
public static string GetQualifiedTypeName(this IMetadataImport importer, Handle typeDefOrRef)
|
||||
{
|
||||
string qualifiedName;
|
||||
if (typeDefOrRef.Kind == HandleKind.TypeDefinition)
|
||||
{
|
||||
TypeAttributes attributes;
|
||||
int baseType;
|
||||
importer.GetTypeDefProps(MetadataTokens.GetToken(typeDefOrRef), out qualifiedName, out attributes, out baseType);
|
||||
}
|
||||
else if (typeDefOrRef.Kind == HandleKind.TypeReference)
|
||||
{
|
||||
int resolutionScope;
|
||||
importer.GetTypeRefProps(MetadataTokens.GetToken(typeDefOrRef), out resolutionScope, out qualifiedName);
|
||||
}
|
||||
else
|
||||
{
|
||||
qualifiedName = null;
|
||||
}
|
||||
|
||||
return qualifiedName;
|
||||
}
|
||||
|
||||
public static void GetTypeDefProps(this IMetadataImport importer, int typeDefinition, out string qualifiedName, out TypeAttributes attributes, out int baseType)
|
||||
{
|
||||
int bufferLength;
|
||||
importer.GetTypeDefProps(typeDefinition, null, 0, out bufferLength, out attributes, out baseType);
|
||||
|
||||
var buffer = new StringBuilder(bufferLength);
|
||||
importer.GetTypeDefProps(typeDefinition, buffer, buffer.Capacity, out bufferLength, out attributes, out baseType);
|
||||
qualifiedName = buffer.ToString();
|
||||
}
|
||||
|
||||
public static void GetTypeRefProps(this IMetadataImport importer, int typeReference, out int resolutionScope, out string qualifiedName)
|
||||
{
|
||||
int bufferLength;
|
||||
importer.GetTypeRefProps(typeReference, out resolutionScope, null, 0, out bufferLength);
|
||||
|
||||
var buffer = new StringBuilder(bufferLength);
|
||||
importer.GetTypeRefProps(typeReference, out resolutionScope, buffer, buffer.Capacity, out bufferLength);
|
||||
qualifiedName = buffer.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
[ComVisible(false)]
|
||||
[ComImport]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
[Guid("7DAC8207-D3AE-4c75-9B67-92801A497D44")]
|
||||
internal unsafe interface IMetadataImport
|
||||
{
|
||||
[PreserveSig]
|
||||
void CloseEnum(uint handleEnum);
|
||||
uint CountEnum(uint handleEnum);
|
||||
void ResetEnum(uint handleEnum, uint ulongPos);
|
||||
uint EnumTypeDefs(ref uint handlePointerEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] arrayTypeDefs, uint countMax);
|
||||
uint EnumInterfaceImpls(ref uint handlePointerEnum, uint td, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] uint[] arrayImpls, uint countMax);
|
||||
uint EnumTypeRefs(ref uint handlePointerEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] arrayTypeRefs, uint countMax);
|
||||
uint FindTypeDefByName(string stringTypeDef, uint tokenEnclosingClass);
|
||||
Guid GetScopeProps(StringBuilder stringName, uint cchName, out uint pchName);
|
||||
uint GetModuleFromScope();
|
||||
|
||||
void GetTypeDefProps(
|
||||
int typeDefinition,
|
||||
[Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder qualifiedName,
|
||||
int qualifiedNameBufferLength,
|
||||
out int qualifiedNameLength,
|
||||
[MarshalAs(UnmanagedType.U4)] out TypeAttributes attributes,
|
||||
out int baseType);
|
||||
|
||||
uint GetInterfaceImplProps(uint impl, out uint pointerClass);
|
||||
|
||||
void GetTypeRefProps(
|
||||
int typeReference,
|
||||
out int resolutionScope,
|
||||
[Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder qualifiedName,
|
||||
int qualifiedNameBufferLength,
|
||||
out int qualifiedNameLength);
|
||||
|
||||
uint ResolveTypeRef(uint tr, [In] ref Guid riid, [MarshalAs(UnmanagedType.Interface)] out object ppIScope);
|
||||
uint EnumMembers(ref uint handlePointerEnum, uint cl, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] uint[] arrayMembers, uint countMax);
|
||||
uint EnumMembersWithName(ref uint handlePointerEnum, uint cl, string stringName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] arrayMembers, uint countMax);
|
||||
uint EnumMethods(ref uint handlePointerEnum, uint cl, uint* arrayMethods, uint countMax);
|
||||
uint EnumMethodsWithName(ref uint handlePointerEnum, uint cl, string stringName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] arrayMethods, uint countMax);
|
||||
uint EnumFields(ref uint handlePointerEnum, uint cl, uint* arrayFields, uint countMax);
|
||||
uint EnumFieldsWithName(ref uint handlePointerEnum, uint cl, string stringName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] arrayFields, uint countMax);
|
||||
uint EnumParams(ref uint handlePointerEnum, uint mb, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] uint[] arrayParams, uint countMax);
|
||||
uint EnumMemberRefs(ref uint handlePointerEnum, uint tokenParent, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] uint[] arrayMemberRefs, uint countMax);
|
||||
uint EnumMethodImpls(ref uint handlePointerEnum, uint td, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] arrayMethodBody,
|
||||
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] arrayMethodDecl, uint countMax);
|
||||
uint EnumPermissionSets(ref uint handlePointerEnum, uint tk, uint dwordActions, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] arrayPermission,
|
||||
uint countMax);
|
||||
uint FindMember(uint td, string stringName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] byte[] voidPointerSigBlob, uint byteCountSigBlob);
|
||||
uint FindMethod(uint td, string stringName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] byte[] voidPointerSigBlob, uint byteCountSigBlob);
|
||||
uint FindField(uint td, string stringName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] byte[] voidPointerSigBlob, uint byteCountSigBlob);
|
||||
uint FindMemberRef(uint td, string stringName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] byte[] voidPointerSigBlob, uint byteCountSigBlob);
|
||||
uint GetMethodProps(uint mb, out uint pointerClass, IntPtr stringMethod, uint cchMethod, out uint pchMethod, IntPtr pdwAttr,
|
||||
IntPtr ppvSigBlob, IntPtr pcbSigBlob, IntPtr pulCodeRVA);
|
||||
unsafe uint GetMemberRefProps(uint mr, ref uint ptk, StringBuilder stringMember, uint cchMember, out uint pchMember, out byte* ppvSigBlob);
|
||||
uint EnumProperties(ref uint handlePointerEnum, uint td, uint* arrayProperties, uint countMax);
|
||||
uint EnumEvents(ref uint handlePointerEnum, uint td, uint* arrayEvents, uint countMax);
|
||||
uint GetEventProps(uint ev, out uint pointerClass, StringBuilder stringEvent, uint cchEvent, out uint pchEvent, out uint pdwEventFlags,
|
||||
out uint ptkEventType, out uint pmdAddOn, out uint pmdRemoveOn, out uint pmdFire,
|
||||
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 11)] uint[] rmdOtherMethod, uint countMax);
|
||||
uint EnumMethodSemantics(ref uint handlePointerEnum, uint mb, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] uint[] arrayEventProp, uint countMax);
|
||||
uint GetMethodSemantics(uint mb, uint tokenEventProp);
|
||||
uint GetClassLayout(uint td, out uint pdwPackSize, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] ulong[] arrayFieldOffset, uint countMax, out uint countPointerFieldOffset);
|
||||
unsafe uint GetFieldMarshal(uint tk, out byte* ppvNativeType);
|
||||
uint GetRVA(uint tk, out uint pulCodeRVA);
|
||||
unsafe uint GetPermissionSetProps(uint pm, out uint pdwAction, out void* ppvPermission);
|
||||
|
||||
[PreserveSig]
|
||||
unsafe int GetSigFromToken(
|
||||
int tkSignature, // Signature token.
|
||||
out byte* ppvSig, // return pointer to signature blob
|
||||
out int pcbSig); // return size of signature
|
||||
|
||||
uint GetModuleRefProps(uint mur, StringBuilder stringName, uint cchName);
|
||||
uint EnumModuleRefs(ref uint handlePointerEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] arrayModuleRefs, uint cmax);
|
||||
unsafe uint GetTypeSpecFromToken(uint typespec, out byte* ppvSig);
|
||||
uint GetNameFromToken(uint tk);
|
||||
uint EnumUnresolvedMethods(ref uint handlePointerEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] arrayMethods, uint countMax);
|
||||
uint GetUserString(uint stk, StringBuilder stringString, uint cchString);
|
||||
uint GetPinvokeMap(uint tk, out uint pdwMappingFlags, StringBuilder stringImportName, uint cchImportName, out uint pchImportName);
|
||||
uint EnumSignatures(ref uint handlePointerEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] arraySignatures, uint cmax);
|
||||
uint EnumTypeSpecs(ref uint handlePointerEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] arrayTypeSpecs, uint cmax);
|
||||
uint EnumUserStrings(ref uint handlePointerEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] arrayStrings, uint cmax);
|
||||
[PreserveSig]
|
||||
int GetParamForMethodIndex(uint md, uint ulongParamSeq, out uint pointerParam);
|
||||
uint EnumCustomAttributes(ref uint handlePointerEnum, uint tk, uint tokenType, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] arrayCustomAttributes, uint countMax);
|
||||
uint GetCustomAttributeProps(uint cv, out uint ptkObj, out uint ptkType, out void* ppBlob);
|
||||
uint FindTypeRef(uint tokenResolutionScope, string stringName);
|
||||
uint GetMemberProps(uint mb, out uint pointerClass, StringBuilder stringMember, uint cchMember, out uint pchMember, out uint pdwAttr,
|
||||
out byte* ppvSigBlob, out uint pcbSigBlob, out uint pulCodeRVA, out uint pdwImplFlags, out uint pdwCPlusTypeFlag, out void* ppValue);
|
||||
uint GetFieldProps(uint mb, out uint pointerClass, StringBuilder stringField, uint cchField, out uint pchField, out uint pdwAttr,
|
||||
out byte* ppvSigBlob, out uint pcbSigBlob, out uint pdwCPlusTypeFlag, out void* ppValue);
|
||||
uint GetPropertyProps(uint prop, out uint pointerClass, StringBuilder stringProperty, uint cchProperty, out uint pchProperty, out uint pdwPropFlags,
|
||||
out byte* ppvSig, out uint bytePointerSig, out uint pdwCPlusTypeFlag, out void* ppDefaultValue, out uint pcchDefaultValue, out uint pmdSetter,
|
||||
out uint pmdGetter, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 14)] uint[] rmdOtherMethod, uint countMax);
|
||||
uint GetParamProps(uint tk, out uint pmd, out uint pulSequence, StringBuilder stringName, uint cchName, out uint pchName,
|
||||
out uint pdwAttr, out uint pdwCPlusTypeFlag, out void* ppValue);
|
||||
uint GetCustomAttributeByName(uint tokenObj, string stringName, out void* ppData);
|
||||
[PreserveSig]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
bool IsValidToken(uint tk);
|
||||
uint GetNestedClassProps(uint typeDefNestedClass);
|
||||
uint GetNativeCallConvFromSig(void* voidPointerSig, uint byteCountSig);
|
||||
int IsGlobal(uint pd);
|
||||
}
|
||||
}
|
|
@ -1,377 +0,0 @@
|
|||
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Reflection.Metadata.Ecma335;
|
||||
using System.Text.RegularExpressions;
|
||||
using Microsoft.CodeAnalysis.Collections;
|
||||
using Roslyn.Utilities;
|
||||
|
||||
namespace Microsoft.DiaSymReader.Tools
|
||||
{
|
||||
internal sealed class MetadataModel
|
||||
{
|
||||
public MetadataReader Reader { get; }
|
||||
|
||||
private readonly Lazy<ValueTuple<Dictionary<string, AssemblyReferenceHandle>, string[]>> _lazyAssemblyRefMap;
|
||||
|
||||
private readonly Lazy<Dictionary<byte[], TypeSpecificationHandle>> _lazyTypeSpecificationMap;
|
||||
|
||||
private readonly Lazy<Dictionary<string, EntityHandle>> _lazyTypeMap;
|
||||
|
||||
public MetadataModel(MetadataReader reader)
|
||||
{
|
||||
Reader = reader;
|
||||
|
||||
_lazyAssemblyRefMap = new Lazy<ValueTuple<Dictionary<string, AssemblyReferenceHandle>, string[]>>(BuildAssemblyRefMap);
|
||||
_lazyTypeSpecificationMap = new Lazy<Dictionary<byte[], TypeSpecificationHandle>>(BuildTypeSpecificationMap);
|
||||
_lazyTypeMap = new Lazy<Dictionary<string, EntityHandle>>(BuildTypeMap);
|
||||
}
|
||||
|
||||
public ImmutableArray<int> GetRowCounts()
|
||||
{
|
||||
var builder = ImmutableArray.CreateBuilder<int>(MetadataTokens.TableCount);
|
||||
for (int i = 0; i < MetadataTokens.TableCount; i++)
|
||||
{
|
||||
builder.Add(Reader.GetTableRowCount((TableIndex)i));
|
||||
}
|
||||
|
||||
return builder.MoveToImmutable();
|
||||
}
|
||||
|
||||
private ValueTuple<Dictionary<string, AssemblyReferenceHandle>, string[]> BuildAssemblyRefMap()
|
||||
{
|
||||
var assemblyRefsByName = new Dictionary<string, AssemblyReferenceHandle>(StringComparer.OrdinalIgnoreCase);
|
||||
var assemblyNames = new string[Reader.AssemblyReferences.Count];
|
||||
|
||||
foreach (var handle in Reader.AssemblyReferences)
|
||||
{
|
||||
var displayName = MetadataHelpers.GetAssemblyDisplayName(Reader, Reader.GetAssemblyReference(handle));
|
||||
|
||||
assemblyNames[MetadataTokens.GetRowNumber(handle)] = displayName;
|
||||
assemblyRefsByName.Add(displayName, handle);
|
||||
}
|
||||
|
||||
return ValueTuple.Create(assemblyRefsByName, assemblyNames);
|
||||
}
|
||||
|
||||
public bool TryResolveAssemblyReference(string displayName, out AssemblyReferenceHandle handle) =>
|
||||
_lazyAssemblyRefMap.Value.Item1.TryGetValue(displayName, out handle);
|
||||
|
||||
public string GetAssemblyDisplayName(AssemblyReferenceHandle? handle) =>
|
||||
GetAssemblyDisplayName(_lazyAssemblyRefMap.Value.Item2, handle);
|
||||
|
||||
private static string GetAssemblyDisplayName(string[] displayNames, AssemblyReferenceHandle? handle) =>
|
||||
handle.HasValue ? displayNames[MetadataTokens.GetRowNumber(handle.Value)] : CoreLibPlaceholder;
|
||||
|
||||
private Dictionary<byte[], TypeSpecificationHandle> BuildTypeSpecificationMap()
|
||||
{
|
||||
var result = new Dictionary<byte[], TypeSpecificationHandle>(ByteSequenceComparer.Instance);
|
||||
|
||||
for (int rowId = 1; rowId <= Reader.GetTableRowCount(TableIndex.TypeSpec); rowId++)
|
||||
{
|
||||
var handle = MetadataTokens.TypeSpecificationHandle(rowId);
|
||||
var typeSpec = Reader.GetTypeSpecification(handle);
|
||||
|
||||
result[Reader.GetBlobBytes(typeSpec.Signature)] = handle;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool TryResolveTypeSpecification(byte[] spec, out TypeSpecificationHandle typeSpec) =>
|
||||
_lazyTypeSpecificationMap.Value.TryGetValue(spec, out typeSpec);
|
||||
|
||||
private static readonly Regex s_primitiveTypePattern = new Regex(
|
||||
@"((System.Void|System.Boolean|System.Char|System.SByte|System.Byte|System.Int16|System.UInt16|System.Int32|System.UInt32|System.Int64|System.UInt64|System.Single|System.Double|System.String|System.TypedReference|System.IntPtr|System.UIntPtr)[][*&,]*), ([^,]+), Version=[0-9]+.[0-9]+.[0-9]+.[0-9]+, Culture=neutral, PublicKeyToken=[a-zA-Z0-9]+",
|
||||
RegexOptions.Compiled);
|
||||
|
||||
private const string CoreLibPlaceholder = "{CORLIB}";
|
||||
|
||||
internal bool TryResolveType(string assemblyQualifiedName, out EntityHandle type)
|
||||
{
|
||||
if (_lazyTypeMap.Value.TryGetValue(assemblyQualifiedName, out type))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
string normalized = s_primitiveTypePattern.Replace(assemblyQualifiedName, "$1, " + CoreLibPlaceholder);
|
||||
return _lazyTypeMap.Value.TryGetValue(normalized, out type);
|
||||
}
|
||||
|
||||
private Dictionary<string, EntityHandle> BuildTypeMap()
|
||||
{
|
||||
var nameToHandle = new Dictionary<string, EntityHandle>();
|
||||
var handleToName = new Dictionary<EntityHandle, AQName>();
|
||||
|
||||
foreach (var handle in Reader.TypeDefinitions)
|
||||
{
|
||||
var typeDef = Reader.GetTypeDefinition(handle);
|
||||
|
||||
string name = Reader.GetString(typeDef.Name);
|
||||
var visibility = (typeDef.Attributes & TypeAttributes.VisibilityMask);
|
||||
|
||||
string qualifiedName;
|
||||
|
||||
TypeDefinitionHandle declaringType;
|
||||
if (visibility != TypeAttributes.Public &&
|
||||
visibility != TypeAttributes.NotPublic &&
|
||||
!(declaringType = typeDef.GetDeclaringType()).IsNil)
|
||||
{
|
||||
// Spec:
|
||||
// Finally, the TypeDef table has a special ordering constraint:
|
||||
// the definition of an enclosing class shall precede the definition of all classes it encloses.
|
||||
//
|
||||
// Hence we alrady have calculated the name of the declaring type.
|
||||
qualifiedName = MakeNestedTypeName(handleToName[declaringType].TypeName, name);
|
||||
}
|
||||
else
|
||||
{
|
||||
qualifiedName = MakeNamespaceTypeName(Reader.GetString(typeDef.Namespace), name);
|
||||
}
|
||||
|
||||
nameToHandle.Add(qualifiedName, handle);
|
||||
handleToName.Add(handle, new AQName(qualifiedName, default(AssemblyReferenceHandle)));
|
||||
}
|
||||
|
||||
foreach (var handle in Reader.TypeReferences)
|
||||
{
|
||||
var typeRef = Reader.GetTypeReference(handle);
|
||||
|
||||
if (typeRef.ResolutionScope.Kind == HandleKind.TypeReference)
|
||||
{
|
||||
// defer nested types
|
||||
continue;
|
||||
}
|
||||
|
||||
string qualifiedName = MakeNamespaceTypeName(Reader.GetString(typeRef.Namespace), Reader.GetString(typeRef.Name));
|
||||
|
||||
var assemblyRef = (typeRef.ResolutionScope.Kind == HandleKind.AssemblyReference) ?
|
||||
(AssemblyReferenceHandle)typeRef.ResolutionScope :
|
||||
default(AssemblyReferenceHandle);
|
||||
|
||||
var assemblyQualifiedName = MakeAssemblyQualifiedName(qualifiedName, GetAssemblyDisplayName(assemblyRef));
|
||||
|
||||
nameToHandle[assemblyQualifiedName] = handle;
|
||||
handleToName[handle] = new AQName(qualifiedName, assemblyRef);
|
||||
}
|
||||
|
||||
foreach (var handle in Reader.TypeReferences)
|
||||
{
|
||||
CalculateQualifiedTypeNameRecursive(handle, nameToHandle, handleToName);
|
||||
}
|
||||
|
||||
for (int rowId = 0; rowId <= Reader.GetTableRowCount(TableIndex.TypeSpec); rowId++)
|
||||
{
|
||||
var handle = MetadataTokens.TypeSpecificationHandle(rowId);
|
||||
var signature = Reader.GetTypeSpecification(handle).Signature;
|
||||
var sigReader = Reader.GetBlobReader(signature);
|
||||
|
||||
AQName assemblyQualifiedName;
|
||||
if (TryCalculateQualifiedTypeSpecificationName(sigReader, handleToName, out assemblyQualifiedName))
|
||||
{
|
||||
nameToHandle[assemblyQualifiedName.TypeName] = handle;
|
||||
handleToName[handle] = assemblyQualifiedName;
|
||||
}
|
||||
}
|
||||
|
||||
return nameToHandle;
|
||||
}
|
||||
|
||||
private AQName CalculateQualifiedTypeNameRecursive(
|
||||
TypeReferenceHandle handle,
|
||||
Dictionary<string, EntityHandle> nameToHandle,
|
||||
Dictionary<EntityHandle, AQName> handleToName)
|
||||
{
|
||||
AQName name;
|
||||
if (handleToName.TryGetValue(handle, out name))
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
var typeRef = Reader.GetTypeReference(handle);
|
||||
|
||||
// we have alread calculated all other names earlier:
|
||||
Debug.Assert(typeRef.ResolutionScope.Kind == HandleKind.TypeReference);
|
||||
|
||||
var declaringTypeAssemblyQualifiedName = CalculateQualifiedTypeNameRecursive((TypeReferenceHandle)typeRef.ResolutionScope, nameToHandle, handleToName);
|
||||
var qualifiedName = MakeNestedTypeName(declaringTypeAssemblyQualifiedName.TypeName, Reader.GetString(typeRef.Name));
|
||||
var assemblyQualifiedName = MakeAssemblyQualifiedName(qualifiedName, GetAssemblyDisplayName(declaringTypeAssemblyQualifiedName.AssemblyRef));
|
||||
|
||||
var result = new AQName(qualifiedName, declaringTypeAssemblyQualifiedName.AssemblyRef);
|
||||
handleToName[handle] = result;
|
||||
nameToHandle[assemblyQualifiedName] = handle;
|
||||
return result;
|
||||
}
|
||||
|
||||
private struct AQName
|
||||
{
|
||||
public static readonly AQName Empty = new AQName("", null);
|
||||
|
||||
public readonly string TypeName;
|
||||
public readonly AssemblyReferenceHandle? AssemblyRef;
|
||||
|
||||
public AQName(string qualifiedName, AssemblyReferenceHandle? assemblyRef)
|
||||
{
|
||||
TypeName = qualifiedName;
|
||||
AssemblyRef = assemblyRef;
|
||||
}
|
||||
|
||||
public AQName WithTypeName(string typeName) => new AQName(typeName, AssemblyRef);
|
||||
}
|
||||
|
||||
private bool TryCalculateQualifiedTypeSpecificationName(BlobReader sigReader, Dictionary<EntityHandle, AQName> handleToName, out AQName name)
|
||||
{
|
||||
var builder = new ImportTypeSpecNameBuilder(handleToName, _lazyAssemblyRefMap.Value.Item2);
|
||||
var decoder = new SignatureDecoder<AQName, object>(builder, metadataReader: null, genericContext: null);
|
||||
name = decoder.DecodeType(ref sigReader);
|
||||
return builder.IsSupported;
|
||||
}
|
||||
|
||||
private sealed class ImportTypeSpecNameBuilder : ISignatureTypeProvider<AQName, object>
|
||||
{
|
||||
private readonly Dictionary<EntityHandle, AQName> _handleToName;
|
||||
private readonly string[] _assemblyRefDisplayNames;
|
||||
private bool _unsupported;
|
||||
|
||||
public ImportTypeSpecNameBuilder(Dictionary<EntityHandle, AQName> handleToName, string[] assemblyRefDisplayNames)
|
||||
{
|
||||
_handleToName = handleToName;
|
||||
_assemblyRefDisplayNames = assemblyRefDisplayNames;
|
||||
}
|
||||
|
||||
public bool IsSupported => !_unsupported;
|
||||
|
||||
private string GetFullName(AQName name)
|
||||
{
|
||||
return MakeAssemblyQualifiedName(name.TypeName, GetAssemblyDisplayName(_assemblyRefDisplayNames, name.AssemblyRef));
|
||||
}
|
||||
|
||||
private static string GetPrimitiveTypeName(PrimitiveTypeCode typeCode)
|
||||
{
|
||||
switch (typeCode)
|
||||
{
|
||||
case PrimitiveTypeCode.Void: return "System.Void";
|
||||
case PrimitiveTypeCode.Boolean: return "System.Boolean";
|
||||
case PrimitiveTypeCode.Char: return "System.Char";
|
||||
case PrimitiveTypeCode.SByte: return "System.SByte";
|
||||
case PrimitiveTypeCode.Byte: return "System.Byte";
|
||||
case PrimitiveTypeCode.Int16: return "System.Int16";
|
||||
case PrimitiveTypeCode.UInt16: return "System.UInt16";
|
||||
case PrimitiveTypeCode.Int32: return "System.Int32";
|
||||
case PrimitiveTypeCode.UInt32: return "System.UInt32";
|
||||
case PrimitiveTypeCode.Int64: return "System.Int64";
|
||||
case PrimitiveTypeCode.UInt64: return "System.UInt64";
|
||||
case PrimitiveTypeCode.Single: return "System.Single";
|
||||
case PrimitiveTypeCode.Double: return "System.Double";
|
||||
case PrimitiveTypeCode.String: return "System.String";
|
||||
case PrimitiveTypeCode.TypedReference: return "System.TypedReference";
|
||||
case PrimitiveTypeCode.IntPtr: return "System.IntPtr";
|
||||
case PrimitiveTypeCode.UIntPtr: return "System.UIntPtr";
|
||||
default:
|
||||
throw ExceptionUtilities.UnexpectedValue(typeCode);
|
||||
}
|
||||
}
|
||||
|
||||
public AQName GetSZArrayType(AQName elementType)
|
||||
{
|
||||
return elementType.WithTypeName(elementType.TypeName + "[]");
|
||||
}
|
||||
|
||||
public AQName GetArrayType(AQName elementType, ArrayShape shape)
|
||||
{
|
||||
var pooled = PooledStringBuilder.GetInstance();
|
||||
var sb = pooled.Builder;
|
||||
|
||||
sb.Append(elementType.TypeName);
|
||||
sb.Append('[');
|
||||
if (shape.Rank == 1)
|
||||
{
|
||||
sb.Append('*');
|
||||
}
|
||||
|
||||
sb.Append(',', shape.Rank - 1);
|
||||
sb.Append(']');
|
||||
|
||||
return elementType.WithTypeName(pooled.ToStringAndFree());
|
||||
}
|
||||
|
||||
public AQName GetByReferenceType(AQName elementType)
|
||||
{
|
||||
return elementType.WithTypeName(elementType.TypeName + "&");
|
||||
}
|
||||
|
||||
public AQName GetPointerType(AQName elementType)
|
||||
{
|
||||
return elementType.WithTypeName(elementType.TypeName + "*");
|
||||
}
|
||||
|
||||
public AQName GetGenericInstantiation(AQName genericType, ImmutableArray<AQName> typeArguments)
|
||||
{
|
||||
var pooled = PooledStringBuilder.GetInstance();
|
||||
var sb = pooled.Builder;
|
||||
return genericType.WithTypeName(genericType.TypeName + "[" + string.Join(",", typeArguments.Select(GetFullName)) + "]");
|
||||
}
|
||||
|
||||
public AQName GetTypeFromDefinition(MetadataReader reader, TypeDefinitionHandle handle, byte rawTypeKind)
|
||||
{
|
||||
return _handleToName[handle];
|
||||
}
|
||||
|
||||
public AQName GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind)
|
||||
{
|
||||
return _handleToName[handle];
|
||||
}
|
||||
|
||||
public AQName GetPrimitiveType(PrimitiveTypeCode typeCode)
|
||||
{
|
||||
return new AQName(GetPrimitiveTypeName(typeCode), null);
|
||||
}
|
||||
|
||||
public AQName GetFunctionPointerType(MethodSignature<AQName> signature)
|
||||
{
|
||||
_unsupported = true;
|
||||
return AQName.Empty;
|
||||
}
|
||||
|
||||
public AQName GetGenericMethodParameter(object genericContext, int index)
|
||||
{
|
||||
_unsupported = true;
|
||||
return AQName.Empty;
|
||||
}
|
||||
|
||||
public AQName GetGenericTypeParameter(object genericContext, int index)
|
||||
{
|
||||
_unsupported = true;
|
||||
return AQName.Empty;
|
||||
}
|
||||
|
||||
public AQName GetModifiedType(AQName modifier, AQName unmodifiedType, bool isRequired)
|
||||
{
|
||||
_unsupported = true;
|
||||
return AQName.Empty;
|
||||
}
|
||||
|
||||
public AQName GetPinnedType(AQName elementType)
|
||||
{
|
||||
_unsupported = true;
|
||||
return AQName.Empty;
|
||||
}
|
||||
|
||||
public AQName GetTypeFromSpecification(MetadataReader reader, object genericContext, TypeSpecificationHandle handle, byte rawTypeKind)
|
||||
{
|
||||
_unsupported = true;
|
||||
return AQName.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
private static string MakeAssemblyQualifiedName(string qualifiedName, string assemblyName) => qualifiedName + ", " + assemblyName;
|
||||
private static string MakeNestedTypeName(string declaringTypeName, string name) => declaringTypeName + "+" + name;
|
||||
private static string MakeNamespaceTypeName(string @namespace, string name) => @namespace.Length > 0 ? @namespace + "." + name : name;
|
||||
}
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -->
|
||||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ImportGroup Label="Settings">
|
||||
<Import Project="..\..\build\Targets\Settings.targets" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{C0122B3F-86F0-4114-86F6-321535394C4E}</ProjectGuid>
|
||||
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<OutputType>Library</OutputType>
|
||||
<RootNamespace>Microsoft.DiaSymReader.Tools</RootNamespace>
|
||||
<AssemblyName>Microsoft.DiaSymReader.Converter</AssemblyName>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<TargetFrameworkVersion>v5.0</TargetFrameworkVersion>
|
||||
<TargetFrameworkProfile>
|
||||
</TargetFrameworkProfile>
|
||||
<TargetFrameworkIdentifier>.NETPortable</TargetFrameworkIdentifier>
|
||||
<NuGetTargetMoniker>.NETStandard,Version=v1.3</NuGetTargetMoniker>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' " />
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
|
||||
<ItemGroup>
|
||||
<Compile Include="ConstantSignatureConverter.cs" />
|
||||
<Compile Include="MetadataModel.cs" />
|
||||
<Compile Include="Utilities\ByteSequenceComparer.cs" />
|
||||
<Compile Include="Utilities\ExceptionUtilities.cs" />
|
||||
<Compile Include="Utilities\Hash.cs" />
|
||||
<Compile Include="IMetadataImport.cs" />
|
||||
<Compile Include="PdbConverter.cs" />
|
||||
<Compile Include="SymReaderFactory.cs" />
|
||||
<Compile Include="Utilities\ImportDefinitionEncoder.cs" />
|
||||
<Compile Include="Utilities\SerializedTypeDecoder.cs" />
|
||||
<Compile Include="Utilities\SymReaderHelpers.cs" />
|
||||
<Compile Include="SymReaderMetadataImport.cs" />
|
||||
<Compile Include="Utilities\MetadataHelpers.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="project.json" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<InternalsVisibleTo Include="Microsoft.DiaSymReader.Converter.UnitTests" />
|
||||
</ItemGroup>
|
||||
<Import Project="..\Microsoft.CodeAnalysis.Metadata\Microsoft.CodeAnalysis.Metadata.projitems" Label="Shared" />
|
||||
<Import Project="..\Microsoft.CodeAnalysis.PooledObjects\Microsoft.CodeAnalysis.PooledObjects.projitems" Label="Shared" />
|
||||
<ImportGroup Label="Targets">
|
||||
<Import Project="..\..\build\Targets\Imports.targets" />
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -1,930 +0,0 @@
|
|||
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.IO;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Reflection.PortableExecutable;
|
||||
using System.Reflection.Metadata.Ecma335;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics;
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
using Microsoft.CodeAnalysis.Debugging;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Roslyn.Utilities;
|
||||
using Microsoft.CodeAnalysis;
|
||||
|
||||
namespace Microsoft.DiaSymReader.Tools
|
||||
{
|
||||
public sealed class PdbConverter
|
||||
{
|
||||
/// <summary>
|
||||
/// Converts Windows PDB stream to Portable PDB.
|
||||
/// </summary>
|
||||
/// <param name="peStream">PE image stream (.dll or .exe)</param>
|
||||
/// <param name="sourcePdbStream">Source stream of Windows PDB data. Must be readable.</param>
|
||||
/// <param name="targetPdbStream">Target stream of Portable PDB data. Must be writable.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="peStream"/>, <paramref name="sourcePdbStream"/>, or <paramref name="targetPdbStream"/> is null.</exception>
|
||||
/// <exception cref="ArgumentException"><paramref name="sourcePdbStream"/> does not support reading.</exception>
|
||||
/// <exception cref="ArgumentException"><paramref name="targetPdbStream"/> does not support writing.</exception>
|
||||
/// <exception cref="BadImageFormatException">The format of the PE image or the source PDB image is invalid.</exception>
|
||||
/// <exception cref="InvalidDataException">Unexpected data found in the PE image or the source PDB image.</exception>
|
||||
public static void Convert(Stream peStream, Stream sourcePdbStream, Stream targetPdbStream)
|
||||
{
|
||||
ValidateArguments(peStream, sourcePdbStream, targetPdbStream);
|
||||
|
||||
var metadataBuilder = new MetadataBuilder();
|
||||
ImmutableArray<int> typeSystemRowCounts;
|
||||
var debugEntryPointToken = default(MethodDefinitionHandle);
|
||||
var pdbId = default(BlobContentId);
|
||||
|
||||
try
|
||||
{
|
||||
using (var peReader = new PEReader(peStream))
|
||||
{
|
||||
pdbId = ReadPdbId(peReader);
|
||||
|
||||
var symReader = SymReaderFactory.CreateWindowsPdbReader(sourcePdbStream, peReader);
|
||||
|
||||
var metadataReader = peReader.GetMetadataReader();
|
||||
var metadataModel = new MetadataModel(metadataReader);
|
||||
|
||||
typeSystemRowCounts = metadataModel.GetRowCounts();
|
||||
debugEntryPointToken = ReadEntryPointHandle(symReader);
|
||||
|
||||
// documents:
|
||||
var documentIndex = new Dictionary<string, DocumentHandle>(StringComparer.Ordinal);
|
||||
var documents = symReader.GetDocuments();
|
||||
metadataBuilder.SetCapacity(TableIndex.Document, documents.Length);
|
||||
|
||||
bool vbSemantics = false;
|
||||
|
||||
foreach (var document in documents)
|
||||
{
|
||||
string name = document.GetName();
|
||||
Guid language = document.GetLanguage();
|
||||
|
||||
// TODO:
|
||||
// won't work for IL-merged assmemblies
|
||||
vbSemantics |= language == SymReaderHelpers.VisualBasicLanguageGuid;
|
||||
|
||||
var rid = metadataBuilder.AddDocument(
|
||||
name: metadataBuilder.GetOrAddDocumentName(name),
|
||||
hashAlgorithm: metadataBuilder.GetOrAddGuid(document.GetHashAlgorithm()),
|
||||
hash: metadataBuilder.GetOrAddBlob(document.GetChecksum()),
|
||||
language: metadataBuilder.GetOrAddGuid(language));
|
||||
|
||||
documentIndex.Add(name, rid);
|
||||
}
|
||||
|
||||
var lastLocalVariableHandle = default(LocalVariableHandle);
|
||||
var lastLocalConstantHandle = default(LocalConstantHandle);
|
||||
|
||||
var importStringsByMethod = new Dictionary<int, ImmutableArray<string>>();
|
||||
var importScopesByMethod = new Dictionary<int, ImportScopeHandle>();
|
||||
|
||||
// Maps import scope content to import scope handles
|
||||
var importScopeIndex = new Dictionary<ImportScopeInfo, ImportScopeHandle>();
|
||||
var importScopes = new List<ImportScopeInfo>();
|
||||
|
||||
// reserve slot for module import scope:
|
||||
importScopes.Add(default(ImportScopeInfo));
|
||||
|
||||
var externAliasImports = new List<ImportInfo>();
|
||||
var externAliasStringSet = new HashSet<string>(StringComparer.Ordinal);
|
||||
|
||||
string vbDefaultNamespace = null;
|
||||
var vbProjectLevelImports = new List<ImportInfo>();
|
||||
|
||||
// first pass:
|
||||
foreach (var methodHandle in metadataReader.MethodDefinitions)
|
||||
{
|
||||
int methodToken = MetadataTokens.GetToken(methodHandle);
|
||||
ImmutableArray<ImmutableArray<ImportInfo>> importGroups;
|
||||
|
||||
if (vbSemantics)
|
||||
{
|
||||
var importStrings = CustomDebugInfoReader.GetVisualBasicImportStrings(
|
||||
methodToken,
|
||||
symReader,
|
||||
getMethodImportStrings: (token, sr) => GetImportStrings(token, importStringsByMethod, sr));
|
||||
|
||||
if (importStrings.IsEmpty)
|
||||
{
|
||||
// no debug info
|
||||
continue;
|
||||
}
|
||||
|
||||
var vbFileLevelImports = ArrayBuilder<ImportInfo>.GetInstance();
|
||||
foreach (var importString in importStrings)
|
||||
{
|
||||
ImportInfo import;
|
||||
if (TryParseImportString(importString, out import, vbSemantics: true))
|
||||
{
|
||||
if (import.Kind == ImportTargetKind.DefaultNamespace)
|
||||
{
|
||||
vbDefaultNamespace = import.Target;
|
||||
}
|
||||
else if (import.Scope == VBImportScopeKind.Project)
|
||||
{
|
||||
vbProjectLevelImports.Add(import);
|
||||
}
|
||||
else
|
||||
{
|
||||
vbFileLevelImports.Add(import);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
importGroups = ImmutableArray.Create(vbFileLevelImports.ToImmutableAndFree());
|
||||
}
|
||||
else
|
||||
{
|
||||
ImmutableArray<string> localExternAliasStrings;
|
||||
var importStringGroups = CustomDebugInfoReader.GetCSharpGroupedImportStrings(
|
||||
methodToken,
|
||||
symReader,
|
||||
getMethodCustomDebugInfo: (token, sr) => sr.GetCustomDebugInfo(token, methodVersion: 1),
|
||||
getMethodImportStrings: (token, sr) => GetImportStrings(token, importStringsByMethod, sr),
|
||||
externAliasStrings: out localExternAliasStrings);
|
||||
|
||||
if (importStringGroups.IsDefault)
|
||||
{
|
||||
// no debug info
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!localExternAliasStrings.IsDefault)
|
||||
{
|
||||
foreach (var externAlias in localExternAliasStrings)
|
||||
{
|
||||
ImportInfo import;
|
||||
if (externAliasStringSet.Add(externAlias) &&
|
||||
TryParseImportString(externAlias, out import, vbSemantics: false))
|
||||
{
|
||||
externAliasImports.Add(import);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
importGroups = ImmutableArray.CreateRange(importStringGroups.Select(g => ParseImportStrings(g, vbSemantics: false)));
|
||||
}
|
||||
|
||||
var importScopeHandle = DefineImportScope(importGroups, importScopeIndex, importScopes);
|
||||
importScopesByMethod.Add(methodToken, importScopeHandle);
|
||||
}
|
||||
|
||||
// import scopes:
|
||||
metadataBuilder.AddImportScope(
|
||||
parentScope: default(ImportScopeHandle),
|
||||
imports: SerializeModuleImportScope(metadataBuilder, externAliasImports, vbProjectLevelImports, vbDefaultNamespace, metadataModel));
|
||||
|
||||
for (int i = 1; i < importScopes.Count; i++)
|
||||
{
|
||||
metadataBuilder.AddImportScope(
|
||||
parentScope: importScopes[i].Parent,
|
||||
imports: SerializeImportsBlob(metadataBuilder, importScopes[i].Imports, metadataModel));
|
||||
}
|
||||
|
||||
var dynamicNames = new Dictionary<string, DynamicLocalInfo>();
|
||||
var dynamicSlots = new Dictionary<int, DynamicLocalInfo>();
|
||||
|
||||
// methods:
|
||||
metadataBuilder.SetCapacity(TableIndex.MethodDebugInformation, metadataReader.MethodDefinitions.Count);
|
||||
foreach (var methodHandle in metadataReader.MethodDefinitions)
|
||||
{
|
||||
var methodDef = metadataReader.GetMethodDefinition(methodHandle);
|
||||
int methodToken = MetadataTokens.GetToken(methodHandle);
|
||||
|
||||
var symMethod = symReader.GetMethod(methodToken);
|
||||
if (symMethod == null)
|
||||
{
|
||||
metadataBuilder.AddMethodDebugInformation(default(DocumentHandle), sequencePoints: default(BlobHandle));
|
||||
continue;
|
||||
}
|
||||
|
||||
// method debug info:
|
||||
int localSignatureRowId;
|
||||
if (methodDef.RelativeVirtualAddress != 0)
|
||||
{
|
||||
var methodBody = peReader.GetMethodBody(methodDef.RelativeVirtualAddress);
|
||||
localSignatureRowId = methodBody.LocalSignature.IsNil ? 0 : MetadataTokens.GetRowNumber(methodBody.LocalSignature);
|
||||
}
|
||||
else
|
||||
{
|
||||
localSignatureRowId = 0;
|
||||
}
|
||||
|
||||
var symSequencePoints = symMethod.GetSequencePoints().ToImmutableArray();
|
||||
|
||||
DocumentHandle singleDocumentHandle;
|
||||
BlobHandle sequencePointsBlob = SerializeSequencePoints(metadataBuilder, localSignatureRowId, symSequencePoints, documentIndex, out singleDocumentHandle);
|
||||
|
||||
metadataBuilder.AddMethodDebugInformation(
|
||||
document: singleDocumentHandle,
|
||||
sequencePoints: sequencePointsBlob);
|
||||
|
||||
// state machine and async info:
|
||||
var symAsyncMethod = symMethod.AsAsyncMethod();
|
||||
if (symAsyncMethod != null)
|
||||
{
|
||||
var kickoffToken = MetadataTokens.Handle(symAsyncMethod.GetKickoffMethod());
|
||||
metadataBuilder.AddStateMachineMethod(
|
||||
moveNextMethod: methodHandle,
|
||||
kickoffMethod: (MethodDefinitionHandle)kickoffToken);
|
||||
|
||||
metadataBuilder.AddCustomDebugInformation(
|
||||
parent: methodHandle,
|
||||
kind: metadataBuilder.GetOrAddGuid(PortableCustomDebugInfoKinds.AsyncMethodSteppingInformationBlob),
|
||||
value: SerializeAsyncMethodSteppingInfo(metadataBuilder, symAsyncMethod, MetadataTokens.GetRowNumber(methodHandle)));
|
||||
}
|
||||
|
||||
// custom debug information:
|
||||
var dynamicLocals = default(ImmutableArray<DynamicLocalInfo>);
|
||||
|
||||
byte[] customDebugInfoBytes = symReader.GetCustomDebugInfo(methodToken, methodVersion: 1);
|
||||
if (customDebugInfoBytes != null)
|
||||
{
|
||||
foreach (var record in CustomDebugInfoReader.GetCustomDebugInfoRecords(customDebugInfoBytes))
|
||||
{
|
||||
switch (record.Kind)
|
||||
{
|
||||
case CustomDebugInfoKind.DynamicLocals:
|
||||
dynamicLocals = CustomDebugInfoReader.DecodeDynamicLocalsRecord(record.Data);
|
||||
break;
|
||||
|
||||
case CustomDebugInfoKind.StateMachineHoistedLocalScopes:
|
||||
metadataBuilder.AddCustomDebugInformation(
|
||||
parent: methodHandle,
|
||||
kind: metadataBuilder.GetOrAddGuid(PortableCustomDebugInfoKinds.EncLocalSlotMap),
|
||||
value: SerializeStateMachineHoistedLocalsBlob(metadataBuilder, CustomDebugInfoReader.DecodeStateMachineHoistedLocalScopesRecord(record.Data)));
|
||||
break;
|
||||
|
||||
case CustomDebugInfoKind.EditAndContinueLocalSlotMap:
|
||||
metadataBuilder.AddCustomDebugInformation(
|
||||
parent: methodHandle,
|
||||
kind: metadataBuilder.GetOrAddGuid(PortableCustomDebugInfoKinds.EncLocalSlotMap),
|
||||
value: metadataBuilder.GetOrAddBlob(record.Data));
|
||||
break;
|
||||
|
||||
case CustomDebugInfoKind.EditAndContinueLambdaMap:
|
||||
metadataBuilder.AddCustomDebugInformation(
|
||||
parent: methodHandle,
|
||||
kind: metadataBuilder.GetOrAddGuid(PortableCustomDebugInfoKinds.EncLambdaAndClosureMap),
|
||||
value: metadataBuilder.GetOrAddBlob(record.Data));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var rootScope = symMethod.GetRootScope();
|
||||
if (rootScope.GetNamespaces().Length == 0 || rootScope.GetLocals().Length == 0 || rootScope.GetConstants().Length == 0)
|
||||
{
|
||||
dynamicNames.Clear();
|
||||
dynamicSlots.Clear();
|
||||
|
||||
foreach (var dynamicLocal in dynamicLocals)
|
||||
{
|
||||
if (dynamicLocal.SlotId == 0)
|
||||
{
|
||||
// All dynamic constants have slot id == 0,
|
||||
// but a variable can also have slot id == 0
|
||||
if (!dynamicNames.ContainsKey(dynamicLocal.Name))
|
||||
{
|
||||
dynamicNames.Add(dynamicLocal.Name, dynamicLocal);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: warning
|
||||
}
|
||||
}
|
||||
else if (!dynamicSlots.ContainsKey(dynamicLocal.SlotId))
|
||||
{
|
||||
dynamicSlots.Add(dynamicLocal.SlotId, dynamicLocal);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: warning
|
||||
}
|
||||
}
|
||||
|
||||
foreach (ISymUnmanagedScope scope in rootScope.GetChildren())
|
||||
{
|
||||
SerializeScope(
|
||||
metadataBuilder,
|
||||
metadataModel,
|
||||
methodHandle,
|
||||
importScopesByMethod[methodToken],
|
||||
scope,
|
||||
dynamicSlots,
|
||||
dynamicNames,
|
||||
vbSemantics,
|
||||
ref lastLocalVariableHandle,
|
||||
ref lastLocalConstantHandle);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: warning:
|
||||
// "Root scope must be empty (method 0x{0:x8})", MetadataTokens.GetToken(methodHandle))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (COMException e)
|
||||
{
|
||||
// TODO: loc
|
||||
throw new BadImageFormatException("Invalid PDB format: " + e.Message, e);
|
||||
}
|
||||
|
||||
var serializer = new PortablePdbBuilder(metadataBuilder, typeSystemRowCounts, debugEntryPointToken, idProvider: _ => pdbId);
|
||||
BlobBuilder blobBuilder = new BlobBuilder();
|
||||
serializer.Serialize(blobBuilder);
|
||||
blobBuilder.WriteContentTo(targetPdbStream);
|
||||
}
|
||||
|
||||
private static BlobHandle SerializeStateMachineHoistedLocalsBlob(MetadataBuilder metadataBuilder, ImmutableArray<StateMachineHoistedLocalScope> scopes)
|
||||
{
|
||||
var builder = new BlobBuilder();
|
||||
|
||||
foreach (var scope in scopes)
|
||||
{
|
||||
builder.WriteInt32(scope.StartOffset);
|
||||
builder.WriteInt32(scope.EndOffset - scope.StartOffset);
|
||||
}
|
||||
|
||||
return metadataBuilder.GetOrAddBlob(builder);
|
||||
}
|
||||
|
||||
private static BlobHandle SerializeAsyncMethodSteppingInfo(MetadataBuilder metadataBuilder, ISymUnmanagedAsyncMethod symAsyncMethod, int moveNextMethodRowId)
|
||||
{
|
||||
var builder = new BlobBuilder();
|
||||
|
||||
builder.WriteUInt32((uint)((long)symAsyncMethod.GetCatchHandlerILOffset() + 1));
|
||||
|
||||
foreach (var stepInfo in symAsyncMethod.GetAsyncStepInfos())
|
||||
{
|
||||
builder.WriteInt32(stepInfo.YieldOffset);
|
||||
builder.WriteInt32(stepInfo.ResumeOffset);
|
||||
builder.WriteCompressedInteger(moveNextMethodRowId);
|
||||
}
|
||||
|
||||
return metadataBuilder.GetOrAddBlob(builder);
|
||||
}
|
||||
|
||||
private static bool TryParseImportString(string importString, out ImportInfo import, bool vbSemantics)
|
||||
{
|
||||
ImportTargetKind kind;
|
||||
string target;
|
||||
string alias;
|
||||
string externAlias = null;
|
||||
var scope = VBImportScopeKind.Unspecified;
|
||||
|
||||
if (vbSemantics ?
|
||||
CustomDebugInfoReader.TryParseVisualBasicImportString(importString, out alias, out target, out kind, out scope) :
|
||||
CustomDebugInfoReader.TryParseCSharpImportString(importString, out alias, out externAlias, out target, out kind))
|
||||
{
|
||||
import = new ImportInfo(kind, target, alias, externAlias, scope);
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: report warning
|
||||
import = default(ImportInfo);
|
||||
return false;
|
||||
}
|
||||
|
||||
private static ImmutableArray<string> GetImportStrings(int token, Dictionary<int, ImmutableArray<string>> cache, ISymUnmanagedReader3 reader)
|
||||
{
|
||||
ImmutableArray<string> result;
|
||||
if (!cache.TryGetValue(token, out result))
|
||||
{
|
||||
result = SymReaderHelpers.GetImportStrings(reader, token, methodVersion: 1);
|
||||
cache.Add(token, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static BlobContentId ReadPdbId(PEReader peReader)
|
||||
{
|
||||
foreach (var entry in peReader.ReadDebugDirectory())
|
||||
{
|
||||
if (entry.Type == DebugDirectoryEntryType.CodeView)
|
||||
{
|
||||
// TODO: const
|
||||
if (entry.MajorVersion == 0x504D)
|
||||
{
|
||||
// TODO: loc
|
||||
throw new InvalidDataException("Specified PE was built with Portable PDB.");
|
||||
}
|
||||
|
||||
return new BlobContentId(peReader.ReadCodeViewDebugDirectoryData(entry).Guid, entry.Stamp);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: loc
|
||||
throw new InvalidDataException("Specified PE file doesn't have any PDB associated with it.");
|
||||
}
|
||||
|
||||
private static MethodDefinitionHandle ReadEntryPointHandle(ISymUnmanagedReader symReader)
|
||||
{
|
||||
var handle = MetadataTokens.EntityHandle(symReader.GetUserEntryPoint());
|
||||
if (handle.IsNil)
|
||||
{
|
||||
return default(MethodDefinitionHandle);
|
||||
}
|
||||
|
||||
if (handle.Kind != HandleKind.MethodDefinition)
|
||||
{
|
||||
// TODO: loc
|
||||
throw new BadImageFormatException("Invalid user entry point in the source PDB");
|
||||
}
|
||||
|
||||
return (MethodDefinitionHandle)handle;
|
||||
}
|
||||
|
||||
private static void ValidateArguments(Stream peStream, Stream sourcePdbStream, Stream targetPdbStream)
|
||||
{
|
||||
if (peStream == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(peStream));
|
||||
}
|
||||
|
||||
if (sourcePdbStream == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(sourcePdbStream));
|
||||
}
|
||||
|
||||
if (!sourcePdbStream.CanRead)
|
||||
{
|
||||
// TODO: localize
|
||||
throw new ArgumentException("Stream must be readable", nameof(sourcePdbStream));
|
||||
}
|
||||
|
||||
if (targetPdbStream == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(targetPdbStream));
|
||||
}
|
||||
|
||||
if (!targetPdbStream.CanWrite)
|
||||
{
|
||||
// TODO: localize
|
||||
throw new ArgumentException("Stream must be writable", nameof(targetPdbStream));
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly ImportScopeHandle ModuleImportScopeHandle = MetadataTokens.ImportScopeHandle(1);
|
||||
|
||||
private struct ImportScopeInfo : IEquatable<ImportScopeInfo>
|
||||
{
|
||||
public readonly ImportScopeHandle Parent;
|
||||
public readonly ImmutableArray<ImportInfo> Imports;
|
||||
|
||||
public ImportScopeInfo(ImmutableArray<ImportInfo> imports, ImportScopeHandle parent)
|
||||
{
|
||||
Parent = parent;
|
||||
Imports = imports;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj) => obj is ImportScopeInfo && Equals((ImportScopeInfo)obj);
|
||||
public bool Equals(ImportScopeInfo other) => Parent == other.Parent && Imports.SequenceEqual(other.Imports);
|
||||
public override int GetHashCode() => Hash.Combine(Parent.GetHashCode(), Hash.CombineValues(Imports));
|
||||
}
|
||||
|
||||
private static ImportScopeHandle DefineImportScope(
|
||||
ImmutableArray<ImmutableArray<ImportInfo>> importGroups,
|
||||
Dictionary<ImportScopeInfo, ImportScopeHandle> importScopeIndex,
|
||||
List<ImportScopeInfo> importScopes)
|
||||
{
|
||||
ImportScopeHandle parentHandle = ModuleImportScopeHandle;
|
||||
for (int i = importGroups.Length - 1; i >= 0; i--)
|
||||
{
|
||||
var info = new ImportScopeInfo(importGroups[i], parentHandle);
|
||||
|
||||
ImportScopeHandle existingScopeHandle;
|
||||
if (importScopeIndex.TryGetValue(info, out existingScopeHandle))
|
||||
{
|
||||
parentHandle = existingScopeHandle;
|
||||
}
|
||||
else
|
||||
{
|
||||
importScopes.Add(info);
|
||||
parentHandle = MetadataTokens.ImportScopeHandle(importScopes.Count);
|
||||
}
|
||||
}
|
||||
|
||||
return parentHandle;
|
||||
}
|
||||
|
||||
private static ImmutableArray<ImportInfo> ParseImportStrings(ImmutableArray<string> importStrings, bool vbSemantics)
|
||||
{
|
||||
var builder = ArrayBuilder<ImportInfo>.GetInstance();
|
||||
foreach (var importString in importStrings)
|
||||
{
|
||||
ImportInfo import;
|
||||
if (TryParseImportString(importString, out import, vbSemantics))
|
||||
{
|
||||
builder.Add(import);
|
||||
}
|
||||
}
|
||||
|
||||
return builder.ToImmutableAndFree();
|
||||
}
|
||||
|
||||
private static BlobHandle SerializeModuleImportScope(
|
||||
MetadataBuilder metadataBuilder,
|
||||
IEnumerable<ImportInfo> csExternAliasImports,
|
||||
IEnumerable<ImportInfo> vbProjectLevelImports,
|
||||
string vbDefaultNamespace,
|
||||
MetadataModel metadataModel)
|
||||
{
|
||||
// module-level import scope:
|
||||
var builder = new BlobBuilder();
|
||||
var encoder = new ImportDefinitionEncoder(metadataBuilder, builder);
|
||||
|
||||
if (vbDefaultNamespace != null)
|
||||
{
|
||||
SerializeModuleDefaultNamespace(metadataBuilder, vbDefaultNamespace);
|
||||
}
|
||||
|
||||
foreach (var import in csExternAliasImports)
|
||||
{
|
||||
SerializeImport(encoder, import, metadataModel);
|
||||
}
|
||||
|
||||
foreach (var import in vbProjectLevelImports)
|
||||
{
|
||||
SerializeImport(encoder, import, metadataModel);
|
||||
}
|
||||
|
||||
return metadataBuilder.GetOrAddBlob(builder);
|
||||
}
|
||||
|
||||
private static void SerializeModuleDefaultNamespace(MetadataBuilder metadataBuilder, string namespaceName)
|
||||
{
|
||||
metadataBuilder.AddCustomDebugInformation(
|
||||
parent: EntityHandle.ModuleDefinition,
|
||||
kind: metadataBuilder.GetOrAddGuid(PortableCustomDebugInfoKinds.DefaultNamespace),
|
||||
value: metadataBuilder.GetOrAddBlobUTF8(namespaceName));
|
||||
}
|
||||
|
||||
private static BlobHandle SerializeImportsBlob(MetadataBuilder metadataBuilder, ImmutableArray<ImportInfo> imports, MetadataModel metadataModel)
|
||||
{
|
||||
var builder = new BlobBuilder();
|
||||
var encoder = new ImportDefinitionEncoder(metadataBuilder, builder);
|
||||
|
||||
foreach (var import in imports)
|
||||
{
|
||||
SerializeImport(encoder, import, metadataModel);
|
||||
}
|
||||
|
||||
return metadataBuilder.GetOrAddBlob(builder);
|
||||
}
|
||||
|
||||
private struct ImportInfo
|
||||
{
|
||||
public readonly ImportTargetKind Kind;
|
||||
public readonly string Target;
|
||||
public readonly string ExternAlias;
|
||||
public readonly string Alias;
|
||||
public readonly VBImportScopeKind Scope;
|
||||
|
||||
public ImportInfo(ImportTargetKind kind, string target, string alias, string externAlias, VBImportScopeKind scope)
|
||||
{
|
||||
Kind = kind;
|
||||
Target = target;
|
||||
Alias = alias;
|
||||
ExternAlias = externAlias;
|
||||
Scope = scope;
|
||||
}
|
||||
}
|
||||
|
||||
private static void SerializeImport(ImportDefinitionEncoder encoder, ImportInfo import, MetadataModel metadataModel)
|
||||
{
|
||||
var assemblyRef = default(AssemblyReferenceHandle);
|
||||
EntityHandle type;
|
||||
switch (import.Kind)
|
||||
{
|
||||
case ImportTargetKind.Assembly:
|
||||
// alias: assembly alias
|
||||
// target: assembly name for module-level extern alias definition, or null for file level extern alias import
|
||||
|
||||
if (import.Target == null)
|
||||
{
|
||||
// TODO: skip if the alias isn't defined in an ancestor scope?
|
||||
encoder.ImportAssemblyReferenceAlias(import.Alias);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!metadataModel.TryResolveAssemblyReference(import.Target, out assemblyRef))
|
||||
{
|
||||
// no type from the assembly is used, the AssemblyRef is not present in the metadata
|
||||
break;
|
||||
}
|
||||
|
||||
encoder.AliasAssemblyReference(assemblyRef, import.Alias);
|
||||
break;
|
||||
|
||||
case ImportTargetKind.Namespace:
|
||||
if (import.ExternAlias != null && !metadataModel.TryResolveAssemblyReference(import.ExternAlias, out assemblyRef))
|
||||
{
|
||||
// no type from the assembly is used, the AssemblyRef is not present in the metadata
|
||||
break;
|
||||
}
|
||||
|
||||
encoder.Namespace(import.Target, import.Alias, assemblyRef);
|
||||
break;
|
||||
|
||||
case ImportTargetKind.Type:
|
||||
if (!metadataModel.TryResolveType(import.Target, out type))
|
||||
{
|
||||
// the type is not used in the source, the metadata is missing a TypeRef.
|
||||
break;
|
||||
}
|
||||
|
||||
encoder.Type(type, import.Alias);
|
||||
break;
|
||||
|
||||
case ImportTargetKind.NamespaceOrType:
|
||||
if (metadataModel.TryResolveType(import.Target, out type))
|
||||
{
|
||||
encoder.Type(type, import.Alias);
|
||||
}
|
||||
else
|
||||
{
|
||||
encoder.Namespace(import.Target, import.Alias);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case ImportTargetKind.XmlNamespace:
|
||||
encoder.XmlNamespace(import.Alias, import.Target);
|
||||
break;
|
||||
|
||||
case ImportTargetKind.DefaultNamespace:
|
||||
// alraedy handled
|
||||
throw ExceptionUtilities.Unreachable;
|
||||
|
||||
case ImportTargetKind.CurrentNamespace:
|
||||
case ImportTargetKind.MethodToken:
|
||||
case ImportTargetKind.Defunct:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static void SerializeScope(
|
||||
MetadataBuilder metadataBuilder,
|
||||
MetadataModel metadataModel,
|
||||
MethodDefinitionHandle methodHandle,
|
||||
ImportScopeHandle importScopeHandle,
|
||||
ISymUnmanagedScope symScope,
|
||||
Dictionary<int, DynamicLocalInfo> dynamicSlots,
|
||||
Dictionary<string, DynamicLocalInfo> dynamicNames,
|
||||
bool vbSemantics,
|
||||
ref LocalVariableHandle lastLocalVariableHandle,
|
||||
ref LocalConstantHandle lastLocalConstantHandle)
|
||||
{
|
||||
// VB Windows PDB encode the range as end-inclusive,
|
||||
// all Portable PDBs use end-exclusive encoding.
|
||||
int start = symScope.GetStartOffset();
|
||||
int end = symScope.GetEndOffset() + (vbSemantics ? 1 : 0);
|
||||
|
||||
metadataBuilder.AddLocalScope(
|
||||
method: methodHandle,
|
||||
importScope: importScopeHandle,
|
||||
variableList: NextHandle(lastLocalVariableHandle),
|
||||
constantList: NextHandle(lastLocalConstantHandle),
|
||||
startOffset: start,
|
||||
length: end - start);
|
||||
|
||||
foreach (var symLocal in symScope.GetLocals())
|
||||
{
|
||||
int slot = symLocal.GetSlot();
|
||||
string name = symLocal.GetName();
|
||||
|
||||
lastLocalVariableHandle = metadataBuilder.AddLocalVariable(
|
||||
attributes: (LocalVariableAttributes)symLocal.GetAttributes(),
|
||||
index: slot,
|
||||
name: metadataBuilder.GetOrAddString(name));
|
||||
|
||||
DynamicLocalInfo dynamicInfo;
|
||||
if (slot > 0 && dynamicSlots.TryGetValue(slot, out dynamicInfo) ||
|
||||
slot == 0 && dynamicNames.TryGetValue(name, out dynamicInfo))
|
||||
{
|
||||
metadataBuilder.AddCustomDebugInformation(
|
||||
parent: lastLocalVariableHandle,
|
||||
kind: metadataBuilder.GetOrAddGuid(PortableCustomDebugInfoKinds.DynamicLocalVariables),
|
||||
value: SerializeDynamicLocalBlob(metadataBuilder, dynamicInfo));
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var symConstant in symScope.GetConstants())
|
||||
{
|
||||
string name = symConstant.GetName();
|
||||
object value = symConstant.GetValue();
|
||||
|
||||
lastLocalConstantHandle = metadataBuilder.AddLocalConstant(
|
||||
name: metadataBuilder.GetOrAddString(name),
|
||||
signature: SerializeConstantSignature(metadataBuilder, metadataModel, symConstant.GetSignature(), value));
|
||||
|
||||
DynamicLocalInfo dynamicInfo;
|
||||
if (dynamicNames.TryGetValue(name, out dynamicInfo))
|
||||
{
|
||||
metadataBuilder.AddCustomDebugInformation(
|
||||
parent: lastLocalConstantHandle,
|
||||
kind: metadataBuilder.GetOrAddGuid(PortableCustomDebugInfoKinds.DynamicLocalVariables),
|
||||
value: SerializeDynamicLocalBlob(metadataBuilder, dynamicInfo));
|
||||
}
|
||||
}
|
||||
|
||||
int previousChildScopeEnd = start;
|
||||
foreach (ISymUnmanagedScope child in symScope.GetChildren())
|
||||
{
|
||||
int childScopeStart = child.GetStartOffset();
|
||||
int childScopeEnd = child.GetEndOffset();
|
||||
|
||||
// scopes are properly nested:
|
||||
if (childScopeStart < previousChildScopeEnd || childScopeEnd > end)
|
||||
{
|
||||
// TODO: loc/warning
|
||||
throw new BadImageFormatException($"Invalid scope IL offset range: [{childScopeStart}, {childScopeEnd}), method 0x{MetadataTokens.GetToken(methodHandle):x}.");
|
||||
}
|
||||
|
||||
previousChildScopeEnd = childScopeEnd;
|
||||
|
||||
SerializeScope(metadataBuilder, metadataModel, methodHandle, importScopeHandle, child, dynamicSlots, dynamicNames, vbSemantics, ref lastLocalVariableHandle, ref lastLocalConstantHandle);
|
||||
}
|
||||
}
|
||||
|
||||
private unsafe static BlobHandle SerializeConstantSignature(MetadataBuilder metadataBuilder, MetadataModel metadataModel, byte[] signature, object value)
|
||||
{
|
||||
var builder = new BlobBuilder();
|
||||
ConstantSignatureConverter.Convert(builder, metadataModel, signature, value);
|
||||
return metadataBuilder.GetOrAddBlob(builder);
|
||||
}
|
||||
|
||||
private static BlobHandle SerializeDynamicLocalBlob(MetadataBuilder metadataBuilder, DynamicLocalInfo dynamicInfo)
|
||||
{
|
||||
Debug.Assert(dynamicInfo.FlagCount > 0);
|
||||
Debug.Assert(dynamicInfo.Flags != 0);
|
||||
|
||||
var builder = new BlobBuilder();
|
||||
|
||||
int c = dynamicInfo.FlagCount - 1;
|
||||
ulong flags = dynamicInfo.Flags;
|
||||
|
||||
// trim trailing 0s:
|
||||
while ((flags & (1u << c)) == 0) c--;
|
||||
|
||||
int b = 0;
|
||||
int shift = 0;
|
||||
for (int i = 0; i <= c; i++)
|
||||
{
|
||||
bool bit = (flags & (1u << c)) != 0;
|
||||
|
||||
if (bit)
|
||||
{
|
||||
b |= 1 << shift;
|
||||
}
|
||||
|
||||
if (shift == 7)
|
||||
{
|
||||
builder.WriteByte((byte)b);
|
||||
b = 0;
|
||||
shift = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
shift++;
|
||||
}
|
||||
}
|
||||
|
||||
if (b != 0)
|
||||
{
|
||||
builder.WriteByte((byte)b);
|
||||
}
|
||||
|
||||
return metadataBuilder.GetOrAddBlob(builder);
|
||||
}
|
||||
|
||||
private static LocalVariableHandle NextHandle(LocalVariableHandle handle) =>
|
||||
MetadataTokens.LocalVariableHandle(MetadataTokens.GetRowNumber(handle) + 1);
|
||||
|
||||
private static LocalConstantHandle NextHandle(LocalConstantHandle handle) =>
|
||||
MetadataTokens.LocalConstantHandle(MetadataTokens.GetRowNumber(handle) + 1);
|
||||
|
||||
private static BlobHandle SerializeSequencePoints(
|
||||
MetadataBuilder metadataBuilder,
|
||||
int localSignatureRowId,
|
||||
ImmutableArray<SymUnmanagedSequencePoint> sequencePoints,
|
||||
Dictionary<string, DocumentHandle> documentIndex,
|
||||
out DocumentHandle singleDocumentHandle)
|
||||
{
|
||||
if (sequencePoints.Length == 0)
|
||||
{
|
||||
singleDocumentHandle = default(DocumentHandle);
|
||||
return default(BlobHandle);
|
||||
}
|
||||
|
||||
var writer = new BlobBuilder();
|
||||
|
||||
int previousNonHiddenStartLine = -1;
|
||||
int previousNonHiddenStartColumn = -1;
|
||||
|
||||
// header:
|
||||
writer.WriteCompressedInteger(localSignatureRowId);
|
||||
|
||||
DocumentHandle previousDocument = TryGetSingleDocument(sequencePoints, documentIndex);
|
||||
singleDocumentHandle = previousDocument;
|
||||
|
||||
for (int i = 0; i < sequencePoints.Length; i++)
|
||||
{
|
||||
var currentDocument = documentIndex[sequencePoints[i].Document.GetName()];
|
||||
if (previousDocument != currentDocument)
|
||||
{
|
||||
// optional document in header or document record:
|
||||
if (!previousDocument.IsNil)
|
||||
{
|
||||
writer.WriteCompressedInteger(0);
|
||||
}
|
||||
|
||||
writer.WriteCompressedInteger(MetadataTokens.GetHeapOffset(currentDocument));
|
||||
previousDocument = currentDocument;
|
||||
}
|
||||
|
||||
// delta IL offset:
|
||||
if (i > 0)
|
||||
{
|
||||
writer.WriteCompressedInteger((sequencePoints[i].Offset - sequencePoints[i - 1].Offset));
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteCompressedInteger(sequencePoints[i].Offset);
|
||||
}
|
||||
|
||||
if (sequencePoints[i].IsHidden)
|
||||
{
|
||||
writer.WriteInt16(0);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Delta Lines & Columns:
|
||||
SerializeDeltaLinesAndColumns(writer, sequencePoints[i]);
|
||||
|
||||
// delta Start Lines & Columns:
|
||||
if (previousNonHiddenStartLine < 0)
|
||||
{
|
||||
Debug.Assert(previousNonHiddenStartColumn < 0);
|
||||
writer.WriteCompressedInteger(sequencePoints[i].StartLine);
|
||||
writer.WriteCompressedInteger(sequencePoints[i].StartColumn);
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteCompressedSignedInteger(sequencePoints[i].StartLine - previousNonHiddenStartLine);
|
||||
writer.WriteCompressedSignedInteger(sequencePoints[i].StartColumn - previousNonHiddenStartColumn);
|
||||
}
|
||||
|
||||
previousNonHiddenStartLine = sequencePoints[i].StartLine;
|
||||
previousNonHiddenStartColumn = sequencePoints[i].StartColumn;
|
||||
}
|
||||
|
||||
return metadataBuilder.GetOrAddBlob(writer);
|
||||
}
|
||||
|
||||
private static DocumentHandle TryGetSingleDocument(ImmutableArray<SymUnmanagedSequencePoint> sequencePoints, Dictionary<string, DocumentHandle> documentIndex)
|
||||
{
|
||||
DocumentHandle singleDocument = documentIndex[sequencePoints[0].Document.GetName()];
|
||||
for (int i = 1; i < sequencePoints.Length; i++)
|
||||
{
|
||||
if (documentIndex[sequencePoints[i].Document.GetName()] != singleDocument)
|
||||
{
|
||||
return default(DocumentHandle);
|
||||
}
|
||||
}
|
||||
|
||||
return singleDocument;
|
||||
}
|
||||
|
||||
private static void SerializeDeltaLinesAndColumns(BlobBuilder writer, SymUnmanagedSequencePoint sequencePoint)
|
||||
{
|
||||
int deltaLines = sequencePoint.EndLine - sequencePoint.StartLine;
|
||||
int deltaColumns = sequencePoint.EndColumn - sequencePoint.StartColumn;
|
||||
|
||||
// only hidden sequence points have zero width
|
||||
Debug.Assert(deltaLines != 0 || deltaColumns != 0 || sequencePoint.IsHidden);
|
||||
|
||||
writer.WriteCompressedInteger(deltaLines);
|
||||
|
||||
if (deltaLines == 0)
|
||||
{
|
||||
writer.WriteCompressedInteger(deltaColumns);
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteCompressedSignedInteger(deltaColumns);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Reflection.PortableExecutable;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Microsoft.DiaSymReader.Tools
|
||||
{
|
||||
public static class SymReaderFactory
|
||||
{
|
||||
[DefaultDllImportSearchPaths(DllImportSearchPath.AssemblyDirectory)]
|
||||
[DllImport("Microsoft.DiaSymReader.Native.x86.dll", EntryPoint = "CreateSymReader")]
|
||||
private extern static void CreateSymReader32(ref Guid id, [MarshalAs(UnmanagedType.IUnknown)]out object symReader);
|
||||
|
||||
[DefaultDllImportSearchPaths(DllImportSearchPath.AssemblyDirectory)]
|
||||
[DllImport("Microsoft.DiaSymReader.Native.amd64.dll", EntryPoint = "CreateSymReader")]
|
||||
private extern static void CreateSymReader64(ref Guid id, [MarshalAs(UnmanagedType.IUnknown)]out object symReader);
|
||||
|
||||
public static ISymUnmanagedReader3 CreateWindowsPdbReader(Stream pdbStream, PEReader peReader)
|
||||
{
|
||||
object symReader = null;
|
||||
|
||||
var guid = default(Guid);
|
||||
if (IntPtr.Size == 4)
|
||||
{
|
||||
CreateSymReader32(ref guid, out symReader);
|
||||
}
|
||||
else
|
||||
{
|
||||
CreateSymReader64(ref guid, out symReader);
|
||||
}
|
||||
|
||||
var reader = (ISymUnmanagedReader3)symReader;
|
||||
reader.Initialize(pdbStream, new SymReaderMetadataImport(peReader.GetMetadataReader(), peReader));
|
||||
return reader;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,451 +0,0 @@
|
|||
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Reflection.Metadata.Ecma335;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Microsoft.DiaSymReader.Tools
|
||||
{
|
||||
/// <summary>
|
||||
/// Minimal implementation of IMetadataImport that implements APIs used by SymReader.
|
||||
/// </summary>
|
||||
internal sealed class SymReaderMetadataImport : IMetadataImport, IDisposable
|
||||
{
|
||||
private readonly MetadataReader _metadataReaderOpt;
|
||||
private readonly IDisposable _metadataOwnerOpt;
|
||||
private readonly List<GCHandle> _pinnedBuffers;
|
||||
|
||||
public SymReaderMetadataImport(MetadataReader metadataReaderOpt, IDisposable metadataOwnerOpt)
|
||||
{
|
||||
_metadataReaderOpt = metadataReaderOpt;
|
||||
_pinnedBuffers = new List<GCHandle>();
|
||||
_metadataOwnerOpt = metadataOwnerOpt;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
GC.SuppressFinalize(this);
|
||||
Dispose(true);
|
||||
}
|
||||
|
||||
private void Dispose(bool disposing)
|
||||
{
|
||||
_metadataOwnerOpt?.Dispose();
|
||||
|
||||
foreach (var pinnedBuffer in _pinnedBuffers)
|
||||
{
|
||||
pinnedBuffer.Free();
|
||||
}
|
||||
}
|
||||
|
||||
~SymReaderMetadataImport()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
[PreserveSig]
|
||||
public unsafe int GetSigFromToken(
|
||||
int tkSignature, // Signature token.
|
||||
out byte* ppvSig, // return pointer to signature blob
|
||||
out int pcbSig) // return size of signature
|
||||
{
|
||||
if (_metadataReaderOpt == null)
|
||||
{
|
||||
throw new NotSupportedException("Metadata not available");
|
||||
}
|
||||
|
||||
var sig = _metadataReaderOpt.GetStandaloneSignature((StandaloneSignatureHandle)MetadataTokens.Handle(tkSignature));
|
||||
var signature = _metadataReaderOpt.GetBlobBytes(sig.Signature);
|
||||
|
||||
GCHandle pinnedBuffer = GCHandle.Alloc(signature, GCHandleType.Pinned);
|
||||
ppvSig = (byte*)pinnedBuffer.AddrOfPinnedObject();
|
||||
pcbSig = signature.Length;
|
||||
|
||||
_pinnedBuffers.Add(pinnedBuffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void GetTypeDefProps(
|
||||
int typeDefinition,
|
||||
[MarshalAs(UnmanagedType.LPWStr), Out]StringBuilder qualifiedName,
|
||||
int qualifiedNameBufferLength,
|
||||
out int qualifiedNameLength,
|
||||
[MarshalAs(UnmanagedType.U4)]out TypeAttributes attributes,
|
||||
out int baseType)
|
||||
{
|
||||
if (_metadataReaderOpt == null)
|
||||
{
|
||||
throw new NotSupportedException("Metadata not available");
|
||||
}
|
||||
|
||||
var handle = (TypeDefinitionHandle)MetadataTokens.Handle(typeDefinition);
|
||||
var typeDef = _metadataReaderOpt.GetTypeDefinition(handle);
|
||||
|
||||
if (qualifiedName != null)
|
||||
{
|
||||
qualifiedName.Clear();
|
||||
|
||||
if (!typeDef.Namespace.IsNil)
|
||||
{
|
||||
qualifiedName.Append(_metadataReaderOpt.GetString(typeDef.Namespace));
|
||||
qualifiedName.Append('.');
|
||||
}
|
||||
|
||||
qualifiedName.Append(_metadataReaderOpt.GetString(typeDef.Name));
|
||||
qualifiedNameLength = qualifiedName.Length;
|
||||
}
|
||||
else
|
||||
{
|
||||
qualifiedNameLength =
|
||||
(typeDef.Namespace.IsNil ? 0 : _metadataReaderOpt.GetString(typeDef.Namespace).Length + 1) +
|
||||
_metadataReaderOpt.GetString(typeDef.Name).Length;
|
||||
}
|
||||
|
||||
baseType = MetadataTokens.GetToken(typeDef.BaseType);
|
||||
attributes = typeDef.Attributes;
|
||||
}
|
||||
|
||||
public void GetTypeRefProps(
|
||||
int typeReference,
|
||||
out int resolutionScope,
|
||||
[MarshalAs(UnmanagedType.LPWStr), Out]StringBuilder qualifiedName,
|
||||
int qualifiedNameBufferLength,
|
||||
out int qualifiedNameLength)
|
||||
{
|
||||
if (_metadataReaderOpt == null)
|
||||
{
|
||||
throw new NotSupportedException("Metadata not available");
|
||||
}
|
||||
|
||||
var handle = (TypeReferenceHandle)MetadataTokens.Handle(typeReference);
|
||||
var typeRef = _metadataReaderOpt.GetTypeReference(handle);
|
||||
|
||||
if (qualifiedName != null)
|
||||
{
|
||||
qualifiedName.Clear();
|
||||
|
||||
if (!typeRef.Namespace.IsNil)
|
||||
{
|
||||
qualifiedName.Append(_metadataReaderOpt.GetString(typeRef.Namespace));
|
||||
qualifiedName.Append('.');
|
||||
}
|
||||
|
||||
qualifiedName.Append(_metadataReaderOpt.GetString(typeRef.Name));
|
||||
qualifiedNameLength = qualifiedName.Length;
|
||||
}
|
||||
else
|
||||
{
|
||||
qualifiedNameLength =
|
||||
(typeRef.Namespace.IsNil ? 0 : _metadataReaderOpt.GetString(typeRef.Namespace).Length + 1) +
|
||||
_metadataReaderOpt.GetString(typeRef.Name).Length;
|
||||
}
|
||||
|
||||
resolutionScope = MetadataTokens.GetToken(typeRef.ResolutionScope);
|
||||
}
|
||||
|
||||
#region Not Implemented
|
||||
|
||||
public void CloseEnum(uint handleEnum)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public uint CountEnum(uint handleEnum)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public uint EnumCustomAttributes(ref uint handlePointerEnum, uint tk, uint tokenType, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)]uint[] arrayCustomAttributes, uint countMax)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public unsafe uint EnumEvents(ref uint handlePointerEnum, uint td, uint* arrayEvents, uint countMax)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public unsafe uint EnumFields(ref uint handlePointerEnum, uint cl, uint* arrayFields, uint countMax)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public uint EnumFieldsWithName(ref uint handlePointerEnum, uint cl, string stringName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)]uint[] arrayFields, uint countMax)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public uint EnumInterfaceImpls(ref uint handlePointerEnum, uint td, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)]uint[] arrayImpls, uint countMax)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public uint EnumMemberRefs(ref uint handlePointerEnum, uint tokenParent, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)]uint[] arrayMemberRefs, uint countMax)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public uint EnumMembers(ref uint handlePointerEnum, uint cl, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)]uint[] arrayMembers, uint countMax)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public uint EnumMembersWithName(ref uint handlePointerEnum, uint cl, string stringName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)]uint[] arrayMembers, uint countMax)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public uint EnumMethodImpls(ref uint handlePointerEnum, uint td, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)]uint[] arrayMethodBody, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)]uint[] arrayMethodDecl, uint countMax)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public unsafe uint EnumMethods(ref uint handlePointerEnum, uint cl, uint* arrayMethods, uint countMax)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public uint EnumMethodSemantics(ref uint handlePointerEnum, uint mb, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)]uint[] arrayEventProp, uint countMax)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public uint EnumMethodsWithName(ref uint handlePointerEnum, uint cl, string stringName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)]uint[] arrayMethods, uint countMax)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public uint EnumModuleRefs(ref uint handlePointerEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)]uint[] arrayModuleRefs, uint cmax)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public uint EnumParams(ref uint handlePointerEnum, uint mb, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)]uint[] arrayParams, uint countMax)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public uint EnumPermissionSets(ref uint handlePointerEnum, uint tk, uint dwordActions, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)]uint[] arrayPermission, uint countMax)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public unsafe uint EnumProperties(ref uint handlePointerEnum, uint td, uint* arrayProperties, uint countMax)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public uint EnumSignatures(ref uint handlePointerEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)]uint[] arraySignatures, uint cmax)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public uint EnumTypeDefs(ref uint handlePointerEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)]uint[] arrayTypeDefs, uint countMax)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public uint EnumTypeRefs(ref uint handlePointerEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)]uint[] arrayTypeRefs, uint countMax)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public uint EnumTypeSpecs(ref uint handlePointerEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)]uint[] arrayTypeSpecs, uint cmax)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public uint EnumUnresolvedMethods(ref uint handlePointerEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)]uint[] arrayMethods, uint countMax)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public uint EnumUserStrings(ref uint handlePointerEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)]uint[] arrayStrings, uint cmax)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public uint FindField(uint td, string stringName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)]byte[] voidPointerSigBlob, uint byteCountSigBlob)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public uint FindMember(uint td, string stringName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)]byte[] voidPointerSigBlob, uint byteCountSigBlob)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public uint FindMemberRef(uint td, string stringName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)]byte[] voidPointerSigBlob, uint byteCountSigBlob)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public uint FindMethod(uint td, string stringName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)]byte[] voidPointerSigBlob, uint byteCountSigBlob)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public uint FindTypeDefByName(string stringTypeDef, uint tokenEnclosingClass)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public uint FindTypeRef(uint tokenResolutionScope, string stringName)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public uint GetClassLayout(uint td, out uint pdwPackSize, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)]ulong[] arrayFieldOffset, uint countMax, out uint countPointerFieldOffset)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public unsafe uint GetCustomAttributeByName(uint tokenObj, string stringName, out void* ppData)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public unsafe uint GetCustomAttributeProps(uint cv, out uint ptkObj, out uint ptkType, out void* ppBlob)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public uint GetEventProps(uint ev, out uint pointerClass, StringBuilder stringEvent, uint cchEvent, out uint pchEvent, out uint pdwEventFlags, out uint ptkEventType, out uint pmdAddOn, out uint pmdRemoveOn, out uint pmdFire, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 11)]uint[] rmdOtherMethod, uint countMax)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public unsafe uint GetFieldMarshal(uint tk, out byte* ppvNativeType)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public unsafe uint GetFieldProps(uint mb, out uint pointerClass, StringBuilder stringField, uint cchField, out uint pchField, out uint pdwAttr, out byte* ppvSigBlob, out uint pcbSigBlob, out uint pdwCPlusTypeFlag, out void* ppValue)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public uint GetInterfaceImplProps(uint impl, out uint pointerClass)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public unsafe uint GetMemberProps(uint mb, out uint pointerClass, StringBuilder stringMember, uint cchMember, out uint pchMember, out uint pdwAttr, out byte* ppvSigBlob, out uint pcbSigBlob, out uint pulCodeRVA, out uint pdwImplFlags, out uint pdwCPlusTypeFlag, out void* ppValue)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public unsafe uint GetMemberRefProps(uint mr, ref uint ptk, StringBuilder stringMember, uint cchMember, out uint pchMember, out byte* ppvSigBlob)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public uint GetMethodProps(uint mb, out uint pointerClass, IntPtr stringMethod, uint cchMethod, out uint pchMethod, IntPtr pdwAttr, IntPtr ppvSigBlob, IntPtr pcbSigBlob, IntPtr pulCodeRVA)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public uint GetMethodSemantics(uint mb, uint tokenEventProp)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public uint GetModuleFromScope()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public uint GetModuleRefProps(uint mur, StringBuilder stringName, uint cchName)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public uint GetNameFromToken(uint tk)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public unsafe uint GetNativeCallConvFromSig(void* voidPointerSig, uint byteCountSig)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public uint GetNestedClassProps(uint typeDefNestedClass)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public int GetParamForMethodIndex(uint md, uint ulongParamSeq, out uint pointerParam)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public unsafe uint GetParamProps(uint tk, out uint pmd, out uint pulSequence, StringBuilder stringName, uint cchName, out uint pchName, out uint pdwAttr, out uint pdwCPlusTypeFlag, out void* ppValue)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public unsafe uint GetPermissionSetProps(uint pm, out uint pdwAction, out void* ppvPermission)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public uint GetPinvokeMap(uint tk, out uint pdwMappingFlags, StringBuilder stringImportName, uint cchImportName, out uint pchImportName)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public unsafe uint GetPropertyProps(uint prop, out uint pointerClass, StringBuilder stringProperty, uint cchProperty, out uint pchProperty, out uint pdwPropFlags, out byte* ppvSig, out uint bytePointerSig, out uint pdwCPlusTypeFlag, out void* ppDefaultValue, out uint pcchDefaultValue, out uint pmdSetter, out uint pmdGetter, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 14)]uint[] rmdOtherMethod, uint countMax)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public uint GetRVA(uint tk, out uint pulCodeRVA)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Guid GetScopeProps(StringBuilder stringName, uint cchName, out uint pchName)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public unsafe uint GetTypeSpecFromToken(uint typespec, out byte* ppvSig)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public uint GetUserString(uint stk, StringBuilder stringString, uint cchString)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public int IsGlobal(uint pd)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public bool IsValidToken(uint tk)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void ResetEnum(uint handleEnum, uint ulongPos)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public uint ResolveTypeRef(uint tr, [In]ref Guid riid, [MarshalAs(UnmanagedType.Interface)]out object ppIScope)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -1,121 +0,0 @@
|
|||
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics;
|
||||
using Roslyn.Utilities;
|
||||
|
||||
namespace Microsoft.CodeAnalysis.Collections
|
||||
{
|
||||
internal sealed class ByteSequenceComparer : IEqualityComparer<byte[]>, IEqualityComparer<ImmutableArray<byte>>
|
||||
{
|
||||
internal static readonly ByteSequenceComparer Instance = new ByteSequenceComparer();
|
||||
|
||||
private ByteSequenceComparer()
|
||||
{
|
||||
}
|
||||
|
||||
internal static bool Equals(ImmutableArray<byte> x, ImmutableArray<byte> y)
|
||||
{
|
||||
if (x == y)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (x.IsDefault || y.IsDefault || x.Length != y.Length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0; i < x.Length; i++)
|
||||
{
|
||||
if (x[i] != y[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static bool Equals(byte[] left, int leftStart, byte[] right, int rightStart, int length)
|
||||
{
|
||||
if (left == null || right == null)
|
||||
{
|
||||
return ReferenceEquals(left, right);
|
||||
}
|
||||
|
||||
if (ReferenceEquals(left, right) && leftStart == rightStart)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
for (var i = 0; i < length; i++)
|
||||
{
|
||||
if (left[leftStart + i] != right[rightStart + i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static bool Equals(byte[] left, byte[] right)
|
||||
{
|
||||
if (ReferenceEquals(left, right))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (left == null || right == null || left.Length != right.Length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0; i < left.Length; i++)
|
||||
{
|
||||
if (left[i] != right[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Both hash computations below use the FNV-1a algorithm (http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function).
|
||||
|
||||
internal static int GetHashCode(byte[] x)
|
||||
{
|
||||
Debug.Assert(x != null);
|
||||
return Hash.GetFNVHashCode(x);
|
||||
}
|
||||
|
||||
internal static int GetHashCode(ImmutableArray<byte> x)
|
||||
{
|
||||
Debug.Assert(!x.IsDefault);
|
||||
return Hash.GetFNVHashCode(x);
|
||||
}
|
||||
|
||||
bool IEqualityComparer<byte[]>.Equals(byte[] x, byte[] y)
|
||||
{
|
||||
return Equals(x, y);
|
||||
}
|
||||
|
||||
int IEqualityComparer<byte[]>.GetHashCode(byte[] x)
|
||||
{
|
||||
return GetHashCode(x);
|
||||
}
|
||||
|
||||
bool IEqualityComparer<ImmutableArray<byte>>.Equals(ImmutableArray<byte> x, ImmutableArray<byte> y)
|
||||
{
|
||||
return Equals(x, y);
|
||||
}
|
||||
|
||||
int IEqualityComparer<ImmutableArray<byte>>.GetHashCode(ImmutableArray<byte> x)
|
||||
{
|
||||
return GetHashCode(x);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Roslyn.Utilities
|
||||
{
|
||||
internal static class ExceptionUtilities
|
||||
{
|
||||
internal static Exception UnexpectedValue(object o)
|
||||
{
|
||||
string output = string.Format("Unexpected value '{0}' of type '{1}'", o, (o != null) ? o.GetType().FullName : "<unknown>");
|
||||
Debug.Assert(false, output);
|
||||
|
||||
// We do not throw from here because we don't want all Watson reports to be bucketed to this call.
|
||||
return new InvalidOperationException(output);
|
||||
}
|
||||
|
||||
internal static Exception Unreachable
|
||||
{
|
||||
get { return new InvalidOperationException("This program location is thought to be unreachable."); }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,350 +0,0 @@
|
|||
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.IO;
|
||||
|
||||
namespace Roslyn.Utilities
|
||||
{
|
||||
internal static class Hash
|
||||
{
|
||||
/// <summary>
|
||||
/// This is how VB Anonymous Types combine hash values for fields.
|
||||
/// </summary>
|
||||
internal static int Combine(int newKey, int currentKey)
|
||||
{
|
||||
return unchecked((currentKey * (int)0xA5555529) + newKey);
|
||||
}
|
||||
|
||||
internal static int Combine(bool newKeyPart, int currentKey)
|
||||
{
|
||||
return Combine(currentKey, newKeyPart ? 1 : 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is how VB Anonymous Types combine hash values for fields.
|
||||
/// PERF: Do not use with enum types because that involves multiple
|
||||
/// unnecessary boxing operations. Unfortunately, we can't constrain
|
||||
/// T to "non-enum", so we'll use a more restrictive constraint.
|
||||
/// </summary>
|
||||
internal static int Combine<T>(T newKeyPart, int currentKey) where T : class
|
||||
{
|
||||
int hash = unchecked(currentKey * (int)0xA5555529);
|
||||
|
||||
if (newKeyPart != null)
|
||||
{
|
||||
return unchecked(hash + newKeyPart.GetHashCode());
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
internal static int CombineValues<T>(IEnumerable<T> values, int maxItemsToHash = int.MaxValue)
|
||||
{
|
||||
if (values == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
var hashCode = 0;
|
||||
var count = 0;
|
||||
foreach (var value in values)
|
||||
{
|
||||
if (count++ >= maxItemsToHash)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Should end up with a constrained virtual call to object.GetHashCode (i.e. avoid boxing where possible).
|
||||
if (value != null)
|
||||
{
|
||||
hashCode = Hash.Combine(value.GetHashCode(), hashCode);
|
||||
}
|
||||
}
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
internal static int CombineValues<T>(T[] values, int maxItemsToHash = int.MaxValue)
|
||||
{
|
||||
if (values == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
var maxSize = Math.Min(maxItemsToHash, values.Length);
|
||||
var hashCode = 0;
|
||||
|
||||
for (int i = 0; i < maxSize; i++)
|
||||
{
|
||||
T value = values[i];
|
||||
|
||||
// Should end up with a constrained virtual call to object.GetHashCode (i.e. avoid boxing where possible).
|
||||
if (value != null)
|
||||
{
|
||||
hashCode = Hash.Combine(value.GetHashCode(), hashCode);
|
||||
}
|
||||
}
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
internal static int CombineValues<T>(ImmutableArray<T> values, int maxItemsToHash = int.MaxValue)
|
||||
{
|
||||
if (values.IsDefaultOrEmpty)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
var hashCode = 0;
|
||||
var count = 0;
|
||||
foreach (var value in values)
|
||||
{
|
||||
if (count++ >= maxItemsToHash)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Should end up with a constrained virtual call to object.GetHashCode (i.e. avoid boxing where possible).
|
||||
if (value != null)
|
||||
{
|
||||
hashCode = Hash.Combine(value.GetHashCode(), hashCode);
|
||||
}
|
||||
}
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
internal static int CombineValues(IEnumerable<string> values, StringComparer stringComparer, int maxItemsToHash = int.MaxValue)
|
||||
{
|
||||
if (values == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
var hashCode = 0;
|
||||
var count = 0;
|
||||
foreach (var value in values)
|
||||
{
|
||||
if (count++ >= maxItemsToHash)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (value != null)
|
||||
{
|
||||
hashCode = Hash.Combine(stringComparer.GetHashCode(value), hashCode);
|
||||
}
|
||||
}
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The offset bias value used in the FNV-1a algorithm
|
||||
/// See http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
|
||||
/// </summary>
|
||||
internal const int FnvOffsetBias = unchecked((int)2166136261);
|
||||
|
||||
/// <summary>
|
||||
/// The generative factor used in the FNV-1a algorithm
|
||||
/// See http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
|
||||
/// </summary>
|
||||
internal const int FnvPrime = 16777619;
|
||||
|
||||
/// <summary>
|
||||
/// Compute the FNV-1a hash of a sequence of bytes
|
||||
/// See http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
|
||||
/// </summary>
|
||||
/// <param name="data">The sequence of bytes</param>
|
||||
/// <returns>The FNV-1a hash of <paramref name="data"/></returns>
|
||||
internal static int GetFNVHashCode(byte[] data)
|
||||
{
|
||||
int hashCode = Hash.FnvOffsetBias;
|
||||
|
||||
for (int i = 0; i < data.Length; i++)
|
||||
{
|
||||
hashCode = unchecked((hashCode ^ data[i]) * Hash.FnvPrime);
|
||||
}
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compute the FNV-1a hash of a sequence of bytes and determines if the byte
|
||||
/// sequence is valid ASCII and hence the hash code matches a char sequence
|
||||
/// encoding the same text.
|
||||
/// See http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
|
||||
/// </summary>
|
||||
/// <param name="data">The sequence of bytes that are likely to be ASCII text.</param>
|
||||
/// <param name="length">The length of the sequence.</param>
|
||||
/// <param name="isAscii">True if the sequence contains only characters in the ASCII range.</param>
|
||||
/// <returns>The FNV-1a hash of <paramref name="data"/></returns>
|
||||
internal static unsafe int GetFNVHashCode(byte* data, int length, out bool isAscii)
|
||||
{
|
||||
int hashCode = Hash.FnvOffsetBias;
|
||||
|
||||
byte asciiMask = 0;
|
||||
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
byte b = data[i];
|
||||
asciiMask |= b;
|
||||
hashCode = unchecked((hashCode ^ b) * Hash.FnvPrime);
|
||||
}
|
||||
|
||||
isAscii = (asciiMask & 0x80) == 0;
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compute the FNV-1a hash of a sequence of bytes
|
||||
/// See http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
|
||||
/// </summary>
|
||||
/// <param name="data">The sequence of bytes</param>
|
||||
/// <returns>The FNV-1a hash of <paramref name="data"/></returns>
|
||||
internal static int GetFNVHashCode(ImmutableArray<byte> data)
|
||||
{
|
||||
int hashCode = Hash.FnvOffsetBias;
|
||||
|
||||
for (int i = 0; i < data.Length; i++)
|
||||
{
|
||||
hashCode = unchecked((hashCode ^ data[i]) * Hash.FnvPrime);
|
||||
}
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compute the hashcode of a sub-string using FNV-1a
|
||||
/// See http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
|
||||
/// Note: FNV-1a was developed and tuned for 8-bit sequences. We're using it here
|
||||
/// for 16-bit Unicode chars on the understanding that the majority of chars will
|
||||
/// fit into 8-bits and, therefore, the algorithm will retain its desirable traits
|
||||
/// for generating hash codes.
|
||||
/// </summary>
|
||||
/// <param name="text">The input string</param>
|
||||
/// <param name="start">The start index of the first character to hash</param>
|
||||
/// <param name="length">The number of characters, beginning with <paramref name="start"/> to hash</param>
|
||||
/// <returns>The FNV-1a hash code of the substring beginning at <paramref name="start"/> and ending after <paramref name="length"/> characters.</returns>
|
||||
internal static int GetFNVHashCode(string text, int start, int length)
|
||||
{
|
||||
int hashCode = Hash.FnvOffsetBias;
|
||||
int end = start + length;
|
||||
|
||||
for (int i = start; i < end; i++)
|
||||
{
|
||||
hashCode = unchecked((hashCode ^ text[i]) * Hash.FnvPrime);
|
||||
}
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compute the hashcode of a sub-string using FNV-1a
|
||||
/// See http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
|
||||
/// </summary>
|
||||
/// <param name="text">The input string</param>
|
||||
/// <param name="start">The start index of the first character to hash</param>
|
||||
/// <returns>The FNV-1a hash code of the substring beginning at <paramref name="start"/> and ending at the end of the string.</returns>
|
||||
internal static int GetFNVHashCode(string text, int start)
|
||||
{
|
||||
return GetFNVHashCode(text, start, length: text.Length - start);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compute the hashcode of a string using FNV-1a
|
||||
/// See http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
|
||||
/// </summary>
|
||||
/// <param name="text">The input string</param>
|
||||
/// <returns>The FNV-1a hash code of <paramref name="text"/></returns>
|
||||
internal static int GetFNVHashCode(string text)
|
||||
{
|
||||
return CombineFNVHash(Hash.FnvOffsetBias, text);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compute the hashcode of a string using FNV-1a
|
||||
/// See http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
|
||||
/// </summary>
|
||||
/// <param name="text">The input string</param>
|
||||
/// <returns>The FNV-1a hash code of <paramref name="text"/></returns>
|
||||
internal static int GetFNVHashCode(System.Text.StringBuilder text)
|
||||
{
|
||||
int hashCode = Hash.FnvOffsetBias;
|
||||
int end = text.Length;
|
||||
|
||||
for (int i = 0; i < end; i++)
|
||||
{
|
||||
hashCode = unchecked((hashCode ^ text[i]) * Hash.FnvPrime);
|
||||
}
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compute the hashcode of a sub string using FNV-1a
|
||||
/// See http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
|
||||
/// </summary>
|
||||
/// <param name="text">The input string as a char array</param>
|
||||
/// <param name="start">The start index of the first character to hash</param>
|
||||
/// <param name="length">The number of characters, beginning with <paramref name="start"/> to hash</param>
|
||||
/// <returns>The FNV-1a hash code of the substring beginning at <paramref name="start"/> and ending after <paramref name="length"/> characters.</returns>
|
||||
internal static int GetFNVHashCode(char[] text, int start, int length)
|
||||
{
|
||||
int hashCode = Hash.FnvOffsetBias;
|
||||
int end = start + length;
|
||||
|
||||
for (int i = start; i < end; i++)
|
||||
{
|
||||
hashCode = unchecked((hashCode ^ text[i]) * Hash.FnvPrime);
|
||||
}
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compute the hashcode of a single character using the FNV-1a algorithm
|
||||
/// See http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
|
||||
/// Note: In general, this isn't any more useful than "char.GetHashCode". However,
|
||||
/// it may be needed if you need to generate the same hash code as a string or
|
||||
/// substring with just a single character.
|
||||
/// </summary>
|
||||
/// <param name="ch">The character to hash</param>
|
||||
/// <returns>The FNV-1a hash code of the character.</returns>
|
||||
internal static int GetFNVHashCode(char ch)
|
||||
{
|
||||
return Hash.CombineFNVHash(Hash.FnvOffsetBias, ch);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Combine a string with an existing FNV-1a hash code
|
||||
/// See http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
|
||||
/// </summary>
|
||||
/// <param name="hashCode">The accumulated hash code</param>
|
||||
/// <param name="text">The string to combine</param>
|
||||
/// <returns>The result of combining <paramref name="hashCode"/> with <paramref name="text"/> using the FNV-1a algorithm</returns>
|
||||
internal static int CombineFNVHash(int hashCode, string text)
|
||||
{
|
||||
foreach (char ch in text)
|
||||
{
|
||||
hashCode = unchecked((hashCode ^ ch) * Hash.FnvPrime);
|
||||
}
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Combine a char with an existing FNV-1a hash code
|
||||
/// See http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
|
||||
/// </summary>
|
||||
/// <param name="hashCode">The accumulated hash code</param>
|
||||
/// <param name="ch">The new character to combine</param>
|
||||
/// <returns>The result of combining <paramref name="hashCode"/> with <paramref name="ch"/> using the FNV-1a algorithm</returns>
|
||||
internal static int CombineFNVHash(int hashCode, char ch)
|
||||
{
|
||||
return unchecked((hashCode ^ ch) * Hash.FnvPrime);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,96 +0,0 @@
|
|||
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Reflection.Metadata.Ecma335;
|
||||
|
||||
namespace System.Reflection.Metadata
|
||||
{
|
||||
// TODO: move to SRM
|
||||
|
||||
internal struct ImportDefinitionEncoder
|
||||
{
|
||||
public MetadataBuilder MetadataBuilder { get; }
|
||||
public BlobBuilder Builder { get; }
|
||||
|
||||
public ImportDefinitionEncoder(MetadataBuilder metadataBuilder, BlobBuilder builder)
|
||||
{
|
||||
MetadataBuilder = metadataBuilder;
|
||||
Builder = builder;
|
||||
}
|
||||
|
||||
public void Type(EntityHandle type, string alias = null)
|
||||
{
|
||||
if (alias != null)
|
||||
{
|
||||
// <import> ::= AliasType <alias> <target-type>
|
||||
Builder.WriteByte((byte)ImportDefinitionKind.AliasType);
|
||||
Builder.WriteCompressedInteger(MetadataTokens.GetHeapOffset(MetadataBuilder.GetOrAddBlobUTF8(alias)));
|
||||
}
|
||||
else
|
||||
{
|
||||
// <import> ::= ImportType <target-type>
|
||||
Builder.WriteByte((byte)ImportDefinitionKind.ImportType);
|
||||
}
|
||||
|
||||
Builder.WriteCompressedInteger(CodedIndex.TypeDefOrRefOrSpec(type));
|
||||
}
|
||||
|
||||
public void Namespace(string namespaceName, string alias = null, AssemblyReferenceHandle externAlias = default(AssemblyReferenceHandle))
|
||||
{
|
||||
if (!externAlias.IsNil)
|
||||
{
|
||||
if (alias != null)
|
||||
{
|
||||
// <import> ::= AliasAssemblyNamespace <alias> <target-assembly> <target-namespace>
|
||||
Builder.WriteByte((byte)ImportDefinitionKind.AliasAssemblyNamespace);
|
||||
Builder.WriteCompressedInteger(MetadataTokens.GetHeapOffset(MetadataBuilder.GetOrAddBlobUTF8(alias)));
|
||||
}
|
||||
else
|
||||
{
|
||||
// <import> ::= ImportAssemblyNamespace <target-assembly> <target-namespace>
|
||||
Builder.WriteByte((byte)ImportDefinitionKind.ImportAssemblyNamespace);
|
||||
}
|
||||
|
||||
Builder.WriteCompressedInteger(MetadataTokens.GetRowNumber(externAlias));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (alias != null)
|
||||
{
|
||||
// <import> ::= AliasNamespace <alias> <target-namespace>
|
||||
Builder.WriteByte((byte)ImportDefinitionKind.AliasNamespace);
|
||||
Builder.WriteCompressedInteger(MetadataTokens.GetHeapOffset(MetadataBuilder.GetOrAddBlobUTF8(alias)));
|
||||
}
|
||||
else
|
||||
{
|
||||
// <import> ::= ImportNamespace <target-namespace>
|
||||
Builder.WriteByte((byte)ImportDefinitionKind.ImportNamespace);
|
||||
}
|
||||
}
|
||||
|
||||
Builder.WriteCompressedInteger(MetadataTokens.GetHeapOffset(MetadataBuilder.GetOrAddBlobUTF8(namespaceName)));
|
||||
}
|
||||
|
||||
public void XmlNamespace(string alias, string target)
|
||||
{
|
||||
// <import> ::= ImportXmlNamespace <alias> <target-namespace>
|
||||
Builder.WriteByte((byte)ImportDefinitionKind.ImportXmlNamespace);
|
||||
Builder.WriteCompressedInteger(MetadataTokens.GetHeapOffset(MetadataBuilder.GetOrAddBlobUTF8(alias)));
|
||||
Builder.WriteCompressedInteger(MetadataTokens.GetHeapOffset(MetadataBuilder.GetOrAddBlobUTF8(target)));
|
||||
}
|
||||
|
||||
public void ImportAssemblyReferenceAlias(string alias)
|
||||
{
|
||||
// <import> ::= ImportAssemblyReferenceAlias <alias>
|
||||
Builder.WriteByte((byte)ImportDefinitionKind.ImportAssemblyReferenceAlias);
|
||||
Builder.WriteCompressedInteger(MetadataTokens.GetHeapOffset(MetadataBuilder.GetOrAddBlobUTF8(alias)));
|
||||
}
|
||||
|
||||
public void AliasAssemblyReference(AssemblyReferenceHandle assemblyReference, string alias)
|
||||
{
|
||||
// <import> ::= AliasAssemblyReference <alias> <target-assembly>
|
||||
Builder.WriteByte((byte)ImportDefinitionKind.AliasAssemblyReference);
|
||||
Builder.WriteCompressedInteger(MetadataTokens.GetHeapOffset(MetadataBuilder.GetOrAddBlobUTF8(alias)));
|
||||
Builder.WriteCompressedInteger(MetadataTokens.GetRowNumber(assemblyReference));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,254 +0,0 @@
|
|||
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Text;
|
||||
using Microsoft.CodeAnalysis.Collections;
|
||||
using Roslyn.Utilities;
|
||||
|
||||
namespace Roslyn.Utilities
|
||||
{
|
||||
public static class MetadataHelpers
|
||||
{
|
||||
internal static string GetAssemblyDisplayName(MetadataReader reader, AssemblyReference assemblyRef)
|
||||
{
|
||||
string nameStr = reader.GetString(assemblyRef.Name);
|
||||
string cultureName = assemblyRef.Culture.IsNil ? "" : reader.GetString(assemblyRef.Culture);
|
||||
ImmutableArray<byte> publicKeyOrToken = reader.GetBlobContent(assemblyRef.PublicKeyOrToken);
|
||||
bool hasPublicKey = (assemblyRef.Flags & AssemblyFlags.PublicKey) != 0;
|
||||
|
||||
if (publicKeyOrToken.IsEmpty)
|
||||
{
|
||||
publicKeyOrToken = default(ImmutableArray<byte>);
|
||||
}
|
||||
|
||||
return BuildDisplayName(
|
||||
name: nameStr,
|
||||
version: assemblyRef.Version,
|
||||
cultureName: cultureName,
|
||||
publicKeyOrToken: publicKeyOrToken,
|
||||
hasPublicKey: hasPublicKey,
|
||||
isRetargetable: (assemblyRef.Flags & AssemblyFlags.Retargetable) != 0,
|
||||
contentType: (AssemblyContentType)((int)(assemblyRef.Flags & AssemblyFlags.ContentTypeMask) >> 9));
|
||||
}
|
||||
|
||||
internal const string InvariantCultureDisplay = "neutral";
|
||||
internal const int PublicKeyTokenSize = 8;
|
||||
|
||||
private static string BuildDisplayName(
|
||||
string name,
|
||||
Version version,
|
||||
string cultureName,
|
||||
ImmutableArray<byte> publicKeyOrToken,
|
||||
bool hasPublicKey,
|
||||
bool isRetargetable,
|
||||
AssemblyContentType contentType)
|
||||
{
|
||||
PooledStringBuilder pooledBuilder = PooledStringBuilder.GetInstance();
|
||||
var sb = pooledBuilder.Builder;
|
||||
EscapeName(sb, name);
|
||||
|
||||
sb.Append(", Version=");
|
||||
sb.Append(version.Major);
|
||||
sb.Append(".");
|
||||
sb.Append(version.Minor);
|
||||
sb.Append(".");
|
||||
sb.Append(version.Build);
|
||||
sb.Append(".");
|
||||
sb.Append(version.Revision);
|
||||
|
||||
sb.Append(", Culture=");
|
||||
if (cultureName.Length == 0)
|
||||
{
|
||||
sb.Append(InvariantCultureDisplay);
|
||||
}
|
||||
else
|
||||
{
|
||||
EscapeName(sb, cultureName);
|
||||
}
|
||||
|
||||
if (hasPublicKey)
|
||||
{
|
||||
sb.Append(", PublicKey=");
|
||||
AppendKey(sb, publicKeyOrToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append(", PublicKeyToken=");
|
||||
if (publicKeyOrToken.Length > 0)
|
||||
{
|
||||
AppendKey(sb, publicKeyOrToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append("null");
|
||||
}
|
||||
}
|
||||
|
||||
if (isRetargetable)
|
||||
{
|
||||
sb.Append(", Retargetable=Yes");
|
||||
}
|
||||
|
||||
switch (contentType)
|
||||
{
|
||||
case AssemblyContentType.Default:
|
||||
break;
|
||||
|
||||
case AssemblyContentType.WindowsRuntime:
|
||||
sb.Append(", ContentType=WindowsRuntime");
|
||||
break;
|
||||
|
||||
default:
|
||||
throw ExceptionUtilities.UnexpectedValue(contentType);
|
||||
}
|
||||
|
||||
string result = sb.ToString();
|
||||
pooledBuilder.Free();
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void AppendKey(StringBuilder sb, ImmutableArray<byte> key)
|
||||
{
|
||||
foreach (byte b in key)
|
||||
{
|
||||
sb.Append(b.ToString("x2"));
|
||||
}
|
||||
}
|
||||
|
||||
private static void EscapeName(StringBuilder result, string name)
|
||||
{
|
||||
bool quoted = false;
|
||||
if (IsWhiteSpace(name[0]) || IsWhiteSpace(name[name.Length - 1]))
|
||||
{
|
||||
result.Append('"');
|
||||
quoted = true;
|
||||
}
|
||||
|
||||
for (int i = 0; i < name.Length; i++)
|
||||
{
|
||||
char c = name[i];
|
||||
switch (c)
|
||||
{
|
||||
case ',':
|
||||
case '=':
|
||||
case '\\':
|
||||
case '"':
|
||||
case '\'':
|
||||
result.Append('\\');
|
||||
result.Append(c);
|
||||
break;
|
||||
|
||||
case '\t':
|
||||
result.Append("\\t");
|
||||
break;
|
||||
|
||||
case '\r':
|
||||
result.Append("\\r");
|
||||
break;
|
||||
|
||||
case '\n':
|
||||
result.Append("\\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
result.Append(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (quoted)
|
||||
{
|
||||
result.Append('"');
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsWhiteSpace(char c)
|
||||
{
|
||||
return c == ' ' || c == '\t' || c == '\r' || c == '\n';
|
||||
}
|
||||
|
||||
public static SignatureTypeCode GetConstantTypeCode(object value)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return (SignatureTypeCode)SignatureTypeKind.Class;
|
||||
}
|
||||
|
||||
Debug.Assert(!value.GetType().GetTypeInfo().IsEnum);
|
||||
|
||||
// Perf: Note that JIT optimizes each expression val.GetType() == typeof(T) to a single register comparison.
|
||||
// Also the checks are sorted by commonality of the checked types.
|
||||
|
||||
if (value.GetType() == typeof(int))
|
||||
{
|
||||
return SignatureTypeCode.Int32;
|
||||
}
|
||||
|
||||
if (value.GetType() == typeof(string))
|
||||
{
|
||||
return SignatureTypeCode.String;
|
||||
}
|
||||
|
||||
if (value.GetType() == typeof(bool))
|
||||
{
|
||||
return SignatureTypeCode.Boolean;
|
||||
}
|
||||
|
||||
if (value.GetType() == typeof(char))
|
||||
{
|
||||
return SignatureTypeCode.Char;
|
||||
}
|
||||
|
||||
if (value.GetType() == typeof(byte))
|
||||
{
|
||||
return SignatureTypeCode.Byte;
|
||||
}
|
||||
|
||||
if (value.GetType() == typeof(long))
|
||||
{
|
||||
return SignatureTypeCode.Int64;
|
||||
}
|
||||
|
||||
if (value.GetType() == typeof(double))
|
||||
{
|
||||
return SignatureTypeCode.Double;
|
||||
}
|
||||
|
||||
if (value.GetType() == typeof(short))
|
||||
{
|
||||
return SignatureTypeCode.Int16;
|
||||
}
|
||||
|
||||
if (value.GetType() == typeof(ushort))
|
||||
{
|
||||
return SignatureTypeCode.UInt16;
|
||||
}
|
||||
|
||||
if (value.GetType() == typeof(uint))
|
||||
{
|
||||
return SignatureTypeCode.UInt32;
|
||||
}
|
||||
|
||||
if (value.GetType() == typeof(sbyte))
|
||||
{
|
||||
return SignatureTypeCode.SByte;
|
||||
}
|
||||
|
||||
if (value.GetType() == typeof(ulong))
|
||||
{
|
||||
return SignatureTypeCode.UInt64;
|
||||
}
|
||||
|
||||
if (value.GetType() == typeof(float))
|
||||
{
|
||||
return SignatureTypeCode.Single;
|
||||
}
|
||||
|
||||
throw ExceptionUtilities.Unreachable;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,422 +0,0 @@
|
|||
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
#if F
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Microsoft.CodeAnalysis.Collections;
|
||||
using Roslyn.Utilities;
|
||||
|
||||
namespace Microsoft.CodeAnalysis.Metadata
|
||||
{
|
||||
internal struct AssemblyQualifiedTypeName
|
||||
{
|
||||
internal readonly string TopLevelType;
|
||||
internal readonly string[] NestedTypes;
|
||||
internal readonly AssemblyQualifiedTypeName[] TypeArguments;
|
||||
internal readonly int PointerCount;
|
||||
internal readonly int[] ArrayRanks;
|
||||
internal readonly string AssemblyName;
|
||||
|
||||
internal AssemblyQualifiedTypeName(
|
||||
string topLevelType,
|
||||
string[] nestedTypes,
|
||||
AssemblyQualifiedTypeName[] typeArguments,
|
||||
int pointerCount,
|
||||
int[] arrayRanks,
|
||||
string assemblyName)
|
||||
{
|
||||
this.TopLevelType = topLevelType;
|
||||
this.NestedTypes = nestedTypes;
|
||||
this.TypeArguments = typeArguments;
|
||||
this.PointerCount = pointerCount;
|
||||
this.ArrayRanks = arrayRanks;
|
||||
this.AssemblyName = assemblyName;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decodes a serialized type name in its canonical form. The canonical name is its full type name, followed
|
||||
/// optionally by the assembly where it is defined, its version, culture and public key token. If the assembly
|
||||
/// name is omitted, the type name is in the current assembly otherwise it is in the referenced assembly. The
|
||||
/// full type name is the fully qualified metadata type name.
|
||||
/// </summary>
|
||||
internal struct SerializedTypeDecoder
|
||||
{
|
||||
private const char GenericTypeNameManglingChar = '`';
|
||||
|
||||
private static readonly char[] s_typeNameDelimiters = { '+', ',', '[', ']', '*' };
|
||||
private readonly string _input;
|
||||
private int _offset;
|
||||
|
||||
public SerializedTypeDecoder(string s)
|
||||
{
|
||||
_input = s;
|
||||
_offset = 0;
|
||||
}
|
||||
|
||||
private void Advance()
|
||||
{
|
||||
if (!EndOfInput)
|
||||
{
|
||||
_offset++;
|
||||
}
|
||||
}
|
||||
|
||||
private void AdvanceTo(int i)
|
||||
{
|
||||
if (i <= _input.Length)
|
||||
{
|
||||
_offset = i;
|
||||
}
|
||||
}
|
||||
|
||||
private bool EndOfInput
|
||||
{
|
||||
get
|
||||
{
|
||||
return _offset >= _input.Length;
|
||||
}
|
||||
}
|
||||
|
||||
private int Offset
|
||||
{
|
||||
get
|
||||
{
|
||||
return _offset;
|
||||
}
|
||||
}
|
||||
|
||||
private char Current
|
||||
{
|
||||
get
|
||||
{
|
||||
return _input[_offset];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decodes a type name. A type name is a string which is terminated by the end of the string or one of the
|
||||
/// delimiters '+', ',', '[', ']'. '+' separates nested classes. '[' and ']'
|
||||
/// enclosed generic type arguments. ',' separates types.
|
||||
/// </summary>
|
||||
internal AssemblyQualifiedTypeName DecodeTypeName(bool isTypeArgument = false, bool isTypeArgumentWithAssemblyName = false)
|
||||
{
|
||||
Debug.Assert(!isTypeArgumentWithAssemblyName || isTypeArgument);
|
||||
|
||||
string topLevelType = null;
|
||||
ArrayBuilder<string> nestedTypesBuilder = null;
|
||||
AssemblyQualifiedTypeName[] typeArguments = null;
|
||||
int pointerCount = 0;
|
||||
ArrayBuilder<int> arrayRanksBuilder = null;
|
||||
string assemblyName = null;
|
||||
bool decodingTopLevelType = true;
|
||||
bool isGenericTypeName = false;
|
||||
|
||||
var pooledStrBuilder = PooledStringBuilder.GetInstance();
|
||||
StringBuilder typeNameBuilder = pooledStrBuilder.Builder;
|
||||
|
||||
while (!EndOfInput)
|
||||
{
|
||||
int i = _input.IndexOfAny(s_typeNameDelimiters, _offset);
|
||||
if (i >= 0)
|
||||
{
|
||||
char c = _input[i];
|
||||
|
||||
// Found name, which could be a generic name with arity.
|
||||
// Generic type parameter count, if any, are handled in DecodeGenericName.
|
||||
string decodedString = DecodeGenericName(i);
|
||||
Debug.Assert(decodedString != null);
|
||||
|
||||
// Type name is generic if the decoded name of the top level type OR any of the outer types of a nested type had the '`' character.
|
||||
isGenericTypeName = isGenericTypeName || decodedString.IndexOf(GenericTypeNameManglingChar) >= 0;
|
||||
typeNameBuilder.Append(decodedString);
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '*':
|
||||
if (arrayRanksBuilder != null)
|
||||
{
|
||||
// Error case, array shape must be specified at the end of the type name.
|
||||
// Process as a regular character and continue.
|
||||
typeNameBuilder.Append(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
pointerCount++;
|
||||
}
|
||||
|
||||
Advance();
|
||||
break;
|
||||
|
||||
case '+':
|
||||
if (arrayRanksBuilder != null || pointerCount > 0)
|
||||
{
|
||||
// Error case, array shape must be specified at the end of the type name.
|
||||
// Process as a regular character and continue.
|
||||
typeNameBuilder.Append(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Type followed by nested type. Handle nested class separator and collect the nested types.
|
||||
HandleDecodedTypeName(typeNameBuilder.ToString(), decodingTopLevelType, ref topLevelType, ref nestedTypesBuilder);
|
||||
typeNameBuilder.Clear();
|
||||
decodingTopLevelType = false;
|
||||
}
|
||||
|
||||
Advance();
|
||||
break;
|
||||
|
||||
case '[':
|
||||
// Is type followed by generic type arguments?
|
||||
if (isGenericTypeName && typeArguments == null)
|
||||
{
|
||||
Advance();
|
||||
if (arrayRanksBuilder != null || pointerCount > 0)
|
||||
{
|
||||
// Error case, array shape must be specified at the end of the type name.
|
||||
// Process as a regular character and continue.
|
||||
typeNameBuilder.Append(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Decode type arguments.
|
||||
typeArguments = DecodeTypeArguments();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Decode array shape.
|
||||
DecodeArrayShape(typeNameBuilder, ref arrayRanksBuilder);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case ']':
|
||||
if (isTypeArgument)
|
||||
{
|
||||
// End of type arguments. This occurs when the last type argument is a type in the
|
||||
// current assembly.
|
||||
goto ExitDecodeTypeName;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Error case, process as a regular character and continue.
|
||||
typeNameBuilder.Append(c);
|
||||
Advance();
|
||||
break;
|
||||
}
|
||||
|
||||
case ',':
|
||||
// A comma may separate a type name from its assembly name or a type argument from
|
||||
// another type argument.
|
||||
// If processing non-type argument or a type argument with assembly name,
|
||||
// process the characters after the comma as an assembly name.
|
||||
if (!isTypeArgument || isTypeArgumentWithAssemblyName)
|
||||
{
|
||||
Advance();
|
||||
if (!EndOfInput && Char.IsWhiteSpace(Current))
|
||||
{
|
||||
Advance();
|
||||
}
|
||||
|
||||
assemblyName = DecodeAssemblyName(isTypeArgumentWithAssemblyName);
|
||||
}
|
||||
goto ExitDecodeTypeName;
|
||||
|
||||
default:
|
||||
throw ExceptionUtilities.UnexpectedValue(c);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
typeNameBuilder.Append(DecodeGenericName(_input.Length));
|
||||
goto ExitDecodeTypeName;
|
||||
}
|
||||
}
|
||||
|
||||
ExitDecodeTypeName:
|
||||
HandleDecodedTypeName(typeNameBuilder.ToString(), decodingTopLevelType, ref topLevelType, ref nestedTypesBuilder);
|
||||
pooledStrBuilder.Free();
|
||||
|
||||
return new AssemblyQualifiedTypeName(
|
||||
topLevelType,
|
||||
nestedTypesBuilder?.ToArrayAndFree(),
|
||||
typeArguments,
|
||||
pointerCount,
|
||||
arrayRanksBuilder?.ToArrayAndFree(),
|
||||
assemblyName);
|
||||
}
|
||||
|
||||
private static void HandleDecodedTypeName(string decodedTypeName, bool decodingTopLevelType, ref string topLevelType, ref ArrayBuilder<string> nestedTypesBuilder)
|
||||
{
|
||||
if (decodedTypeName.Length != 0)
|
||||
{
|
||||
if (decodingTopLevelType)
|
||||
{
|
||||
Debug.Assert(topLevelType == null);
|
||||
topLevelType = decodedTypeName;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (nestedTypesBuilder == null)
|
||||
{
|
||||
nestedTypesBuilder = ArrayBuilder<string>.GetInstance();
|
||||
}
|
||||
|
||||
nestedTypesBuilder.Add(decodedTypeName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decodes a generic name. This is a type name followed optionally by a type parameter count
|
||||
/// </summary>
|
||||
private string DecodeGenericName(int i)
|
||||
{
|
||||
Debug.Assert(i == _input.Length || s_typeNameDelimiters.Contains(_input[i]));
|
||||
|
||||
var length = i - _offset;
|
||||
if (length == 0)
|
||||
{
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
// Save start of name. The name should be the emitted name including the '`' and arity.
|
||||
int start = _offset;
|
||||
AdvanceTo(i);
|
||||
|
||||
// Get the emitted name.
|
||||
return _input.Substring(start, _offset - start);
|
||||
}
|
||||
|
||||
private AssemblyQualifiedTypeName[] DecodeTypeArguments()
|
||||
{
|
||||
if (EndOfInput)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var typeBuilder = ArrayBuilder<AssemblyQualifiedTypeName>.GetInstance();
|
||||
|
||||
while (!EndOfInput)
|
||||
{
|
||||
typeBuilder.Add(DecodeTypeArgument());
|
||||
|
||||
if (!EndOfInput)
|
||||
{
|
||||
switch (Current)
|
||||
{
|
||||
case ',':
|
||||
// More type arguments follow
|
||||
Advance();
|
||||
if (!EndOfInput && Char.IsWhiteSpace(Current))
|
||||
{
|
||||
Advance();
|
||||
}
|
||||
break;
|
||||
|
||||
case ']':
|
||||
// End of type arguments
|
||||
Advance();
|
||||
return typeBuilder.ToArrayAndFree();
|
||||
|
||||
default:
|
||||
throw ExceptionUtilities.UnexpectedValue(EndOfInput);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return typeBuilder.ToArrayAndFree();
|
||||
}
|
||||
|
||||
private AssemblyQualifiedTypeName DecodeTypeArgument()
|
||||
{
|
||||
bool isTypeArgumentWithAssemblyName = false;
|
||||
if (Current == '[')
|
||||
{
|
||||
isTypeArgumentWithAssemblyName = true;
|
||||
Advance();
|
||||
}
|
||||
|
||||
AssemblyQualifiedTypeName result = DecodeTypeName(isTypeArgument: true, isTypeArgumentWithAssemblyName: isTypeArgumentWithAssemblyName);
|
||||
|
||||
if (isTypeArgumentWithAssemblyName)
|
||||
{
|
||||
if (!EndOfInput && Current == ']')
|
||||
{
|
||||
Advance();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private string DecodeAssemblyName(bool isTypeArgumentWithAssemblyName)
|
||||
{
|
||||
if (EndOfInput)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
int i;
|
||||
if (isTypeArgumentWithAssemblyName)
|
||||
{
|
||||
i = _input.IndexOf(']', _offset);
|
||||
if (i < 0)
|
||||
{
|
||||
i = _input.Length;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
i = _input.Length;
|
||||
}
|
||||
|
||||
string name = _input.Substring(_offset, i - _offset);
|
||||
AdvanceTo(i);
|
||||
return name;
|
||||
}
|
||||
|
||||
private void DecodeArrayShape(StringBuilder typeNameBuilder, ref ArrayBuilder<int> arrayRanksBuilder)
|
||||
{
|
||||
Debug.Assert(Current == '[');
|
||||
|
||||
int start = _offset;
|
||||
int rank = 1;
|
||||
Advance();
|
||||
|
||||
while (!EndOfInput)
|
||||
{
|
||||
switch (Current)
|
||||
{
|
||||
case ',':
|
||||
rank++;
|
||||
Advance();
|
||||
break;
|
||||
|
||||
case ']':
|
||||
if (arrayRanksBuilder == null)
|
||||
{
|
||||
arrayRanksBuilder = ArrayBuilder<int>.GetInstance();
|
||||
}
|
||||
|
||||
arrayRanksBuilder.Add(rank);
|
||||
Advance();
|
||||
return;
|
||||
|
||||
default:
|
||||
// Error case, process as regular characters
|
||||
Advance();
|
||||
typeNameBuilder.Append(_input.Substring(start, _offset - start));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Error case, process as regular characters
|
||||
typeNameBuilder.Append(_input.Substring(start, _offset - start));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -1,53 +0,0 @@
|
|||
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.DiaSymReader.Tools
|
||||
{
|
||||
internal static class SymReaderHelpers
|
||||
{
|
||||
internal static readonly Guid VisualBasicLanguageGuid = new Guid("3a12d0b8-c26c-11d0-b442-00a0244a1dd2");
|
||||
|
||||
public static ImmutableArray<string> GetImportStrings(ISymUnmanagedReader reader, int methodToken, int methodVersion)
|
||||
{
|
||||
var method = reader.GetMethodByVersion(methodToken, methodVersion);
|
||||
if (method == null)
|
||||
{
|
||||
// In rare circumstances (only bad PDBs?) GetMethodByVersion can return null.
|
||||
// If there's no debug info for the method, then no import strings are available.
|
||||
return ImmutableArray<string>.Empty;
|
||||
}
|
||||
|
||||
ISymUnmanagedScope rootScope = method.GetRootScope();
|
||||
if (rootScope == null)
|
||||
{
|
||||
// TODO: report warning?
|
||||
return ImmutableArray<string>.Empty;
|
||||
}
|
||||
|
||||
var childScopes = rootScope.GetChildren();
|
||||
if (childScopes.Length == 0)
|
||||
{
|
||||
// It seems like there should always be at least one child scope, but we've
|
||||
// seen PDBs where that is not the case.
|
||||
return ImmutableArray<string>.Empty;
|
||||
}
|
||||
|
||||
// As in NamespaceListWrapper::Init, we only consider namespaces in the first
|
||||
// child of the root scope.
|
||||
ISymUnmanagedScope firstChildScope = childScopes[0];
|
||||
|
||||
var namespaces = firstChildScope.GetNamespaces();
|
||||
if (namespaces.Length == 0)
|
||||
{
|
||||
// It seems like there should always be at least one namespace (i.e. the global
|
||||
// namespace), but we've seen PDBs where that is not the case.
|
||||
return ImmutableArray<string>.Empty;
|
||||
}
|
||||
|
||||
return ImmutableArray.CreateRange(namespaces.Select(n => n.GetName()));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"Microsoft.DiaSymReader": "1.1.0",
|
||||
"Microsoft.DiaSymReader.Native": "1.5.0-beta2-24728",
|
||||
"System.Collections": "4.3.0",
|
||||
"System.Collections.Immutable": "1.3.1",
|
||||
"System.Diagnostics.Debug": "4.3.0",
|
||||
"System.Reflection.Metadata": "1.4.2",
|
||||
"System.Runtime": "4.3.0",
|
||||
"System.Runtime.Extensions": "4.3.0",
|
||||
"System.Runtime.InteropServices": "4.3.0",
|
||||
"System.ValueTuple": "4.3.0",
|
||||
"System.Text.RegularExpressions": "4.3.0"
|
||||
},
|
||||
"frameworks": {
|
||||
"netstandard1.3": {}
|
||||
}
|
||||
}
|
|
@ -83,7 +83,7 @@ namespace Microsoft.DiaSymReader.PortablePdb.UnitTests
|
|||
Assert.Equal(@"C:\F\B.cs", docB1.GetName());
|
||||
Assert.Equal(@"C:\F\C.cs", docC1.GetName());
|
||||
|
||||
Guid alg;
|
||||
var alg = default(Guid);
|
||||
int count;
|
||||
Assert.Equal(HResult.S_FALSE, docMain1.GetChecksum(0, out count, null));
|
||||
Assert.Equal(0, count);
|
||||
|
|
|
@ -1,29 +1,25 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -->
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ImportGroup>
|
||||
<Import Project="..\..\build\Targets\Settings.targets" />
|
||||
</ImportGroup>
|
||||
<!-- Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -->
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<ProjectGuid>{DEB3D675-5A3C-46DA-8945-F2EFAB135EA0}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<RootNamespace>Microsoft.DiaSymReader.PortablePdb.UnitTests</RootNamespace>
|
||||
<AssemblyName>Microsoft.DiaSymReader.PortablePdb.UnitTests</AssemblyName>
|
||||
<TargetFrameworks>netcoreapp1.0;net46</TargetFrameworks>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<TargetFrameworkVersion>v5.0</TargetFrameworkVersion>
|
||||
<TargetFrameworkProfile>
|
||||
</TargetFrameworkProfile>
|
||||
<TargetFrameworkIdentifier>.NETPortable</TargetFrameworkIdentifier>
|
||||
<NuGetTargetMoniker>.NETStandard,Version=v1.3</NuGetTargetMoniker>
|
||||
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<!--
|
||||
We would need to download 32bit dotnet cli, which would add extra time to PR runs
|
||||
Testing 64bit only on Desktop suffixiently covers our interop code paths.
|
||||
-->
|
||||
<TestArchitectures Condition="'$(TargetFramework)' == 'net46'">x64;x86</TestArchitectures>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'" />
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Microsoft.DiaSymReader.PortablePdb\Microsoft.DiaSymReader.PortablePdb.csproj">
|
||||
<Project>{f83343ba-b4ea-451c-b6db-5d645e6171bc}</Project>
|
||||
<Name>Microsoft.DiaSymReader.PortablePdb</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Microsoft.DiaSymReader.PortablePdb\Microsoft.DiaSymReader.PortablePdb.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.DiaSymReader.Native" Version="$(MicrosoftDiaSymReaderNativeVersion)" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Remove="Resources\**\*.cs" />
|
||||
<Content Include="Resources\**\*.cs" />
|
||||
<Content Include="Resources\**\*.cmd" />
|
||||
<Content Include="Resources\**\*.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Resources\Async.dll">
|
||||
|
@ -144,50 +140,20 @@
|
|||
<LogicalName>EncMethodExtents.2.pdbx</LogicalName>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="Resources\Documents.cmd" />
|
||||
<Content Include="Resources\Documents.cs" />
|
||||
<Content Include="Resources\EmbeddedSource.cmd" />
|
||||
<Content Include="Resources\Scopes.cmd" />
|
||||
<Content Include="Resources\Scopes.cs" />
|
||||
<Content Include="Resources\Async.cmd" />
|
||||
<Content Include="Resources\Async.cs" />
|
||||
<Content Include="Resources\MethodBoundaries.cmd" />
|
||||
<Content Include="Resources\MethodBoundaries.cs" />
|
||||
<Content Include="Resources\MiscEmbedded.cmd" />
|
||||
<Content Include="Resources\MiscEmbedded.cs" />
|
||||
<Content Include="Resources\SourceLink.cmd" />
|
||||
<Content Include="Resources\EncMethodExtents\Readme.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="EmbeddedSourceTests.cs" />
|
||||
<Compile Include="EncTests.cs" />
|
||||
<Compile Include="MethodMapTests.cs" />
|
||||
<Compile Include="TestHelpers\TestResource.cs" />
|
||||
<Compile Include="TestHelpers\ResourceLoader.cs" />
|
||||
<Compile Include="SymBinderTests.cs" />
|
||||
<Compile Include="TestHelpers\PdbTestData.cs" />
|
||||
<Compile Include="TestHelpers\SymTestHelpers.cs" />
|
||||
<Compile Include="TestHelpers\TestResources.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="TestHelpers\AssertEx.cs" />
|
||||
<Compile Include="Utilities\EnumerableHelpersTests.cs" />
|
||||
<Compile Include="Utilities\SymMetadataImport.cs" />
|
||||
<Compile Include="SymReaderTests.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\Shared\App.config" />
|
||||
<None Include="project.json" />
|
||||
<None Include="Microsoft.DiaSymReader.PortablePdb.UnitTests.xunit.runner.json">
|
||||
<Content Include="$(NuGetPackageRoot)\Microsoft.DiaSymReader.Native\$(MicrosoftDiaSymReaderNativeVersion)\runtimes\win\native\Microsoft.DiaSymReader.Native.x86.dll">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<Visible>false</Visible>
|
||||
<Link>Microsoft.DiaSymReader.Native.x86.dll</Link>
|
||||
</Content>
|
||||
<Content Include="$(NuGetPackageRoot)\Microsoft.DiaSymReader.Native\$(MicrosoftDiaSymReaderNativeVersion)\runtimes\win\native\Microsoft.DiaSymReader.Native.amd64.dll">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<Visible>false</Visible>
|
||||
<Link>Microsoft.DiaSymReader.Native.amd64.dll</Link>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
|
||||
</ItemGroup>
|
||||
<ImportGroup>
|
||||
<Import Project="..\..\build\Targets\Imports.targets" />
|
||||
<Import Project="..\..\build\Toolset\XunitProjectRunAction.targets" />
|
||||
</ImportGroup>
|
||||
|
||||
<!-- Workaround for https://github.com/Microsoft/msbuild/issues/1721. -->
|
||||
<Import Project="..\Directory.Build.targets" Condition="'$(TargetFramework)' == ''" />
|
||||
</Project>
|
|
@ -1,24 +0,0 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"Microsoft.DiaSymReader.Native": "1.5.0-beta1",
|
||||
"Microsoft.NETCore.Portable.Compatibility": "1.0.1",
|
||||
"System.Collections": "4.3.0",
|
||||
"System.Diagnostics.Debug": "4.3.0",
|
||||
"System.IO.Compression": "4.3.0",
|
||||
"System.IO.FileSystem": "4.3.0",
|
||||
"System.Runtime": "4.3.0",
|
||||
"System.Runtime.Extensions": "4.3.0",
|
||||
"System.Runtime.InteropServices": "4.3.0",
|
||||
"System.IO.Compression": "4.3.0",
|
||||
"System.IO.FileSystem": "4.3.0",
|
||||
"Microsoft.DiaSymReader.Native": "1.5.0-beta2-24728",
|
||||
"xunit": "2.2.0-beta4-build3444",
|
||||
"xunit.runner.console": "2.2.0-beta4-build3444",
|
||||
"xunit.runner.visualstudio": "2.2.0-beta4-build1194"
|
||||
},
|
||||
"frameworks": {
|
||||
"netstandard1.3": {
|
||||
"imports": [ "portable-net452", "dotnet5.4" ]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,73 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -->
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ImportGroup>
|
||||
<Import Project="..\..\build\Targets\Settings.targets" />
|
||||
</ImportGroup>
|
||||
<!-- Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -->
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<ProjectGuid>{F83343BA-B4EA-451C-B6DB-5D645E6171BC}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<RootNamespace>Microsoft.DiaSymReader.PortablePdb</RootNamespace>
|
||||
<AssemblyName>Microsoft.DiaSymReader.PortablePdb</AssemblyName>
|
||||
<TargetFramework>netstandard1.1</TargetFramework>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<TargetFrameworkVersion>v5.0</TargetFrameworkVersion>
|
||||
<TargetFrameworkProfile>
|
||||
</TargetFrameworkProfile>
|
||||
<TargetFrameworkIdentifier>.NETPortable</TargetFrameworkIdentifier>
|
||||
<NuGetTargetMoniker>.NETStandard,Version=v1.1</NuGetTargetMoniker>
|
||||
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<IsPackable>true</IsPackable>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<NuspecFile>$(MSBuildProjectName).nuspec</NuspecFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'" />
|
||||
<ItemGroup>
|
||||
<Compile Include="AsyncMethodData.cs" />
|
||||
<Compile Include="InvalidInputDataException.cs" />
|
||||
<Compile Include="MethodExtent.cs" />
|
||||
<Compile Include="MethodExtents.cs" />
|
||||
<Compile Include="MethodLineDeltas.cs" />
|
||||
<Compile Include="MethodMap.cs" />
|
||||
<Compile Include="Utilities\BlobWriter.cs" />
|
||||
<Compile Include="MethodId.cs" />
|
||||
<Compile Include="DocumentId.cs" />
|
||||
<Compile Include="Utilities\EmptyArray.cs" />
|
||||
<Compile Include="Utilities\ExceptionUtilities.cs" />
|
||||
<Compile Include="Utilities\HashHelpers.cs" />
|
||||
<Compile Include="Utilities\ImmutableByteArrayInterop.cs" />
|
||||
<Compile Include="Utilities\ImmutableArrayExtensions.cs" />
|
||||
<Compile Include="Utilities\LazyMetadataImport.cs" />
|
||||
<Compile Include="Utilities\FileNameUtilities.cs" />
|
||||
<Compile Include="Utilities\HResult.cs" />
|
||||
<Compile Include="Utilities\InteropUtilities.cs" />
|
||||
<Compile Include="Utilities\KeyValuePair.cs" />
|
||||
<Compile Include="Utilities\MetadataUtilities.cs" />
|
||||
<Compile Include="Utilities\EnumerableHelpers.cs" />
|
||||
<Compile Include="DocumentMap.cs" />
|
||||
<Compile Include="IMetadataImport.cs" />
|
||||
<Compile Include="PortablePdbReader.cs" />
|
||||
<Compile Include="ScopeData.cs" />
|
||||
<Compile Include="RootScopeData.cs" />
|
||||
<Compile Include="ChildScopeData.cs" />
|
||||
<Compile Include="SymBinder.cs" />
|
||||
<Compile Include="SymScope.cs" />
|
||||
<Compile Include="SymConstant.cs" />
|
||||
<Compile Include="SymDocument.cs" />
|
||||
<Compile Include="SymMethod.cs" />
|
||||
<Compile Include="SymReader.cs" />
|
||||
<Compile Include="SymVariable.cs" />
|
||||
<Compile Include="Utilities\PortableShim.cs" />
|
||||
<Compile Include="Utilities\ReadOnlyInteropStream.cs" />
|
||||
<Compile Include="Utilities\ReflectionUtilities.cs" />
|
||||
<Compile Include="Utilities\StreamExtensions.cs" />
|
||||
<Compile Include="Utilities\TupleElementNamesAttribute.cs" />
|
||||
<Compile Include="Utilities\ValueTuple.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="project.json" />
|
||||
<PackageReference Include="Microsoft.DiaSymReader" Version="$(MicrosoftDiaSymReaderVersion)" />
|
||||
<PackageReference Include="System.Collections.Immutable" Version="$(SystemCollectionsImmutableVersion)" />
|
||||
<PackageReference Include="System.Reflection.Metadata" Version="$(SystemReflectionMetadataVersion)" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<InternalsVisibleTo Include="Microsoft.DiaSymReader.PortablePdb.UnitTests" />
|
||||
</ItemGroup>
|
||||
<ImportGroup Label="Targets">
|
||||
<Import Project="..\..\build\Targets\Imports.targets" />
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -1,15 +0,0 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"System.Collections.Immutable": "1.3.1",
|
||||
"System.Reflection.Metadata": "1.4.2",
|
||||
"Microsoft.DiaSymReader": "1.1.0",
|
||||
"System.Collections": "4.3.0",
|
||||
"System.Diagnostics.Debug": "4.3.0",
|
||||
"System.Runtime": "4.3.0",
|
||||
"System.Runtime.Extensions": "4.3.0",
|
||||
"System.Runtime.InteropServices": "4.3.0"
|
||||
},
|
||||
"frameworks": {
|
||||
"netstandard1.1": {}
|
||||
}
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.DiaSymReader.Tools
|
||||
{
|
||||
internal static class Pdb2Pdb
|
||||
{
|
||||
public static int Main(string[] args)
|
||||
{
|
||||
if (args.Length < 1)
|
||||
{
|
||||
Console.WriteLine("Usage: Pdb2Pdb <PE file> [/src:<PDB path>] [/dst:<Portable PDB path>]");
|
||||
return 1;
|
||||
}
|
||||
|
||||
string peFile = args[0];
|
||||
var srcPdb = GetArgumentValue(args, "/src:") ?? Path.ChangeExtension(peFile, "pdb");
|
||||
var dstPdb = GetArgumentValue(args, "/dst:") ?? Path.ChangeExtension(peFile, "pdbx");
|
||||
|
||||
if (!File.Exists(peFile))
|
||||
{
|
||||
Console.WriteLine($"PE file not: {peFile}");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!File.Exists(srcPdb))
|
||||
{
|
||||
Console.WriteLine($"PDB file not: {srcPdb}");
|
||||
return 1;
|
||||
}
|
||||
|
||||
using (var peStream = new FileStream(peFile, FileMode.Open, FileAccess.Read))
|
||||
{
|
||||
using (var nativePdbStream = new FileStream(srcPdb, FileMode.Open, FileAccess.Read))
|
||||
{
|
||||
using (var portablePdbStream = new FileStream(dstPdb, FileMode.Create, FileAccess.ReadWrite))
|
||||
{
|
||||
PdbConverter.Convert(peStream, nativePdbStream, portablePdbStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static string GetArgumentValue(string[] args, string prefix)
|
||||
{
|
||||
return args.
|
||||
Where(arg => arg.StartsWith(prefix, StringComparison.Ordinal)).
|
||||
Select(arg => arg.Substring(prefix.Length)).LastOrDefault();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -->
|
||||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ImportGroup Label="Settings">
|
||||
<Import Project="..\..\build\Targets\Settings.targets" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup>
|
||||
<ProjectGuid>{C4C4BEEA-6E4C-4C03-841A-BB085AF9E097}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>Microsoft.DiaSymReader.Tools</RootNamespace>
|
||||
<AssemblyName>Pdb2Pdb</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
<LargeAddressAware>true</LargeAddressAware>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Pdb2Pdb.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\Shared\App.config" />
|
||||
<None Include="project.json" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Microsoft.DiaSymReader.Converter\Microsoft.DiaSymReader.Converter.csproj">
|
||||
<Project>{c0122b3f-86f0-4114-86f6-321535394c4e}</Project>
|
||||
<Name>Microsoft.DiaSymReader.Converter</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ImportGroup Label="Targets">
|
||||
<Import Project="..\..\build\Targets\Imports.targets" />
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -1,9 +0,0 @@
|
|||
{
|
||||
"dependencies": { },
|
||||
"frameworks": {
|
||||
"net46": {}
|
||||
},
|
||||
"runtimes": {
|
||||
"win": { }
|
||||
}
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<appSettings>
|
||||
<add key="xunit.shadowCopy" value="false"/> <!-- Set shadow copy to false so that the VS Test Explorer can properly load our public signed binaries -->
|
||||
</appSettings>
|
||||
<!-- Specify binding redirects since binding redirect auto-generation produces incorrect redirects for System.Runtime -->
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-1.2.1.0" newVersion="1.2.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.IO.Compression" publicKeyToken="b77a5c561934e089" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.1.2.0" newVersion="4.1.2.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.IO.FileSystem" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
</configuration>
|
Загрузка…
Ссылка в новой задаче