Skip to content

Commit f8eeab5

Browse files
scorteanucosminMrBlue
authored andcommitted
Refactor and cleanup for new Oxide.Compiler
1 parent 6623d63 commit f8eeab5

29 files changed

Lines changed: 806 additions & 919 deletions

src/AssemblyResolver.cs

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,53 @@
11
extern alias References;
2-
2+
using System.IO;
33
using Oxide.Core;
44
using References::Mono.Cecil;
5-
using System.IO;
65

7-
namespace Oxide.CSharp
6+
namespace Oxide.CSharp;
7+
8+
internal class AssemblyResolver : IAssemblyResolver
89
{
9-
internal class AssemblyResolver : DefaultAssemblyResolver
10+
private readonly DefaultAssemblyResolver _resolver;
11+
private readonly AssemblyDefinition _mscorlib;
12+
13+
public AssemblyResolver()
1014
{
11-
internal readonly AssemblyDefinition mscorlib;
15+
_resolver = new DefaultAssemblyResolver();
16+
_resolver.AddSearchDirectory(Interface.Oxide.ExtensionDirectory);
17+
_mscorlib = AssemblyDefinition.ReadAssembly(Path.Combine(Interface.Oxide.ExtensionDirectory, "mscorlib.dll"));
18+
}
1219

13-
public AssemblyResolver() : base()
20+
public AssemblyDefinition Resolve(AssemblyNameReference assemblyNameReference)
21+
{
22+
if (assemblyNameReference.Name == "System.Private.CoreLib")
1423
{
15-
AddSearchDirectory(Interface.Oxide.ExtensionDirectory);
16-
mscorlib = AssemblyDefinition.ReadAssembly(Path.Combine(Interface.Oxide.ExtensionDirectory, "mscorlib.dll"));
24+
Interface.Oxide.RootLogger.WriteDebug(Core.Logging.LogType.Warning,
25+
new Logging.LogEvent(50, "Resolve"), "Resolver",
26+
"Redirecting reference to System.Private.CoreLib to mscorlib");
27+
28+
return _mscorlib;
1729
}
1830

19-
public override AssemblyDefinition Resolve(AssemblyNameReference name, ReaderParameters parameters)
31+
return _resolver.Resolve(assemblyNameReference);
32+
}
33+
34+
public AssemblyDefinition Resolve(AssemblyNameReference assemblyNameReference, ReaderParameters readerParameters)
35+
{
36+
if (assemblyNameReference.Name == "System.Private.CoreLib")
2037
{
21-
if (name.Name == "System.Private.CoreLib")
22-
{
23-
Interface.Oxide.RootLogger.WriteDebug(Core.Logging.LogType.Warning, new Logging.LogEvent(50, "Resolve"), "Resolver", "Redirecting reference to System.Private.CoreLib to mscorlib");
24-
return mscorlib;
25-
}
38+
Interface.Oxide.RootLogger.WriteDebug(Core.Logging.LogType.Warning,
39+
new Logging.LogEvent(50, "Resolve"), "Resolver",
40+
"Redirecting reference to System.Private.CoreLib to mscorlib");
2641

27-
return base.Resolve(name, parameters);
42+
return _mscorlib;
2843
}
44+
45+
return _resolver.Resolve(assemblyNameReference, readerParameters);
46+
}
47+
48+
public void Dispose()
49+
{
50+
_resolver.Dispose();
51+
_mscorlib.Dispose();
2952
}
3053
}

src/CSharpPluginLoader.cs

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
using System.Collections.Generic;
88
using System.Linq;
99
using System.Text.RegularExpressions;
10-
using Oxide.Core.Libraries;
10+
using Oxide.CSharp.Common;
1111

1212
namespace Oxide.Plugins
1313
{
@@ -35,19 +35,19 @@ public static CompilablePlugin GetCompilablePlugin(string directory, string name
3535

3636
public override string FileExtension => ".cs";
3737

38-
private List<CompilablePlugin> compilationQueue = new List<CompilablePlugin>();
39-
private CompilerService compiler;
38+
private readonly List<CompilablePlugin> _compilationQueue = new List<CompilablePlugin>();
39+
private readonly CompilerService _compiler;
4040

4141
public CSharpPluginLoader(CSharpExtension extension)
4242
{
4343
Instance = this;
4444
CSharpPluginLoader.extension = extension;
45-
compiler = new CompilerService(extension);
45+
_compiler = new CompilerService(extension);
4646
}
4747

4848
public void OnModLoaded()
4949
{
50-
compiler.Precheck();
50+
_compiler.Precheck();
5151

5252
// Include references to all loaded game extensions and any assemblies they reference
5353
foreach (Core.Extensions.Extension extension in Interface.Oxide.GetAllExtensions())
@@ -78,7 +78,7 @@ public void OnModLoaded()
7878

7979
public override IEnumerable<string> ScanDirectory(string directory)
8080
{
81-
bool installed = compiler.Installed;
81+
bool installed = _compiler.Installed;
8282
if (!installed)
8383
{
8484
yield break;
@@ -126,7 +126,7 @@ public override Plugin Load(string directory, string name)
126126
/// <param name="name"></param>
127127
public override void Reload(string directory, string name)
128128
{
129-
if (Regex.Match(directory, @"\\include\b", RegexOptions.IgnoreCase).Success)
129+
if (Constants.IncludeRegex.Match(directory).Success)
130130
{
131131
name = $"Oxide.{name}";
132132
foreach (CompilablePlugin plugin in plugins.Values)
@@ -202,12 +202,14 @@ public void Load(CompilablePlugin plugin)
202202
IEnumerable<string> loadingRequirements = plugin.Requires.Where(r => LoadingPlugins.Contains(r));
203203
if (loadingRequirements.Any())
204204
{
205-
Interface.Oxide.RootLogger.WriteDebug(LogType.Info, LogEvent.Compile, "CSharp", $"{plugin.Name} plugin is waiting for requirements to be loaded: {loadingRequirements.ToSentence()}");
205+
Interface.Oxide.RootLogger.WriteDebug(LogType.Info, LogEvent.Compile, "CSharp",
206+
$"{plugin.Name} plugin is waiting for requirements to be loaded: {loadingRequirements.ToSentence()}");
206207
}
207208
else
208209
{
209-
Interface.Oxide.LogError($"{plugin.Name} plugin requires missing dependencies: {missingRequirements.ToSentence()}");
210-
PluginErrors[plugin.Name] = $"Missing dependencies: {missingRequirements.ToSentence()}";
210+
string sentence = missingRequirements.ToSentence();
211+
Interface.Oxide.LogError($"{plugin.Name} plugin requires missing dependencies: {sentence}");
212+
PluginErrors[plugin.Name] = $"Missing dependencies: {sentence}";
211213
PluginLoadingCompleted(plugin);
212214
}
213215
}
@@ -239,15 +241,15 @@ public void CompilationRequested(CompilablePlugin plugin)
239241
Compilation.Current.Add(plugin);
240242
return;
241243
}
242-
if (compilationQueue.Count < 1)
244+
if (_compilationQueue.Count < 1)
243245
{
244246
Interface.Oxide.NextTick(() =>
245247
{
246-
CompileAssembly(compilationQueue.ToArray());
247-
compilationQueue.Clear();
248+
CompileAssembly(_compilationQueue.ToArray());
249+
_compilationQueue.Clear();
248250
});
249251
}
250-
compilationQueue.Add(plugin);
252+
_compilationQueue.Add(plugin);
251253
}
252254

253255
public void PluginLoadingStarted(CompilablePlugin plugin)
@@ -278,7 +280,7 @@ private void PluginLoadingCompleted(CompilablePlugin plugin)
278280

279281
private void CompileAssembly(CompilablePlugin[] plugins)
280282
{
281-
compiler.Compile(plugins, compilation =>
283+
_compiler.Compile(plugins, compilation =>
282284
{
283285
if (compilation.compiledAssembly == null)
284286
{
@@ -316,6 +318,6 @@ private void CompileAssembly(CompilablePlugin[] plugins)
316318
});
317319
}
318320

319-
public void OnShutdown() => compiler.Stop(true, "framework shutting down");
321+
public void OnShutdown() => _compiler.Stop(true, "framework shutting down");
320322
}
321323
}

src/Common/Constants.cs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
using System.Text.RegularExpressions;
2+
using Oxide.CompilerServices;
3+
4+
namespace Oxide.CSharp.Common
5+
{
6+
internal static class Constants
7+
{
8+
//TODO: Move to Oxide.Common & optimize this is a temporary solution
9+
internal static readonly ISerializer Serializer = new Serializer();
10+
11+
internal const string CompilerDownloadUrl = "https://downloads.oxidemod.com/artifacts/Oxide.Compiler/{0}/";
12+
internal const string CompilerBasicArguments = "-unsafe true --setting:Force true -ms true";
13+
14+
internal static readonly Regex FileErrorRegex = new Regex(@"^\[(?'Severity'\S+)\]\[(?'Code'\S+)\]\[(?'File'\S+)\] (?'Message'.+)$",
15+
RegexOptions.Compiled);
16+
17+
internal static readonly Regex BlankLineRegex = new Regex(@"^\s*\{?\s*$",
18+
RegexOptions.Compiled | RegexOptions.IgnoreCase);
19+
20+
internal static readonly Regex CustomAttributeRegex =
21+
new Regex(@"^\s*\[", RegexOptions.Compiled | RegexOptions.IgnoreCase);
22+
23+
internal static readonly Regex MainPluginClassNameRegex =
24+
new Regex(@"^\s*(?:public|private|protected|internal)?\s*class\s+(\S+)\s+\:\s+\S+Plugin\s*$",
25+
RegexOptions.Compiled | RegexOptions.IgnoreCase);
26+
27+
internal static readonly Regex RequiresTextRegex = new Regex(@"^//\s*Requires:\s*(\S+?)(\.cs)?\s*$",
28+
RegexOptions.Compiled | RegexOptions.IgnoreCase);
29+
30+
internal static readonly Regex ReferenceTextRegex = new Regex(@"^//\s*Reference:\s*(\S+)\s*$",
31+
RegexOptions.Compiled | RegexOptions.IgnoreCase);
32+
33+
internal static readonly Regex ImplicitReferenceTextRegex =
34+
new Regex(@"^\s*using\s+(Oxide\.(?:Core|Ext|Game)\.(?:[^\.]+))[^;]*;.*$",
35+
RegexOptions.Compiled | RegexOptions.IgnoreCase);
36+
37+
internal static readonly Regex PluginNameRegex = new Regex(@"Oxide\\.[\\w]+\\.([\\w]+)",
38+
RegexOptions.Compiled);
39+
40+
internal static readonly Regex NamespaceRegex = new Regex(@"^\s*namespace Oxide\.Plugins\s*(\{\s*)?$",
41+
RegexOptions.Compiled | RegexOptions.IgnoreCase);
42+
43+
internal static readonly Regex PluginReferenceRegex = new Regex(@"^(Oxide\.(?:Ext|Game)\.(.+))$",
44+
RegexOptions.Compiled | RegexOptions.IgnoreCase);
45+
46+
internal static readonly Regex IncludeRegex = new Regex(@"\\include\b", RegexOptions.Compiled | RegexOptions.IgnoreCase);
47+
48+
internal static readonly Regex SymbolEscapeRegex = new Regex(@"[^\w\d]", RegexOptions.Compiled);
49+
}
50+
}

0 commit comments

Comments
 (0)