Skip to content

Commit

Permalink
lab: Add second solution to Roslyn Dependencies at Build and Runtime
Browse files Browse the repository at this point in the history
  • Loading branch information
ironcev committed Mar 11, 2020
1 parent 563c305 commit 0012e85
Show file tree
Hide file tree
Showing 33 changed files with 1,328 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using System;
using System.Reflection;
using System.Resources;
using System.Runtime.InteropServices;

[assembly: ComVisible(false)]
[assembly: CLSCompliant(false)]

[assembly: AssemblyCompany(AssemblyDescription.Company)]
[assembly: AssemblyTrademark(AssemblyDescription.Trademark)]
[assembly: AssemblyCopyright(AssemblyDescription.Copyright)]

[assembly: AssemblyConfiguration(AssemblyDescription.Configuration)]

[assembly: AssemblyTitle(AssemblyDescription.Title)]
[assembly: AssemblyProduct(AssemblyDescription.Product)]
[assembly: AssemblyDescription(AssemblyDescription.Description)]

[assembly: AssemblyVersion(AssemblyDescription.Version)]
// We will not set the AssemblyFileVersion explicitly. This will automatically make it same as the AssemblyVersion.
[assembly: AssemblyInformationalVersion(AssemblyDescription.InformationalVersion)]

[assembly: AssemblyCulture(AssemblyDescription.Culture)]
[assembly: NeutralResourcesLanguage("en-US")]


internal static partial class AssemblyDescription
{
public const string Company = "Igor Rončević";
public const string Trademark = "";
public const string Copyright = "Copyright © 2019 " + Company;
public const string Product = "Sharpen Lab - Roslyn Dependencies";

public const string Culture = "";

public const string Version = "0.1.0";

public const string Configuration =
#if DEBUG
"Debug"
#else
"Release"
#endif
;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using Microsoft.CodeAnalysis;
using Sharpen.Engine.CSharpVersionDependent;
using System.Reflection;

namespace Sharpen.Engine
{
public class CSharpVersionDependent_2_10_0_0 : ICSharpVersionDependent
{
public string DoSomethngWithNullableReferenceTypes(SyntaxTree syntaxTree)
{
return
$"This code is dynamically loaded from the assembly {Assembly.GetExecutingAssembly().FullName}.\n" +
"In this version nullable reference types do not exist, but it is a version newer then our oldest supported version.";
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace>Sharpen.Engine</RootNamespace>
<AssemblyName>Sharpen.Engine.2_10_0_0</AssemblyName>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="2.10.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Sharpen.Engine.CSharpVersionDependent\Sharpen.Engine.CSharpVersionDependent.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System.Linq;
using System.Reflection;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Sharpen.Engine.CSharpVersionDependent;

namespace Sharpen.Engine
{
public class CSharpVersionDependent_3_0_0_0 : ICSharpVersionDependent
{
public string DoSomethngWithNullableReferenceTypes(SyntaxTree syntaxTree)
{
var count = syntaxTree.GetRoot()
.DescendantNodes()
.Where(node => node.IsKind(SyntaxKind.NullableDirectiveTrivia) || node.IsKind(SyntaxKind.NullableKeyword) || node.IsKind(SyntaxKind.SuppressNullableWarningExpression))
.Count();

return
$"This code is dynamically loaded from the assembly {Assembly.GetExecutingAssembly().FullName}.\n" +
$"Found {count} nodes that have something to do with nullable reference types.";
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace>Sharpen.Engine</RootNamespace>
<AssemblyName>Sharpen.Engine.3_0_0_0</AssemblyName>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.0.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Sharpen.Engine.CSharpVersionDependent\Sharpen.Engine.CSharpVersionDependent.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using Microsoft.CodeAnalysis;

namespace Sharpen.Engine.CSharpVersionDependent
{
public interface ICSharpVersionDependent
{
string DoSomethngWithNullableReferenceTypes(SyntaxTree syntaxTree);
}
}
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>Key.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="2.4.0" />
</ItemGroup>

</Project>
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>

<IsPackable>false</IsPackable>

<GenerateAssemblyInfo>false</GenerateAssemblyInfo>

<AssemblyName>Sharpen.Engine.Tests.Unit</AssemblyName>

<RootNamespace>Sharpen.Engine.Tests.Unit</RootNamespace>

<SignAssembly>true</SignAssembly>

<AssemblyOriginatorKeyFile>Key.snk</AssemblyOriginatorKeyFile>

<LangVersion>7.3</LangVersion>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="nunit" Version="3.11.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.11.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Sharpen.Engine\Sharpen.Engine.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System;
using Microsoft.CodeAnalysis.CSharp;
using NUnit.Framework;

namespace Sharpen.Engine.Tests.Unit
{
[TestFixture]
class SomeSharpenEngineClassTests
{
[Test]
public void DoSomethingWithASyntaxTreeTest()
{
const string code = @"class C { }";

var output = new SomeSharpenEngineClass().DoSomethingWithTheSyntaxTree(CSharpSyntaxTree.ParseText(code));

Console.WriteLine(output);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Microsoft.CodeAnalysis;
using Sharpen.Engine.CSharpVersionDependent;

namespace Sharpen.Engine
{
internal class DefaultCSharpVersionDependent : ICSharpVersionDependent
{
public string DoSomethngWithNullableReferenceTypes(SyntaxTree syntaxTree)
{
return "In this version nullable reference types do not exist.";
}
}
}
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System.Runtime.CompilerServices;

[assembly: InternalsVisibleTo("Sharpen.Engine.Tests.Unit, PublicKey=0024000004800000940000000602000000240000525341310004000001000100614b19b4a82745f9909f03d76cd0b8fe17e00e7bcc1e44a7e8b1a80a23e6b9769b826cb4386f3747d32dcdffe8b77820f2dc3b5717e9a64e1f7e43d8eefec8b7f9f1b7510336c1ffdd35be5638b9f83269e72baa31e66f661c87c6480a4045f0504eb7b4aeac680cded36143b9fba53ca83901054deb08df0bda05db06d74bbb")]
// ReSharper disable CheckNamespace
internal static partial class AssemblyDescription
{
public const string Title = "Sharpen Lab - Roslyn Dependencies";

public const string Description = "Investigates the Roslyn dependencies at build and runtime in various versions of Visual Studio.";

public const string InformationalVersion = Version;
}
// ReSharper restore CheckNamespace
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace>Sharpen.Engine</RootNamespace>
<LangVersion>7.3</LangVersion>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>Key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign>
</PropertyGroup>

<ItemGroup>
<Compile Include="..\AssemblyInfo.Common.cs" Link="Properties\AssemblyInfo.Common.cs" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="2.4.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="2.4.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Sharpen.Engine.CSharpVersionDependent\Sharpen.Engine.CSharpVersionDependent.csproj">
<Private>true</Private>
</ProjectReference>
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using System;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Sharpen.Engine.CSharpVersionDependent;
using Sharpen.Engine.VersionDependent;

namespace Sharpen.Engine
{
public class SomeSharpenEngineClass
{
public string DoSomethingWithTheSyntaxTree(SyntaxTree syntaxTree)
{
ICSharpVersionDependent csharpVersionDependent = CSharpVersionDependentCreator.GetCSharpVersionDependentImplementation();

var versionDependentOutput = csharpVersionDependent.DoSomethngWithNullableReferenceTypes(syntaxTree);

return
"Assembly location:" +
Environment.NewLine +
syntaxTree.GetType().Assembly.Location +
Environment.NewLine +
"Assembly name and version:" +
Environment.NewLine +
syntaxTree.GetType().Assembly +
Environment.NewLine +
$"Number of {nameof(SyntaxNode)} types:" +
Environment.NewLine +
syntaxTree.GetType().Assembly
.ExportedTypes
.Count(type => typeof(SyntaxNode).IsAssignableFrom(type)) +
Environment.NewLine +
$"Number of {nameof(SyntaxKind)} entries:" +
Environment.NewLine +
Enum.GetValues(typeof(SyntaxKind)).Length +
Environment.NewLine +
$"Doing something with nullable reference types:" +
Environment.NewLine +
versionDependentOutput +
Environment.NewLine;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using Microsoft.CodeAnalysis;
using Sharpen.Engine.CSharpVersionDependent;
using System;
using System.Linq;
using System.Reflection;

namespace Sharpen.Engine.VersionDependent
{
public static class CSharpVersionDependentCreator
{
static CSharpVersionDependentCreator()
{
AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve;
}

private static ICSharpVersionDependent instance;
public static ICSharpVersionDependent GetCSharpVersionDependentImplementation()
{
return instance = instance ?? CreateCSharpVersionDependentImplementation();
}

private static readonly Assembly CSharpVersionDependentAssembly = typeof(ICSharpVersionDependent).Assembly;
private static Assembly OnAssemblyResolve(object sender, ResolveEventArgs args)
{
if (args.Name == CSharpVersionDependentAssembly.FullName)
return CSharpVersionDependentAssembly;
return null;
}

private static readonly Version version_2_4_0_0 = new Version(2, 4, 0, 0);
private static readonly Version version_2_10_0_0 = new Version(2, 10, 0, 0);
private static readonly Version version_3_0_0_0 = new Version(3, 0, 0, 0);
private static ICSharpVersionDependent CreateCSharpVersionDependentImplementation()
{
var version = typeof(SyntaxTree).Assembly.GetName().Version;

if (version >= version_3_0_0_0)
return GetCSharpVersionDependentFromAssembly(GetVersionDependentAssembly(version_3_0_0_0));
else if (version >= version_2_10_0_0)
return GetCSharpVersionDependentFromAssembly(GetVersionDependentAssembly(version_2_10_0_0));
else return new DefaultCSharpVersionDependent();
}

private static Assembly GetVersionDependentAssembly(Version version)
{
var versionSuffix = $"{version.Major}_{version.Minor}_{version.Build}_{version.Revision}";
var versionDependentAssemblyFileName = Assembly.GetExecutingAssembly().Location.Replace("Sharpen.Engine.dll", $"Sharpen.Engine.{versionSuffix}.dll");

return Assembly.LoadFile(versionDependentAssemblyFileName);
}

private static ICSharpVersionDependent GetCSharpVersionDependentFromAssembly(Assembly assembly)
{
var implementationType = assembly.ExportedTypes.Single(type => type.GetInterface(nameof(ICSharpVersionDependent)) != null);
return (ICSharpVersionDependent)Activator.CreateInstance(implementationType);
}
}
}
Loading

0 comments on commit 0012e85

Please sign in to comment.