Skip to content

Commit 98515af

Browse files
committed
refactor: refactor
1 parent f3970cf commit 98515af

File tree

5 files changed

+124
-76
lines changed

5 files changed

+124
-76
lines changed

Editor/CscSettingsProvider.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,14 @@ private static SettingsProvider CreateSettingsProvider()
3131
var sp = analyzerPackages.GetArrayElementAtIndex(index);
3232
EditorGUI.PropertyField(rect, sp, GUIContent.none);
3333
};
34+
s_RoAnalyzerPackages.onChangedCallback = list =>
35+
{
36+
for (var i = 0; i < analyzerPackages.arraySize; i++)
37+
{
38+
var sp = analyzerPackages.GetArrayElementAtIndex(i);
39+
sp.FindPropertyRelative("m_Category").intValue = (int)NugetPackage.CategoryType.Analyzer;
40+
}
41+
};
3442

3543
var includedAssemblies = s_AnalyzerFilter.FindPropertyRelative("m_IncludedAssemblies");
3644
s_RoIncludedAssemblies = new ReorderableList(serializedObject, includedAssemblies);

Plugins/CSharpCompilerSettings/Core.cs

Lines changed: 81 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System;
22
using System.Collections;
3-
using System.Collections.Generic;
43
using System.Diagnostics;
54
using System.IO;
65
using System.Linq;
@@ -16,11 +15,9 @@ namespace Coffee.CSharpCompilerSettings
1615
[InitializeOnLoad]
1716
internal static class Core
1817
{
19-
private static readonly Dictionary<string, bool> s_EnableAsmdefs = new Dictionary<string, bool>();
20-
private static readonly Dictionary<string, string> s_AssemblyNames = new Dictionary<string, string>();
21-
private static readonly bool IsGlobal;
18+
public static bool IsGlobal { get; private set; }
2219

23-
private static void DirtyScriptsIfNeeded()
20+
public static void DirtyScriptsIfNeeded()
2421
{
2522
var assemblyName = GetAssemblyName(FindAsmdef());
2623
if (!IsGlobal && string.IsNullOrEmpty(assemblyName)) return;
@@ -36,14 +33,8 @@ public static string GetAssemblyName(string asmdefPath)
3633
{
3734
if (string.IsNullOrEmpty(asmdefPath)) return null;
3835

39-
string assemblyName;
40-
if (s_AssemblyNames.TryGetValue(asmdefPath, out assemblyName)) return assemblyName;
41-
4236
var m = Regex.Match(File.ReadAllText(asmdefPath), "\"name\":\\s*\"([^\"]*)\"");
43-
assemblyName = m.Success ? m.Groups[1].Value : "";
44-
s_AssemblyNames[asmdefPath] = assemblyName;
45-
46-
return assemblyName;
37+
return m.Success ? m.Groups[1].Value : "";
4738
}
4839

4940
public static string GetPortableDllPath(string asmdefPath)
@@ -54,7 +45,7 @@ public static string GetPortableDllPath(string asmdefPath)
5445
.FirstOrDefault(x => Regex.IsMatch(x, "CSharpCompilerSettings_[0-9a-zA-Z]{32}.dll"));
5546
}
5647

57-
private static bool IsInSameDirectory(string path)
48+
public static bool IsInSameDirectory(string path)
5849
{
5950
if (string.IsNullOrEmpty(path)) return false;
6051

@@ -63,7 +54,7 @@ private static bool IsInSameDirectory(string path)
6354
return dir == coreAssemblyLocationDir;
6455
}
6556

66-
private static string FindAsmdef(string path = null)
57+
public static string FindAsmdef(string path = null)
6758
{
6859
if (string.IsNullOrEmpty(path))
6960
{
@@ -80,66 +71,31 @@ private static string FindAsmdef(string path = null)
8071
return asmdefPath.Replace('\\', '/').Replace(Environment.CurrentDirectory.Replace('\\', '/') + "/", "");
8172
}
8273

83-
private static CscSettingsAsset GetSettings()
74+
public static CscSettingsAsset GetSettings()
8475
{
8576
return IsGlobal
8677
? CscSettingsAsset.instance
8778
: CscSettingsAsset.GetAtPath(FindAsmdef()) ?? ScriptableObject.CreateInstance<CscSettingsAsset>();
8879
}
8980

90-
private static void ChangeCompilerProcess(object compiler, object scriptAssembly, CscSettingsAsset setting)
81+
public static string ModifyResponseFile(CscSettingsAsset setting, string assemblyName, string asmdefPath, string text)
9182
{
92-
var tProgram = Type.GetType("UnityEditor.Utils.Program, UnityEditor");
93-
var tScriptCompilerBase = Type.GetType("UnityEditor.Scripting.Compilers.ScriptCompilerBase, UnityEditor");
94-
var fiProcess = tScriptCompilerBase.GetField("process", BindingFlags.NonPublic | BindingFlags.Instance);
95-
var psi = compiler.Get("process", fiProcess).Call("GetProcessStartInfo") as ProcessStartInfo;
96-
var oldCommand = (psi.FileName + " " + psi.Arguments).Replace('\\', '/');
97-
var command = oldCommand.Replace(EditorApplication.applicationContentsPath.Replace('\\', '/'), "@APP_CONTENTS@");
98-
var isDefaultCsc = Regex.IsMatch(command, "@APP_CONTENTS@/[^ ]*(mcs|csc)");
99-
var assemblyName = Path.GetFileNameWithoutExtension(scriptAssembly.Get("Filename") as string);
100-
var asmdefDir = scriptAssembly.Get("OriginPath") as string;
101-
var asmdefPath = string.IsNullOrEmpty(asmdefDir) ? "" : FindAsmdef(asmdefDir);
102-
103-
// csc is not Unity default. It is already modified.
104-
if (!isDefaultCsc)
105-
{
106-
Logger.LogWarning(" <color=#bbbb44><Skipped> current csc is not Unity default. It is already modified.</color>");
107-
return;
108-
}
109-
110-
// Kill current process.
111-
compiler.Call("Dispose");
112-
113-
// Response file.
114-
var responseFile = Regex.Replace(psi.Arguments, "^.*@(.+)$", "$1");
115-
var text = File.ReadAllText(responseFile);
83+
var asmdefDir = string.IsNullOrEmpty(asmdefPath) ? null : Path.GetDirectoryName(asmdefPath);
11684
text = Regex.Replace(text, "[\r\n]+", "\n");
11785
text = Regex.Replace(text, "^-", "/");
11886
text = Regex.Replace(text, "\n/debug\n", "\n/debug:portable\n");
87+
text = Regex.Replace(text, "\n/nullable.*", "");
11988
text += "\n/preferreduilang:en-US";
12089

12190
// Compiler
12291
if (!setting.UseDefaultCompiler)
12392
{
124-
var compilerInfo = CompilerInfo.GetInstalledInfo(setting.CompilerPackage.PackageId);
125-
126-
// csc is not installed. Restart current process.
127-
if (!compilerInfo.IsValid)
128-
{
129-
Logger.LogWarning(" <color=#bbbb44><Skipped> C# compiler '{0}' is not installed. Restart compiler process: {1}</color>", compilerInfo.Path, oldCommand);
130-
131-
var currentProgram = tProgram.New(psi);
132-
currentProgram.Call("Start");
133-
compiler.Set("process", currentProgram, fiProcess);
134-
return;
135-
}
136-
137-
// Change exe file path.
138-
compilerInfo.Setup(psi, responseFile);
93+
// Change language version.
13994
text = Regex.Replace(text, "\n/langversion:[^\n]+\n", "\n/langversion:" + setting.LanguageVersion + "\n");
14095

14196
// Nullable.
142-
text += "\n/nullable:" + setting.Nullable.ToString().ToLower();
97+
if (setting.IsSupportNullable)
98+
text += "\n/nullable:" + setting.Nullable.ToString().ToLower();
14399
}
144100

145101
// Modify scripting define symbols.
@@ -177,18 +133,71 @@ private static void ChangeCompilerProcess(object compiler, object scriptAssembly
177133
text += string.Format("\n/ruleset:\"{0}\"", ruleset);
178134

179135
// Editor Config.
180-
var configs = new[]
181-
{
182-
".editorconfig",
183-
Utils.PathCombine(asmdefDir ?? "Assets", ".editorconfig")
184-
}
185-
.Where(File.Exists);
186-
foreach (var config in configs)
187-
text += string.Format("\n/analyzerconfig:\"{0}\"", config);
136+
// var configs = new[]
137+
// {
138+
// ".editorconfig",
139+
// Utils.PathCombine(asmdefDir ?? "Assets", ".editorconfig")
140+
// }
141+
// .Where(File.Exists);
142+
// foreach (var config in configs)
143+
// text += string.Format("\n/analyzerconfig:\"{0}\"", config);
188144
}
189145

190146
// Replace NewLine and save.
191147
text = Regex.Replace(text, "\n", Environment.NewLine);
148+
149+
return text;
150+
}
151+
152+
private static void ChangeCompilerProcess(object compiler, object scriptAssembly, CscSettingsAsset setting)
153+
{
154+
var tProgram = Type.GetType("UnityEditor.Utils.Program, UnityEditor");
155+
var tScriptCompilerBase = Type.GetType("UnityEditor.Scripting.Compilers.ScriptCompilerBase, UnityEditor");
156+
var fiProcess = tScriptCompilerBase.GetField("process", BindingFlags.NonPublic | BindingFlags.Instance);
157+
var psi = compiler.Get("process", fiProcess).Call("GetProcessStartInfo") as ProcessStartInfo;
158+
var oldCommand = (psi.FileName + " " + psi.Arguments).Replace('\\', '/');
159+
var command = oldCommand.Replace(EditorApplication.applicationContentsPath.Replace('\\', '/'), "@APP_CONTENTS@");
160+
var isDefaultCsc = Regex.IsMatch(command, "@APP_CONTENTS@/[^ ]*(mcs|csc)");
161+
var assemblyName = Path.GetFileNameWithoutExtension(scriptAssembly.Get("Filename") as string);
162+
var asmdefDir = scriptAssembly.Get("OriginPath") as string;
163+
var asmdefPath = string.IsNullOrEmpty(asmdefDir) ? "" : FindAsmdef(asmdefDir);
164+
165+
// csc is not Unity default. It is already modified.
166+
if (!isDefaultCsc)
167+
{
168+
Logger.LogWarning(" <color=#bbbb44><Skipped> current csc is not Unity default. It is already modified.</color>");
169+
return;
170+
}
171+
172+
// Kill current process.
173+
compiler.Call("Dispose");
174+
175+
// Response file.
176+
var responseFile = Regex.Replace(psi.Arguments, "^.*@(.+)$", "$1");
177+
178+
// Compiler
179+
if (!setting.UseDefaultCompiler)
180+
{
181+
var compilerInfo = CompilerInfo.GetInstalledInfo(setting.CompilerPackage.PackageId);
182+
183+
// csc is not installed. Restart current process.
184+
if (!compilerInfo.IsValid)
185+
{
186+
Logger.LogWarning(" <color=#bbbb44><Skipped> C# compiler '{0}' is not installed. Restart compiler process: {1}</color>", compilerInfo.Path, oldCommand);
187+
188+
var currentProgram = tProgram.New(psi);
189+
currentProgram.Call("Start");
190+
compiler.Set("process", currentProgram, fiProcess);
191+
return;
192+
}
193+
194+
// Change exe file path.
195+
compilerInfo.Setup(psi, responseFile);
196+
}
197+
198+
// Modify response file.
199+
var text = File.ReadAllText(responseFile);
200+
text = ModifyResponseFile(setting, assemblyName, asmdefPath, text);
192201
File.WriteAllText(responseFile, text);
193202

194203
// Logging
@@ -202,7 +211,7 @@ private static void ChangeCompilerProcess(object compiler, object scriptAssembly
202211
compiler.Set("process", program, fiProcess);
203212
}
204213

205-
private static void OnAssemblyCompilationStarted(string name)
214+
public static void OnAssemblyCompilationStarted(string name)
206215
{
207216
try
208217
{
@@ -254,7 +263,7 @@ private static void OnAssemblyCompilationStarted(string name)
254263
}
255264
}
256265

257-
static Core()
266+
public static void Initialize()
258267
{
259268
IsGlobal = new[]
260269
{
@@ -301,6 +310,7 @@ static Core()
301310

302311
// Register callback.
303312
Logger.LogDebug("<color=#22aa22><b>InitializeOnLoad:</b></color> start watching assembly compilation.");
313+
CompilationPipeline.assemblyCompilationStarted -= OnAssemblyCompilationStarted;
304314
CompilationPipeline.assemblyCompilationStarted += OnAssemblyCompilationStarted;
305315

306316
// Install custom csc before compilation.
@@ -319,5 +329,10 @@ static Core()
319329
if (2021 <= major || (major == 2020 && 2 <= minor))
320330
DirtyScriptsIfNeeded();
321331
}
332+
333+
static Core()
334+
{
335+
Initialize();
336+
}
322337
}
323338
}

Plugins/CSharpCompilerSettings/CscSettingsAsset.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,11 @@ public string AdditionalSymbols
192192
}
193193
}
194194

195+
public bool IsSupportNullable
196+
{
197+
get { return LVersion.CSharp8 < m_LanguageVersion; }
198+
}
199+
195200
public static CscSettingsAsset GetAtPath(string path)
196201
{
197202
try

Plugins/CSharpCompilerSettings/ReflectionExtensions.cs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,23 +28,27 @@ public static object New(this Type self, params object[] args)
2828
public static object Call(this object self, string methodName, params object[] args)
2929
{
3030
var types = args.Select(x => x.GetType()).ToArray();
31-
return self.Type().GetMethod(methodName, types)
31+
return self.Type().GetMethods(FLAGS)
32+
.Where(x => x.Name == methodName)
33+
.First(x => x.GetParameters().Select(y => y.ParameterType).SequenceEqual(types))
3234
.Invoke(self.Inst(), args);
3335
}
3436

3537
public static object Call(this object self, Type[] genericTypes, string methodName, params object[] args)
3638
{
37-
return self.Type().GetMethod(methodName, FLAGS)
39+
return self.Type().GetMethods(FLAGS)
40+
.First(x => x.IsGenericMethodDefinition && x.Name == methodName)
3841
.MakeGenericMethod(genericTypes)
3942
.Invoke(self.Inst(), args);
4043
}
4144

4245
public static object Get(this object self, string memberName, MemberInfo mi = null)
4346
{
4447
mi = mi ?? self.Type().GetMember(memberName, FLAGS)[0];
45-
return mi is PropertyInfo
46-
? (mi as PropertyInfo).GetValue(self.Inst(), new object[0])
47-
: (mi as FieldInfo).GetValue(self.Inst());
48+
if (mi is PropertyInfo)
49+
return (mi as PropertyInfo).GetValue(self.Inst(), new object[0]);
50+
else
51+
return (mi as FieldInfo).GetValue(self.Inst());
4852
}
4953

5054
public static void Set(this object self, string memberName, object value, MemberInfo mi = null)

Plugins/CSharpCompilerSettings/Utils.cs

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
using System.IO;
55
using System.Linq;
66
using System.Net;
7-
using System.Text.RegularExpressions;
87
using System.Threading;
98
using UnityEditor;
109
using UnityEngine;
@@ -13,6 +12,8 @@ namespace Coffee.CSharpCompilerSettings
1312
{
1413
internal static class Utils
1514
{
15+
public static bool DisableCompilation { get; set; }
16+
1617
/// <summary>
1718
/// Combine the paths.
1819
/// </summary>
@@ -45,7 +46,10 @@ public static void RequestCompilation(string assemblyName = null)
4546

4647
if (string.IsNullOrEmpty(assemblyName))
4748
{
48-
editorCompilation.Call("DirtyAllScripts");
49+
if (DisableCompilation)
50+
Logger.LogWarning("Skipped: Disable compilation");
51+
else
52+
editorCompilation.Call("DirtyAllScripts");
4953
return;
5054
}
5155

@@ -54,7 +58,10 @@ public static void RequestCompilation(string assemblyName = null)
5458
var path = allScripts.FirstOrDefault(x => x.Value == assemblyFilename).Key;
5559
if (string.IsNullOrEmpty(path)) return;
5660

57-
editorCompilation.Call("DirtyScript", path, assemblyFilename);
61+
if (DisableCompilation)
62+
Logger.LogWarning("Skipped: Disable compilation");
63+
else
64+
editorCompilation.Call("DirtyScript", path, assemblyFilename);
5865
}
5966

6067
/// <summary>
@@ -64,12 +71,21 @@ public static void RequestCompilation(string assemblyName = null)
6471
/// <returns>Installed directory path</returns>
6572
public static string InstallNugetPackage(string packageId)
6673
{
67-
Regex.IsMatch(packageId, @".*\.\d+\.\d+\.*");
68-
6974
var url = "https://globalcdn.nuget.org/packages/" + packageId.ToLower() + ".nupkg";
7075
return InstallPackage(packageId, url);
7176
}
7277

78+
/// <summary>
79+
/// Uninstall NuGet package.
80+
/// </summary>
81+
/// <param name="packageId">Package Id</param>
82+
public static void UninstallNugetPackage(string packageId)
83+
{
84+
var installPath = PathCombine("Library", "InstalledPackages", packageId);
85+
if (Directory.Exists(installPath))
86+
Directory.Delete(installPath, true);
87+
}
88+
7389
/// <summary>
7490
/// Install package from url.
7591
/// </summary>

0 commit comments

Comments
 (0)