Skip to content

Commit

Permalink
Add script references: kkokosa#5
Browse files Browse the repository at this point in the history
  • Loading branch information
norek committed Nov 1, 2018
1 parent cbb2bab commit c287f18
Show file tree
Hide file tree
Showing 12 changed files with 411 additions and 19 deletions.
20 changes: 20 additions & 0 deletions src/Tune.Core.Tests/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

[assembly: AssemblyTitle("Tune.Core.Tests")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Tune.Core.Tests")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

[assembly: ComVisible(false)]

[assembly: Guid("41aaabce-9e6a-49d1-9d08-7d82a89fd456")]

// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
31 changes: 31 additions & 0 deletions src/Tune.Core.Tests/ReferenceParserTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using Tune.Core.References;
using Xunit;

namespace Tune.Core.Tests
{
public class ReferenceParserTests
{
[Theory]
[InlineData("")]
[InlineData("//System.Core")]
[InlineData("System.Core")]
[InlineData("using System.Core")]
public void Input_WithoutMetaTag_Fails(string invalidInput)
{
var result = ReferenceParser.TryParse(invalidInput, out string reference);
Assert.False(result);
Assert.Equal(string.Empty, reference);
}

[Fact]
public void Correct_Input_Success()
{
string input = "//#r System.Core ";

var result = ReferenceParser.TryParse(input, out string reference);

Assert.True(result);
Assert.Equal("System.Core", reference);
}
}
}
124 changes: 124 additions & 0 deletions src/Tune.Core.Tests/Tune.Core.Tests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\xunit.runner.visualstudio.2.4.1\build\net20\xunit.runner.visualstudio.props" Condition="Exists('..\packages\xunit.runner.visualstudio.2.4.1\build\net20\xunit.runner.visualstudio.props')" />
<Import Project="..\packages\xunit.runner.console.2.4.1\build\xunit.runner.console.props" Condition="Exists('..\packages\xunit.runner.console.2.4.1\build\xunit.runner.console.props')" />
<Import Project="..\packages\xunit.core.2.4.1\build\xunit.core.props" Condition="Exists('..\packages\xunit.core.2.4.1\build\xunit.core.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{41AAABCE-9E6A-49D1-9D08-7D82A89FD456}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Tune.Core.Tests</RootNamespace>
<AssemblyName>Tune.Core.Tests</AssemblyName>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">15.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
<IsCodedUITest>False</IsCodedUITest>
<TestProjectType>UnitTest</TestProjectType>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="xunit.abstractions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\packages\xunit.abstractions.2.0.3\lib\net35\xunit.abstractions.dll</HintPath>
</Reference>
<Reference Include="xunit.assert, Version=2.4.1.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\packages\xunit.assert.2.4.1\lib\netstandard1.1\xunit.assert.dll</HintPath>
</Reference>
<Reference Include="xunit.core, Version=2.4.1.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\packages\xunit.extensibility.core.2.4.1\lib\net452\xunit.core.dll</HintPath>
</Reference>
<Reference Include="xunit.execution.desktop, Version=2.4.1.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\packages\xunit.extensibility.execution.2.4.1\lib\net452\xunit.execution.desktop.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="ReferenceParserTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Tune.Core\Tune.Core.csproj">
<Project>{3d3a7f7e-0a3a-43fd-8508-d1514ff57eb0}</Project>
<Name>Tune.Core</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Analyzer Include="..\packages\xunit.analyzers.0.10.0\analyzers\dotnet\cs\xunit.analyzers.dll" />
</ItemGroup>
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\xunit.core.2.4.1\build\xunit.core.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\xunit.core.2.4.1\build\xunit.core.props'))" />
<Error Condition="!Exists('..\packages\xunit.core.2.4.1\build\xunit.core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\xunit.core.2.4.1\build\xunit.core.targets'))" />
<Error Condition="!Exists('..\packages\xunit.runner.console.2.4.1\build\xunit.runner.console.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\xunit.runner.console.2.4.1\build\xunit.runner.console.props'))" />
<Error Condition="!Exists('..\packages\xunit.runner.visualstudio.2.4.1\build\net20\xunit.runner.visualstudio.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\xunit.runner.visualstudio.2.4.1\build\net20\xunit.runner.visualstudio.props'))" />
</Target>
<Import Project="..\packages\xunit.core.2.4.1\build\xunit.core.targets" Condition="Exists('..\packages\xunit.core.2.4.1\build\xunit.core.targets')" />
</Project>
31 changes: 31 additions & 0 deletions src/Tune.Core.Tests/app.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<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>
<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.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Security.Cryptography.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Xml.XPath.XDocument" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
</dependentAssembly>
<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>
</assemblyBinding>
</runtime>
</configuration>
12 changes: 12 additions & 0 deletions src/Tune.Core.Tests/packages.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="xunit" version="2.4.1" targetFramework="net46" />
<package id="xunit.abstractions" version="2.0.3" targetFramework="net46" />
<package id="xunit.analyzers" version="0.10.0" targetFramework="net46" />
<package id="xunit.assert" version="2.4.1" targetFramework="net46" />
<package id="xunit.core" version="2.4.1" targetFramework="net46" />
<package id="xunit.extensibility.core" version="2.4.1" targetFramework="net46" />
<package id="xunit.extensibility.execution" version="2.4.1" targetFramework="net46" />
<package id="xunit.runner.console" version="2.4.1" targetFramework="net46" developmentDependency="true" />
<package id="xunit.runner.visualstudio" version="2.4.1" targetFramework="net46" developmentDependency="true" />
</packages>
61 changes: 42 additions & 19 deletions src/Tune.Core/DiagnosticEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,47 +4,70 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Tune.Core.Paths;
using Tune.Core.References;

namespace Tune.Core
{
public class DiagnosticEngine
public partial class DiagnosticEngine
{
public delegate void LogHandler(string message);
public event LogHandler Log;

IAssemblyPathsRepository assemblyRepository;

public DiagnosticEngine()
{
this.nativeTarget = new NativeTarget(Process.GetCurrentProcess().Id);
this.assemblyRepository = new AssemblyPathsRepository();
}

public DiagnosticAssembly Compile(string script, DiagnosticAssemblyMode mode, DiagnosticAssembyPlatform platform)
{
var syntaxTree = CSharpSyntaxTree.ParseText(script);
UpdateLog("Script parsed.");
ReferenceWalker walker = new ReferenceWalker();
walker.Visit(syntaxTree.GetRoot());

string assemblyName = $"assemblyName_{DateTime.Now.Ticks}";

CSharpCompilation compilation = CSharpCompilation
.Create(assemblyName)
.WithOptions(CreateCompilationOptions(mode, platform))
.AddSyntaxTrees(new[] { syntaxTree })
.AddReferences(GetMetadataReferences(walker.References, platform));

return new DiagnosticAssembly(this, assemblyName, compilation); ;
}

private MetadataReference[] GetMetadataReferences(IEnumerable<string> referencesNames, DiagnosticAssembyPlatform platform)
{
List<MetadataReference> references = new List<MetadataReference>();
references.Add(MetadataReference.CreateFromFile(typeof(object).Assembly.Location));
foreach (var referenceName in referencesNames)
{
var assemblyPath = assemblyRepository.GetAssemblyPathBy(referenceName, platform);
if (!string.IsNullOrEmpty(assemblyPath))
{
references.Add(MetadataReference.CreateFromFile(assemblyPath));
}
}
return references.ToArray();
}

private CSharpCompilationOptions CreateCompilationOptions(DiagnosticAssemblyMode mode, DiagnosticAssembyPlatform platform)
{
OptimizationLevel compilationLevel = mode == DiagnosticAssemblyMode.Release
? OptimizationLevel.Release
: OptimizationLevel.Debug;
? OptimizationLevel.Release
: OptimizationLevel.Debug;

Platform compilationPlatform = platform == DiagnosticAssembyPlatform.x64 ? Platform.X64 : Platform.X86;
CSharpCompilation compilation = CSharpCompilation.Create(
assemblyName,
new[] { syntaxTree },
new[] { MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
MetadataReference.CreateFromFile(typeof(Vector).Assembly.Location) },
new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary,
optimizationLevel: compilationLevel,
allowUnsafe: true,
platform: compilationPlatform));

var result = new DiagnosticAssembly(this, assemblyName, compilation);
return result;
return new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary,
optimizationLevel: compilationLevel,
allowUnsafe: true,
platform: compilationPlatform);
}

public void UpdateLog(string message)
Expand Down
21 changes: 21 additions & 0 deletions src/Tune.Core/Extensions/DiagnosticAssembyPlatformExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System;

namespace Tune.Core.Extensions
{
public static class DiagnosticAssembyPlatformExtension
{
public static string ToPlatformString(this DiagnosticAssembyPlatform platform)
{
switch (platform)
{
case DiagnosticAssembyPlatform.x86:
return "32";
case DiagnosticAssembyPlatform.x64:
return "64";
default:
throw new ArgumentOutOfRangeException("Invalid platform type");
}
}
}

}
50 changes: 50 additions & 0 deletions src/Tune.Core/Paths/AssemblyPathsRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Tune.Core.Extensions;

namespace Tune.Core.Paths
{
public interface IAssemblyPathsRepository
{
string GetAssemblyPathBy(string name, DiagnosticAssembyPlatform platform);
}

internal class AssemblyPathsRepository : IAssemblyPathsRepository
{
private bool _initialized = false;
private List<string> _cachedAssemblies = new List<string>();
private Dictionary<string, string> _cachedQueries = new Dictionary<string, string>();

private void InitializeCache()
{
string gacPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "assembly");
DirectoryInfo assemblyDirectory = new DirectoryInfo(gacPath);
List<DirectoryInfo> directoriesToTraverse = new List<DirectoryInfo>();
foreach (var dir in assemblyDirectory.GetDirectories())
{
foreach (var file in dir.GetFiles("*.dll", SearchOption.AllDirectories))
{
_cachedAssemblies.Add(file.FullName);
}
}
_initialized = true;
}
public string GetAssemblyPathBy(string name, DiagnosticAssembyPlatform platform)
{
if (!_initialized)
{
InitializeCache();
}
var cacheKey = name + platform.ToPlatformString();
if (_cachedQueries.TryGetValue(cacheKey, out string result))
{
return result;
}
var assemblyPath = _cachedAssemblies.LastOrDefault(assembly => assembly.Contains(name) && assembly.Contains("_" + platform.ToPlatformString()));
_cachedQueries.Add(cacheKey, assemblyPath);
return assemblyPath;
}
}
}
Loading

0 comments on commit c287f18

Please sign in to comment.