Skip to content

Commit

Permalink
feat: add assembly filter to compile with custom compiler
Browse files Browse the repository at this point in the history
  • Loading branch information
mob-sakai committed Dec 16, 2020
1 parent f16985b commit acfa0e6
Show file tree
Hide file tree
Showing 7 changed files with 165 additions and 87 deletions.
63 changes: 63 additions & 0 deletions Editor/AssemblyFilterDrawer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;

namespace Coffee.CSharpCompilerSettings
{
[CustomPropertyDrawer(typeof(AssemblyFilter))]
internal class AssemblyFilterDrawer : PropertyDrawer
{
private bool _isInitialized;
private SerializedProperty _includedAssemblies;
private SerializedProperty _predefinedAssemblies;
private ReorderableList _roIncludedAssemblies;

private void Initialize(SerializedProperty property)
{
if (_isInitialized) return;
_isInitialized = true;

_predefinedAssemblies = property.FindPropertyRelative("m_PredefinedAssemblies");
_includedAssemblies = property.FindPropertyRelative("m_IncludedAssemblies");

_roIncludedAssemblies = new ReorderableList(property.serializedObject, _includedAssemblies, true, true, true, true);
_roIncludedAssemblies.drawHeaderCallback = rect =>
{
EditorGUI.PrefixLabel(rect, new GUIContent(_includedAssemblies.displayName));

rect.x += rect.width - 110;
rect.width = 110;
EditorGUI.LabelField(rect, "* Prefix '!' to exclude.", EditorStyles.miniLabel);
};
_roIncludedAssemblies.elementHeight = EditorGUIUtility.singleLineHeight + 2;
_roIncludedAssemblies.drawElementCallback = (rect, index, active, focused) =>
{
var sp = _includedAssemblies.GetArrayElementAtIndex(index);
rect.height = EditorGUIUtility.singleLineHeight;
EditorGUI.PropertyField(rect, sp, GUIContent.none);
};
}

public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
Initialize(property);
return _includedAssemblies.arraySize * (EditorGUIUtility.singleLineHeight + 2) + 47;
}

public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
EditorGUI.BeginProperty(position, label, property);
var p = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label);

_roIncludedAssemblies.DoList(new Rect(p.x - 3, p.y, p.width + 6, p.height));

EditorGUI.PropertyField(new Rect(p.x, p.y + p.height - 16, p.width, 16), _predefinedAssemblies);

EditorGUI.EndProperty();
}
}
}
11 changes: 11 additions & 0 deletions Editor/AssemblyFilterDrawer.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 15 additions & 13 deletions Editor/CSharpProjectModifier.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,29 +20,31 @@ private static string OnGeneratedCSProject(string path, string content)

// Modify define symbols.
var defines = Regex.Match(content, "<DefineConstants>(.*)</DefineConstants>").Groups[1].Value.Split(';', ',');
defines = Utils.ModifySymbols(defines, setting.AdditionalSymbols);
defines = Utils.ModifySymbols(defines, setting.GetSymbolModifier(asmdefPath));
var defineText = string.Join(";", defines);
content = Regex.Replace(content, "<DefineConstants>(.*)</DefineConstants>", string.Format("<DefineConstants>{0}</DefineConstants>", defineText), RegexOptions.Multiline);

if (!setting.UseDefaultCompiler)
if (setting.ShouldToUseCustomCompiler(asmdefPath))
{
// Language version.
content = Regex.Replace(content, "<LangVersion>.*</LangVersion>", "<LangVersion>" + setting.LanguageVersion + "</LangVersion>", RegexOptions.Multiline);
}

// Nullable.
var value = setting.Nullable.ToString().ToLower();
if (Regex.IsMatch(content, "<Nullable>.*</Nullable>"))
{
content = Regex.Replace(content, "<Nullable>.*</Nullable>", "<Nullable>" + value + "</Nullable>");
}
else
{
content = Regex.Replace(content, "(\\s+)(<LangVersion>.*</LangVersion>)([\r\n]+)", "$1$2$3$1<Nullable>" + value + "</Nullable>$3");
// Nullable.
if (!setting.IsSupportNullable)
{
var value = setting.Nullable.ToString().ToLower();
if (Regex.IsMatch(content, "<Nullable>.*</Nullable>"))
{
content = Regex.Replace(content, "<Nullable>.*</Nullable>", "<Nullable>" + value + "</Nullable>");
}
else
{
content = Regex.Replace(content, "(\\s+)(<LangVersion>.*</LangVersion>)([\r\n]+)", "$1$2$3$1<Nullable>" + value + "</Nullable>$3");
}
}
}

// Additional contents.
// content = Regex.Replace(content, "^</Project>", "<!-- C# Settings For Unity -->", RegexOptions.Singleline);
content = Regex.Replace(content, "[\r\n]+</Project>[\r\n]*", "\r\n<!-- C# Settings For Unity -->");
{
content += NewLine + " <ItemGroup>";
Expand Down
45 changes: 18 additions & 27 deletions Editor/CscSettingsProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,17 @@ internal class CscSettingsProvider
{
private static SerializedObject serializedObject;
private static SerializedProperty s_EnableLogging;
private static SerializedProperty s_CompilerFilter;
private static SerializedProperty s_AnalyzerFilter;
private static SerializedProperty s_PredefinedAssemblies;
private static ReorderableList s_RoAnalyzerPackages;
private static ReorderableList s_RoIncludedAssemblies;

[SettingsProvider]
private static SettingsProvider CreateSettingsProvider()
{
serializedObject = new SerializedObject(CscSettingsAsset.instance);
s_EnableLogging = serializedObject.FindProperty("m_EnableLogging");
s_CompilerFilter = serializedObject.FindProperty("m_CompilerFilter");
s_AnalyzerFilter = serializedObject.FindProperty("m_AnalyzerFilter");
s_PredefinedAssemblies = s_AnalyzerFilter.FindPropertyRelative("m_PredefinedAssemblies");

var analyzerPackages = serializedObject.FindProperty("m_AnalyzerPackages");
s_RoAnalyzerPackages = new ReorderableList(serializedObject, analyzerPackages);
Expand All @@ -36,28 +35,10 @@ private static SettingsProvider CreateSettingsProvider()
for (var i = 0; i < analyzerPackages.arraySize; i++)
{
var sp = analyzerPackages.GetArrayElementAtIndex(i);
sp.FindPropertyRelative("m_Category").intValue = (int)NugetPackage.CategoryType.Analyzer;
sp.FindPropertyRelative("m_Category").intValue = (int) NugetPackage.CategoryType.Analyzer;
}
};

var includedAssemblies = s_AnalyzerFilter.FindPropertyRelative("m_IncludedAssemblies");
s_RoIncludedAssemblies = new ReorderableList(serializedObject, includedAssemblies);
s_RoIncludedAssemblies.drawHeaderCallback = rect =>
{
EditorGUI.PrefixLabel(rect, new GUIContent(includedAssemblies.displayName));

rect.x += rect.width - 100;
rect.width = 100;
EditorGUI.LabelField(rect, "* Prefix '!' to exclude.", EditorStyles.miniLabel);
};
s_RoIncludedAssemblies.elementHeight = EditorGUIUtility.singleLineHeight + 2;
s_RoIncludedAssemblies.drawElementCallback = (rect, index, active, focused) =>
{
var sp = includedAssemblies.GetArrayElementAtIndex(index);
rect.height = EditorGUIUtility.singleLineHeight;
EditorGUI.PropertyField(rect, sp, GUIContent.none);
};

var keywords = SettingsProvider.GetSearchKeywordsFromSerializedObject(serializedObject);
return new SettingsProvider("Project/C# Compiler", SettingsScope.Project)
{
Expand All @@ -70,20 +51,30 @@ private static SettingsProvider CreateSettingsProvider()
private static void OnGUI(string searchContext)
{
EditorGUILayout.LabelField("Compiler", EditorStyles.boldLabel);
InspectorGUI.DrawCompilerPackage(serializedObject);
if (InspectorGUI.DrawCompilerPackage(serializedObject))
{
using (new GUILayout.HorizontalScope())
{
GUILayout.Space(4);
using (new GUILayout.VerticalScope())
{
GUILayout.Space(10);
EditorGUILayout.PropertyField(s_CompilerFilter, GUIContent.none, true);
}
}
}

EditorGUILayout.Space();

EditorGUILayout.LabelField("Analyzer", EditorStyles.boldLabel);
using (new GUILayout.HorizontalScope())
{
GUILayout.Space(20);
GUILayout.Space(4);
using (new GUILayout.VerticalScope())
{
NugetPackageCatalog.CurrentCategory = NugetPackage.CategoryType.Analyzer;
s_RoAnalyzerPackages.DoLayoutList();
s_RoIncludedAssemblies.DoLayoutList();
GUILayout.Space(-18);
EditorGUILayout.PropertyField(s_PredefinedAssemblies);
EditorGUILayout.PropertyField(s_AnalyzerFilter, GUIContent.none, true);
}
}

Expand Down
7 changes: 5 additions & 2 deletions Editor/InspectorGUI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -140,12 +140,13 @@ private static void OnPostHeaderGUI(Editor editor)
EditorGUILayout.EndVertical();
}

public static void DrawCompilerPackage(SerializedObject so)
public static bool DrawCompilerPackage(SerializedObject so)
{
var spCompilerType = so.FindProperty("m_CompilerType");
EditorGUILayout.PropertyField(spCompilerType);

if (spCompilerType.intValue == (int) CompilerType.CustomPackage)
bool isCustomPackage = spCompilerType.intValue == (int) CompilerType.CustomPackage;
if (isCustomPackage)
{
EditorGUI.indentLevel++;
NugetPackageCatalog.CurrentCategory = NugetPackage.CategoryType.Compiler;
Expand All @@ -154,6 +155,8 @@ public static void DrawCompilerPackage(SerializedObject so)
EditorGUILayout.PropertyField(so.FindProperty("m_Nullable"));
EditorGUI.indentLevel--;
}

return isCustomPackage;
}

public static void DrawControl(bool changed, Action onRevert = null, Action onApply = null, Action onReload = null, Action onPublish = null)
Expand Down
21 changes: 12 additions & 9 deletions Plugins/CSharpCompilerSettings/Core.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,35 +84,38 @@ public static string ModifyResponseFile(CscSettingsAsset setting, string assembl
text = Regex.Replace(text, "[\r\n]+", "\n");
text = Regex.Replace(text, "^-", "/");
text = Regex.Replace(text, "\n/debug\n", "\n/debug:portable\n");
text = Regex.Replace(text, "\n/nullable.*", "");
text += "\n/preferreduilang:en-US";

// Compiler
if (!setting.UseDefaultCompiler)
// Custom compiler.
if (setting.ShouldToUseCustomCompiler(asmdefPath))
{
// Change language version.
text = Regex.Replace(text, "\n/langversion:[^\n]+\n", "\n/langversion:" + setting.LanguageVersion + "\n");

// Nullable.
text = Regex.Replace(text, "\n/nullable.*", "");
if (setting.IsSupportNullable)
{
text += "\n/nullable:" + setting.Nullable.ToString().ToLower();
}
}

// Modify scripting define symbols.
if (!string.IsNullOrEmpty(setting.AdditionalSymbols))
var symbolModifier = setting.GetSymbolModifier(asmdefPath);
if (!string.IsNullOrEmpty(symbolModifier))
{
var defines = Regex.Matches(text, "^/define:(.*)$", RegexOptions.Multiline)
.Cast<Match>()
.Select(x => x.Groups[1].Value);
text = Regex.Replace(text, "[\r\n]+/define:[^\r\n]+", "");
var modifiedDefines = Utils.ModifySymbols(defines, setting.AdditionalSymbols);
var modifiedDefines = Utils.ModifySymbols(defines, symbolModifier);
foreach (var d in modifiedDefines)
text += "\n/define:" + d;
}

// Analyzer.
var globalSettings = CscSettingsAsset.instance;
if (globalSettings.ShouldToRecompileToAnalyze(asmdefPath))
if (globalSettings.ShouldToUseAnalyzer(asmdefPath))
{
// Analyzer dlls.
foreach (var package in globalSettings.AnalyzerPackages)
Expand Down Expand Up @@ -175,8 +178,8 @@ private static void ChangeCompilerProcess(object compiler, object scriptAssembly
// Response file.
var responseFile = Regex.Replace(psi.Arguments, "^.*@(.+)$", "$1");

// Compiler
if (!setting.UseDefaultCompiler)
// Change to custom compiler.
if (setting.ShouldToUseCustomCompiler(asmdefPath))
{
var compilerInfo = CompilerInfo.GetInstalledInfo(setting.CompilerPackage.PackageId);

Expand Down Expand Up @@ -247,7 +250,7 @@ public static void OnAssemblyCompilationStarted(string name)

var globalSettings = CscSettingsAsset.instance;
var settings = GetSettings();
if (!settings.ShouldToRecompile && !globalSettings.ShouldToRecompileToAnalyze(asmdefPath))
if (!globalSettings.ShouldToRecompile(asmdefPath))
{
Logger.LogWarning(" <color=#bbbb44><Skipped> Assembly <b>'{0}'</b> does not need to be recompiled.</color>", assemblyName);
return;
Expand Down
Loading

0 comments on commit acfa0e6

Please sign in to comment.