Skip to content

Commit ecc1b2f

Browse files
committed
ScriptManager migration to the CodeAnalysis call. LoadFolder() is commented out yet.
1 parent 30f7ec8 commit ecc1b2f

File tree

3 files changed

+91
-23
lines changed

3 files changed

+91
-23
lines changed

Source/Orts.Simulation/Common/Scripting/ScriptManager.cs

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,18 @@
1515
// You should have received a copy of the GNU General Public License
1616
// along with Open Rails. If not, see <http://www.gnu.org/licenses/>.
1717

18-
using Microsoft.CodeDom.Providers.DotNetCompilerPlatform;
1918
using Orts.Simulation;
2019
using ORTS.Common;
2120
using System;
22-
using System.CodeDom.Compiler;
2321
using System.Collections.Generic;
2422
using System.Diagnostics;
2523
using System.IO;
24+
using System.Linq;
2625
using System.Reflection;
2726
using System.Text;
2827
using System.Threading;
28+
using Microsoft.CodeAnalysis;
29+
using Microsoft.CodeAnalysis.CSharp;
2930

3031
namespace Orts.Common.Scripting
3132
{
@@ -34,22 +35,17 @@ public class ScriptManager
3435
{
3536
readonly Simulator Simulator;
3637
readonly IDictionary<string, Assembly> Scripts = new Dictionary<string, Assembly>();
37-
static readonly ProviderOptions ProviderOptions = new ProviderOptions(Path.Combine(new Uri(Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase)).LocalPath, "roslyn", "csc.exe"), 10);
38-
static readonly CSharpCodeProvider Compiler = new CSharpCodeProvider(ProviderOptions);
39-
40-
static CompilerParameters GetCompilerParameters()
38+
static readonly string[] ReferenceAssemblies = new[]
4139
{
42-
var cp = new CompilerParameters()
43-
{
44-
GenerateInMemory = true,
45-
IncludeDebugInformation = Debugger.IsAttached,
46-
};
47-
cp.ReferencedAssemblies.Add("System.dll");
48-
cp.ReferencedAssemblies.Add("System.Core.dll");
49-
cp.ReferencedAssemblies.Add("ORTS.Common.dll");
50-
cp.ReferencedAssemblies.Add("Orts.Simulation.dll");
51-
return cp;
52-
}
40+
typeof(System.Object).GetTypeInfo().Assembly.Location,
41+
typeof(System.Diagnostics.Debug).GetTypeInfo().Assembly.Location,
42+
typeof(ORTS.Common.ElapsedTime).GetTypeInfo().Assembly.Location,
43+
typeof(ORTS.Scripting.Api.Timer).GetTypeInfo().Assembly.Location,
44+
};
45+
static MetadataReference[] References = ReferenceAssemblies.Select(r => MetadataReference.CreateFromFile(r)).ToArray();
46+
static CSharpCompilationOptions CompilationOptions = new CSharpCompilationOptions(
47+
OutputKind.DynamicallyLinkedLibrary,
48+
optimizationLevel: Debugger.IsAttached ? OptimizationLevel.Debug : OptimizationLevel.Release);
5349

5450
[CallOnThread("Loader")]
5551
internal ScriptManager(Simulator simulator)
@@ -86,22 +82,40 @@ private static Assembly CompileScript(string path)
8682
{
8783
try
8884
{
89-
var compilerResults = Compiler.CompileAssemblyFromFile(GetCompilerParameters(), path);
90-
if (!compilerResults.Errors.HasErrors)
85+
var scriptName = Path.GetFileName(path);
86+
var scriptCode = File.ReadAllText(path);
87+
var syntaxTree = CSharpSyntaxTree.ParseText(scriptCode);
88+
var compilation = CSharpCompilation.Create(
89+
scriptName,
90+
new[] { syntaxTree },
91+
References,
92+
CompilationOptions);
93+
var ms = new MemoryStream();
94+
var result = compilation.Emit(ms);
95+
if (result.Success)
9196
{
92-
var script = compilerResults.CompiledAssembly;
97+
ms.Seek(0, SeekOrigin.Begin);
98+
var script = Assembly.Load(ms.ToArray());
99+
// in netcore:
100+
//var script = AssemblyLoadContext.Default.LoadFromStream(ms);
93101
if (script == null)
94102
Trace.TraceWarning($"Script file {path} could not be loaded into the process.");
95103
return script;
96104
}
97105
else
98106
{
107+
var errors = result.Diagnostics.Where(diagnostic => diagnostic.IsWarningAsError || diagnostic.Severity == DiagnosticSeverity.Error);
108+
99109
var errorString = new StringBuilder();
100110
errorString.AppendFormat("Skipped script {0} with error:", path);
101111
errorString.Append(Environment.NewLine);
102-
foreach (CompilerError error in compilerResults.Errors)
112+
foreach (var error in errors)
103113
{
104-
errorString.AppendFormat(" {0}, line: {1}, column: {2}", error.ErrorText, error.Line /*- prefixLines*/, error.Column);
114+
var textSpan = error.Location.SourceSpan;
115+
var lineSpan = error.Location.SourceTree.GetLineSpan(textSpan);
116+
var line = lineSpan.StartLinePosition.Line + 1;
117+
var column = lineSpan.StartLinePosition.Character;
118+
errorString.AppendFormat("\t{0}: {1}, line: {2}, column: {3}", error.Id, error.GetMessage(), line, column);
105119
errorString.Append(Environment.NewLine);
106120
}
107121

@@ -126,6 +140,8 @@ private static Assembly CompileScript(string path)
126140

127141
public Assembly LoadFolder(string path)
128142
{
143+
return null;
144+
/*
129145
if (Thread.CurrentThread.Name != "Loader Process")
130146
Trace.TraceError("ScriptManager.Load incorrectly called by {0}; must be Loader Process or crashes will occur.", Thread.CurrentThread.Name);
131147
@@ -152,7 +168,7 @@ public Assembly LoadFolder(string path)
152168
errorString.Append(Environment.NewLine);
153169
foreach (CompilerError error in compilerResults.Errors)
154170
{
155-
errorString.AppendFormat(" {0}, file: {1}, line: {2}, column: {3}", error.ErrorText, error.FileName, error.Line /*- prefixLines*/, error.Column);
171+
errorString.AppendFormat(" {0}, file: {1}, line: {2}, column: {3}", error.ErrorText, error.FileName, error.Line, error.Column);
156172
errorString.Append(Environment.NewLine);
157173
}
158174
@@ -170,6 +186,7 @@ public Assembly LoadFolder(string path)
170186
Trace.WriteLine(new FileLoadException(path, error));
171187
return null;
172188
}
189+
*/
173190
}
174191

175192
/*

Source/Orts.Simulation/Orts.Simulation.csproj

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<Import Project="..\packages\Microsoft.CodeAnalysis.Analyzers.3.3.2\build\Microsoft.CodeAnalysis.Analyzers.props" Condition="Exists('..\packages\Microsoft.CodeAnalysis.Analyzers.3.3.2\build\Microsoft.CodeAnalysis.Analyzers.props')" />
34
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
45
<PropertyGroup>
56
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -43,6 +44,12 @@
4344
<Reference Include="GNU.Gettext">
4445
<HintPath>..\3rdPartyLibs\GNU.Gettext.dll</HintPath>
4546
</Reference>
47+
<Reference Include="Microsoft.CodeAnalysis, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
48+
<HintPath>..\packages\Microsoft.CodeAnalysis.Common.4.0.1\lib\netstandard2.0\Microsoft.CodeAnalysis.dll</HintPath>
49+
</Reference>
50+
<Reference Include="Microsoft.CodeAnalysis.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
51+
<HintPath>..\packages\Microsoft.CodeAnalysis.CSharp.4.0.1\lib\netstandard2.0\Microsoft.CodeAnalysis.CSharp.dll</HintPath>
52+
</Reference>
4653
<Reference Include="MonoGame.Framework">
4754
<HintPath>$(SolutionDir)\3rdPartyLibs\MonoGame\MonoGame.Framework.dll</HintPath>
4855
</Reference>
@@ -54,6 +61,31 @@
5461
<HintPath>..\3rdPartyLibs\Newtonsoft.Json.dll</HintPath>
5562
</Reference>
5663
<Reference Include="System" />
64+
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
65+
<HintPath>..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath>
66+
</Reference>
67+
<Reference Include="System.Collections.Immutable, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
68+
<HintPath>..\packages\System.Collections.Immutable.5.0.0\lib\net461\System.Collections.Immutable.dll</HintPath>
69+
</Reference>
70+
<Reference Include="System.Memory, Version=4.0.1.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
71+
<HintPath>..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll</HintPath>
72+
</Reference>
73+
<Reference Include="System.Numerics" />
74+
<Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
75+
<HintPath>..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
76+
</Reference>
77+
<Reference Include="System.Reflection.Metadata, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
78+
<HintPath>..\packages\System.Reflection.Metadata.5.0.0\lib\net461\System.Reflection.Metadata.dll</HintPath>
79+
</Reference>
80+
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
81+
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.5.0.0\lib\net45\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
82+
</Reference>
83+
<Reference Include="System.Text.Encoding.CodePages, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
84+
<HintPath>..\packages\System.Text.Encoding.CodePages.4.5.1\lib\net461\System.Text.Encoding.CodePages.dll</HintPath>
85+
</Reference>
86+
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
87+
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll</HintPath>
88+
</Reference>
5789
</ItemGroup>
5890
<ItemGroup>
5991
<Compile Include="Common\CommandLog.cs" />
@@ -198,14 +230,21 @@
198230
<ItemGroup>
199231
<None Include="packages.config" />
200232
</ItemGroup>
233+
<ItemGroup>
234+
<Analyzer Include="..\packages\Microsoft.CodeAnalysis.Analyzers.3.3.2\analyzers\dotnet\cs\Microsoft.CodeAnalysis.Analyzers.dll" />
235+
<Analyzer Include="..\packages\Microsoft.CodeAnalysis.Analyzers.3.3.2\analyzers\dotnet\cs\Microsoft.CodeAnalysis.CSharp.Analyzers.dll" />
236+
</ItemGroup>
201237
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
202238
<Import Project="..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.3.6.0\build\net472\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.targets" Condition="Exists('..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.3.6.0\build\net472\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.targets')" />
203239
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
204240
<PropertyGroup>
205241
<ErrorText>Ce projet fait référence à des packages NuGet qui sont manquants sur cet ordinateur. Utilisez l'option de restauration des packages NuGet pour les télécharger. Pour plus d'informations, consultez http://go.microsoft.com/fwlink/?LinkID=322105. Le fichier manquant est : {0}.</ErrorText>
206242
</PropertyGroup>
207243
<Error Condition="!Exists('..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.3.6.0\build\net472\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.3.6.0\build\net472\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.targets'))" />
244+
<Error Condition="!Exists('..\packages\Microsoft.CodeAnalysis.Analyzers.3.3.2\build\Microsoft.CodeAnalysis.Analyzers.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.CodeAnalysis.Analyzers.3.3.2\build\Microsoft.CodeAnalysis.Analyzers.props'))" />
245+
<Error Condition="!Exists('..\packages\Microsoft.CodeAnalysis.Analyzers.3.3.2\build\Microsoft.CodeAnalysis.Analyzers.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.CodeAnalysis.Analyzers.3.3.2\build\Microsoft.CodeAnalysis.Analyzers.targets'))" />
208246
</Target>
247+
<Import Project="..\packages\Microsoft.CodeAnalysis.Analyzers.3.3.2\build\Microsoft.CodeAnalysis.Analyzers.targets" Condition="Exists('..\packages\Microsoft.CodeAnalysis.Analyzers.3.3.2\build\Microsoft.CodeAnalysis.Analyzers.targets')" />
209248
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
210249
Other similar extension points exist, see Microsoft.Common.targets.
211250
<Target Name="BeforeBuild">
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,16 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<packages>
3+
<package id="Microsoft.CodeAnalysis.Analyzers" version="3.3.2" targetFramework="net472" developmentDependency="true" />
4+
<package id="Microsoft.CodeAnalysis.Common" version="4.0.1" targetFramework="net472" />
5+
<package id="Microsoft.CodeAnalysis.CSharp" version="4.0.1" targetFramework="net472" />
36
<package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="3.6.0" targetFramework="net472" />
7+
<package id="System.Buffers" version="4.5.1" targetFramework="net472" />
8+
<package id="System.Collections.Immutable" version="5.0.0" targetFramework="net472" />
9+
<package id="System.Memory" version="4.5.4" targetFramework="net472" />
10+
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net472" />
11+
<package id="System.Reflection.Metadata" version="5.0.0" targetFramework="net472" />
12+
<package id="System.Runtime.CompilerServices.Unsafe" version="5.0.0" targetFramework="net472" />
13+
<package id="System.Runtime.Loader" version="4.3.0" targetFramework="net472" />
14+
<package id="System.Text.Encoding.CodePages" version="4.5.1" targetFramework="net472" />
15+
<package id="System.Threading.Tasks.Extensions" version="4.5.4" targetFramework="net472" />
416
</packages>

0 commit comments

Comments
 (0)