-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
Program.cs
83 lines (68 loc) · 3.22 KB
/
Program.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Runtime.Loader;
using Microsoft.CodeAnalysis;
namespace Microsoft.NET.Sdk.Razor.Tool
{
internal static class Program
{
public static int Main(string[] args)
{
// To minimize the size of the SDK, we resolve all Rosyln-related assemblies
// from the `Roslyn/bincore` location in the SDK. The `RegisterAssemblyResolutionEvents`
// method registers the event that will handle loading the assemblies from the correct
// path. Note: since assembly resolution starts immediately when the `Main` method is
// invoked, so we register the event listener here to ensure they are registered before
// we `Main` is invoked.
RegisterAssemblyResolutionEvents();
return RunApplication(args);
}
private static int RunApplication(string[] args)
{
DebugMode.HandleDebugSwitch(ref args);
var cancel = new CancellationTokenSource();
Console.CancelKeyPress += (sender, e) => { cancel.Cancel(); };
var outputWriter = new StringWriter();
var errorWriter = new StringWriter();
// Prevent shadow copying.
var loader = new DefaultExtensionAssemblyLoader(baseDirectory: null);
var checker = new DefaultExtensionDependencyChecker(loader, outputWriter, errorWriter);
var application = new Application(
cancel.Token,
loader,
checker,
(path, properties) => MetadataReference.CreateFromFile(path, properties),
outputWriter,
errorWriter);
var result = application.Execute(args);
var output = outputWriter.ToString();
var error = errorWriter.ToString();
outputWriter.Dispose();
errorWriter.Dispose();
Console.Write(output);
Console.Error.Write(error);
// This will no-op if server logging is not enabled.
ServerLogger.Log(output);
ServerLogger.Log(error);
return result;
}
private static void RegisterAssemblyResolutionEvents()
{
var roslynPath = Path.Combine(AppContext.BaseDirectory, "..", "..", "..", "Roslyn", "bincore");
AssemblyLoadContext.Default.Resolving += (context, assembly) =>
{
if (assembly.Name is "Microsoft.CodeAnalysis" or "Microsoft.CodeAnalysis.CSharp")
{
var loadedAssembly = context.LoadFromAssemblyPath(Path.Combine(roslynPath, assembly.Name + ".dll"));
// Avoid scenarioes where the assembly in rosylnPath is older than what we expect
if (loadedAssembly.GetName().Version < assembly.Version)
{
throw new Exception($"Found a version of {assembly.Name} that was lower than the target version of {assembly.Version}");
}
return loadedAssembly;
}
return null;
};
}
}
}