Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Add analyzer loading support for CoreCLR
Adds a new type, CoreClrAnalyzerAssemblyLoader, that is responsible
for finding and loading analyzer assemblies on CoreCLR. This is used
in the CscCore and VbcCore CoreCLR-targeting projects.
  • Loading branch information
agocke committed Sep 23, 2015
1 parent dd396a8 commit c601241
Show file tree
Hide file tree
Showing 17 changed files with 349 additions and 63 deletions.
7 changes: 5 additions & 2 deletions src/Compilers/CSharp/CscCore/CscCore.csproj
Expand Up @@ -67,8 +67,11 @@
<Compile Include="..\..\Helpers\ConsoleUtil.cs">
<Link>ConsoleUtil.cs</Link>
</Compile>
<Compile Include="..\..\Helpers\NoOpAnalyzerAssemblyLoader.cs">
<Link>ConsoleUtil.cs</Link>
<Compile Include="..\..\Helpers\CoreClrAnalyzerAssemblyLoader.cs">
<Link>CoreClrAnalyzerAssemblyLoader.cs</Link>
</Compile>
<Compile Include="..\..\Helpers\AnalyzerAssemblyLoadUtils.cs">
<Link>AnalyzerAssemblyLoadUtils.cs</Link>
</Compile>
<Compile Include="Csc.cs" />
<Compile Include="Program.cs" />
Expand Down
3 changes: 2 additions & 1 deletion src/Compilers/CSharp/CscCore/Program.cs
Expand Up @@ -3,6 +3,7 @@
using System;
using System.IO;
using System.Runtime.InteropServices;
using Microsoft.CodeAnalysis;

namespace Microsoft.CodeAnalysis.CSharp.CommandLine
{
Expand All @@ -12,6 +13,6 @@ public static int Main(string[] args)
=> Csc.Run(args: args,
clientDirectory: AppContext.BaseDirectory,
sdkDirectory: null,
analyzerLoader: new NoOpAnalyzerAssemblyLoader());
analyzerLoader: CoreClrAnalyzerAssemblyLoader.CreateAndSetDefault());
}
}
3 changes: 2 additions & 1 deletion src/Compilers/CSharp/CscCore/project.json
Expand Up @@ -23,8 +23,9 @@
"System.Runtime.Extensions": "4.0.11-beta-23321",
"System.Runtime.Handles": "4.0.1-beta-23321",
"System.Runtime.InteropServices": "4.0.21-beta-23321",
"System.Security.Cryptography.Hashing.Algorithms": "4.0.0-beta-23311",
"System.Runtime.Loader": "4.0.0-beta-23321",
"System.Runtime.Serialization.Json": "4.0.1-beta-23321",
"System.Security.Cryptography.Hashing.Algorithms": "4.0.0-beta-23311",
"System.Text.Encoding": "4.0.11-beta-23321",
"System.Text.Encoding.Extensions": "4.0.11-beta-23321",
"System.Threading": "4.0.11-beta-23321",
Expand Down
52 changes: 52 additions & 0 deletions src/Compilers/CSharp/CscCore/project.lock.json
Expand Up @@ -478,6 +478,19 @@
"lib/DNXCore50/System.Runtime.InteropServices.dll": {}
}
},
"System.Runtime.Loader/4.0.0-beta-23321": {
"dependencies": {
"System.IO": "[4.0.0, )",
"System.Reflection": "[4.0.0, )",
"System.Runtime": "[4.0.0, )"
},
"compile": {
"ref/dotnet/System.Runtime.Loader.dll": {}
},
"runtime": {
"lib/DNXCore50/System.Runtime.Loader.dll": {}
}
},
"System.Runtime.Serialization.Json/4.0.1-beta-23321": {
"dependencies": {
"System.Private.DataContractSerialization": "[4.0.1-beta-23321, )"
Expand Down Expand Up @@ -1391,6 +1404,19 @@
"lib/DNXCore50/System.Runtime.InteropServices.dll": {}
}
},
"System.Runtime.Loader/4.0.0-beta-23321": {
"dependencies": {
"System.IO": "[4.0.0, )",
"System.Reflection": "[4.0.0, )",
"System.Runtime": "[4.0.0, )"
},
"compile": {
"ref/dotnet/System.Runtime.Loader.dll": {}
},
"runtime": {
"lib/DNXCore50/System.Runtime.Loader.dll": {}
}
},
"System.Runtime.Serialization.Json/4.0.1-beta-23321": {
"dependencies": {
"System.Private.DataContractSerialization": "[4.0.1-beta-23321, )"
Expand Down Expand Up @@ -2466,6 +2492,19 @@
"lib/DNXCore50/System.Runtime.InteropServices.dll": {}
}
},
"System.Runtime.Loader/4.0.0-beta-23321": {
"dependencies": {
"System.IO": "[4.0.0, )",
"System.Reflection": "[4.0.0, )",
"System.Runtime": "[4.0.0, )"
},
"compile": {
"ref/dotnet/System.Runtime.Loader.dll": {}
},
"runtime": {
"lib/DNXCore50/System.Runtime.Loader.dll": {}
}
},
"System.Runtime.Serialization.Json/4.0.1-beta-23321": {
"dependencies": {
"System.Private.DataContractSerialization": "[4.0.1-beta-23321, )"
Expand Down Expand Up @@ -4581,6 +4620,18 @@
"System.Runtime.InteropServices.nuspec"
]
},
"System.Runtime.Loader/4.0.0-beta-23321": {
"sha512": "xyfQB/CKuzy/kaiMWtNgX16mMTsgt2ktdmG7COIXBFAkHUARSeBAjMOWkGdNWPzOWINYumqamA8JxGsQlPhuPQ==",
"type": "Package",
"files": [
"[Content_Types].xml",
"_rels/.rels",
"lib/DNXCore50/System.Runtime.Loader.dll",
"package/services/metadata/core-properties/55d60ad8f5d24e06bf703dd426e1ec45.psmdcp",
"ref/dotnet/System.Runtime.Loader.dll",
"System.Runtime.Loader.nuspec"
]
},
"System.Runtime.Serialization.Json/4.0.1-beta-23321": {
"sha512": "TWQRwFnriFMykVgsCyowKFI5eLWoceMtoIrrx9Wd2ZL+XAnsdiYe8OUVeL9Q0kLVs3Ew12sPiXtY2wvVDAYR3w==",
"type": "Package",
Expand Down Expand Up @@ -5138,6 +5189,7 @@
"System.Runtime.Extensions >= 4.0.11-beta-23321",
"System.Runtime.Handles >= 4.0.1-beta-23321",
"System.Runtime.InteropServices >= 4.0.21-beta-23321",
"System.Runtime.Loader >= 4.0.0-beta-23321",
"System.Runtime.Serialization.Json >= 4.0.1-beta-23321",
"System.Security.Cryptography.Hashing.Algorithms >= 4.0.0-beta-23311",
"System.Text.Encoding >= 4.0.11-beta-23321",
Expand Down
5 changes: 4 additions & 1 deletion src/Compilers/CSharp/csc/csc.csproj
Expand Up @@ -53,6 +53,9 @@
<Compile Include="..\..\Helpers\AbstractAnalyzerAssemblyLoader.cs">
<Link>AbstractAnalyzerAssemblyLoader.cs</Link>
</Compile>
<Compile Include="..\..\Helpers\AnalyzerAssemblyLoadUtils.cs">
<Link>AnalyzerAssemblyLoadUtils.cs</Link>
</Compile>
<Compile Include="..\..\Helpers\ConsoleUtil.cs">
<Link>ConsoleUtil.cs</Link>
</Compile>
Expand All @@ -77,4 +80,4 @@
<ImportGroup Label="Targets">
<Import Project="..\..\..\..\build\Targets\VSL.Imports.targets" />
</ImportGroup>
</Project>
</Project>
3 changes: 3 additions & 0 deletions src/Compilers/Core/VBCSCompiler/VBCSCompiler.csproj
Expand Up @@ -51,6 +51,9 @@
<Compile Include="..\..\Helpers\AbstractAnalyzerAssemblyLoader.cs">
<Link>AbstractAnalyzerAssemblyLoader.cs</Link>
</Compile>
<Compile Include="..\..\Helpers\AnalyzerAssemblyLoadUtils.cs">
<Link>AnalyzerAssemblyLoadUtils.cs</Link>
</Compile>
<Compile Include="..\..\Helpers\ShadowCopyAnalyzerAssemblyLoader.cs">
<Link>ShadowCopyAnalyzerAssemblyLoader.cs</Link>
</Compile>
Expand Down
38 changes: 2 additions & 36 deletions src/Compilers/Helpers/AbstractAnalyzerAssemblyLoader.cs
Expand Up @@ -11,6 +11,8 @@
using System.Reflection.PortableExecutable;
using Roslyn.Utilities;

using static Microsoft.CodeAnalysis.AnalyzerAssemblyLoadUtils;

namespace Microsoft.CodeAnalysis
{
internal abstract class AbstractAnalyzerAssemblyLoader : IAnalyzerAssemblyLoader
Expand Down Expand Up @@ -148,41 +150,5 @@ private bool FileMatchesAssemblyName(string path, string assemblySimpleName)
{
return Path.GetFileNameWithoutExtension(path).Equals(assemblySimpleName, StringComparison.OrdinalIgnoreCase);
}

private static AssemblyIdentity TryGetAssemblyIdentity(string filePath)
{
try
{
if (!File.Exists(filePath))
{
return null;
}

using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete))
using (var peReader = new PEReader(stream))
{
var metadataReader = peReader.GetMetadataReader();

AssemblyDefinition assemblyDefinition = metadataReader.GetAssemblyDefinition();

string name = metadataReader.GetString(assemblyDefinition.Name);
Version version = assemblyDefinition.Version;

StringHandle cultureHandle = assemblyDefinition.Culture;
string cultureName = (!cultureHandle.IsNil) ? metadataReader.GetString(cultureHandle) : null;
AssemblyFlags flags = assemblyDefinition.Flags;

bool hasPublicKey = (flags & AssemblyFlags.PublicKey) != 0;
BlobHandle publicKeyHandle = assemblyDefinition.PublicKey;
ImmutableArray<byte> publicKeyOrToken = !publicKeyHandle.IsNil
? metadataReader.GetBlobBytes(publicKeyHandle).AsImmutableOrNull()
: default(ImmutableArray<byte>);
return new AssemblyIdentity(name, version, cultureName, publicKeyOrToken, hasPublicKey);
}
}
catch { }

return null;
}
}
}
45 changes: 45 additions & 0 deletions src/Compilers/Helpers/AnalyzerAssemblyLoadUtils.cs
@@ -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.

using System;
using System.Collections.Immutable;
using System.IO;
using System.Reflection;
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;

namespace Microsoft.CodeAnalysis
{
internal static class AnalyzerAssemblyLoadUtils
{
public static AssemblyIdentity TryGetAssemblyIdentity(string filePath)
{
try
{
using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete))
using (var peReader = new PEReader(stream))
{
var metadataReader = peReader.GetMetadataReader();

AssemblyDefinition assemblyDefinition = metadataReader.GetAssemblyDefinition();

string name = metadataReader.GetString(assemblyDefinition.Name);
Version version = assemblyDefinition.Version;

StringHandle cultureHandle = assemblyDefinition.Culture;
string cultureName = (!cultureHandle.IsNil) ? metadataReader.GetString(cultureHandle) : null;
AssemblyFlags flags = assemblyDefinition.Flags;

bool hasPublicKey = (flags & AssemblyFlags.PublicKey) != 0;
BlobHandle publicKeyHandle = assemblyDefinition.PublicKey;
ImmutableArray<byte> publicKeyOrToken = !publicKeyHandle.IsNil
? metadataReader.GetBlobBytes(publicKeyHandle).AsImmutableOrNull()
: default(ImmutableArray<byte>);
return new AssemblyIdentity(name, version, cultureName, publicKeyOrToken, hasPublicKey);
}
}
catch { }

return null;
}
}
}

0 comments on commit c601241

Please sign in to comment.