Skip to content

Commit

Permalink
Merge pull request #1 from Cysharp/hotfix/VsCodeRider
Browse files Browse the repository at this point in the history
If using Rider or VSCode, disable AddRoslynAnalyzerReferenceFeature
  • Loading branch information
mayuki authored May 10, 2021
2 parents e34c1a4 + 916d409 commit def1bb6
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 16 deletions.
1 change: 1 addition & 0 deletions README.ja.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ CsprojModifier は次の特徴を備えています:

- 生成された .csproj に追加のプロジェクトを `Import` 要素で追加する
- 生成された .csproj に Analzyer の参照を追加する
- 2020.2 以降で Rider または Visual Studio Code を利用している場合には無効

![](docs/images/Screen-01.png)

Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ CsprojModifier provides following features:

- Insert additional projects as `Import` elements into generated .csproj
- Add analyzer references to generated .csproj
- Disabled if you are using Rider or Visual Studio Code with Unity 2020.2 or later

![](docs/images/Screen-01.png)

Expand Down Expand Up @@ -64,6 +65,8 @@ For example, you can create the following file `YourAwesomeApp.DesignTime.props`
[BannedApiAnalyzer](https://github.com/dotnet/roslyn-analyzers/tree/main/src/Microsoft.CodeAnalysis.BannedApiAnalyzers) expects BannedSymbols.txt as `AdditionalFiles` to be included in the project, so adding it this way will work.

### Add analyzer references to generated .csproj
**NOTE**: Disabled this feature if you are using Rider or Visual Studio Code with Unity 2020.2 or later. Unity Editor has Roslyn Analyzer IDE support.

[Roslyn analyzers are supported in Unity 2020.2 or later](https://docs.unity3d.com/Manual/roslyn-analyzers.html). However, currently, Roslyn analyzers are not included in .csproj, and those are only used at compile time.

The extension will insert `Analzyer` element into .csproj when generating the project file. As a result, you can run Roslyn Analyzer when editing code in Visual Studio. (of course, you can use it before 2020.2!)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "CsprojtModifier.Editor",
"name": "CsprojModifier.Editor",
"references": [],
"includePlatforms": [],
"excludePlatforms": [],
Expand All @@ -8,6 +8,17 @@
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"versionDefines": [
{
"name": "com.unity.ide.rider",
"expression": "2.0.6",
"define": "HAS_ROSLYN_ANALZYER_SUPPORT_RIDER"
},
{
"name": "com.unity.ide.vscode",
"expression": "1.2.0",
"define": "HAS_ROSLYN_ANALZYER_SUPPORT_VSCODE"
}
],
"noEngineReferences": false
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public override void Initialize()
public override string OnGeneratedCSProject(string path, string content)
{
var settings = CsprojModifierSettings.Instance;
if (RoslynAnalyzerUnityEditorNativeSupport.HasRoslynAnalyzerIdeSupport) return content;
if (!settings.EnableAddAnalyzerReferences) return content;

var canApply = path.EndsWith("Assembly-CSharp.csproj") ||
Expand Down Expand Up @@ -90,14 +91,21 @@ private static IReadOnlyList<string> GetAnalyzers()

public override void OnGUI()
{
EditorGUILayout.LabelField("Analyzer", EditorStyles.boldLabel);
EditorGUILayout.LabelField("Roslyn Analyzer", EditorStyles.boldLabel);
DrawAnalyzerReferences();
}

private void DrawAnalyzerReferences()
{
var settings = CsprojModifierSettings.Instance;
settings.EnableAddAnalyzerReferences = EditorGUILayout.ToggleLeft("Add Analyzer references to .csproj", settings.EnableAddAnalyzerReferences);

if (RoslynAnalyzerUnityEditorNativeSupport.HasRoslynAnalyzerIdeSupport)
{
EditorGUILayout.HelpBox("The current code editor has Roslyn Analyzer IDE support. Roslyn Analyzers are enabled by Unity Editor.", MessageType.Info);
return;
}

settings.EnableAddAnalyzerReferences = EditorGUILayout.ToggleLeft("Add Roslyn Analyzer references to .csproj", settings.EnableAddAnalyzerReferences);
if (settings.EnableAddAnalyzerReferences)
{
using (new EditorGUILayout.VerticalScope(GUI.skin.box))
Expand All @@ -108,12 +116,32 @@ private void DrawAnalyzerReferences()
EditorGUILayout.LabelField(analyzer, EditorStyles.label);
}
}
EditorGUILayout.HelpBox("Analyzer must be tagged as 'RoslynAnalyzer'", MessageType.Info);
EditorGUILayout.HelpBox("Analyzer must be labeled as 'RoslynAnalyzer'", MessageType.Info);

EditorGUILayout.LabelField("The project to be added for analyzer references.");
EditorGUILayout.LabelField("The project to be added for Roslyn Analyzer references.");
_reorderableListAdditionalAddAnalyzerProjects.DoLayoutList();
}
}


private static class RoslynAnalyzerUnityEditorNativeSupport
{
public static bool HasRoslynAnalyzerIdeSupport
{
get
{

#if UNITY_2020_2_OR_NEWER && (HAS_ROSLYN_ANALZYER_SUPPORT_RIDER || HAS_ROSLYN_ANALZYER_SUPPORT_VSCODE)
// The editor extension for 'Rider' or 'Visual Studio Code' has the functionality to add Roslyn analyzer references.
var codeEditorType = Unity.CodeEditor.CodeEditor.CurrentEditor.GetType();
if (codeEditorType.Name == "VSCodeScriptEditor" || codeEditorType.Name == "RiderScriptEditor")
{
return true;
}
#endif
return false;
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Unity.CodeEditor;
using UnityEngine;

namespace CsprojModifier.Editor.Features
Expand All @@ -20,21 +21,29 @@ public void OnGUI()

if (GUILayout.Button("Regenerate project files"))
{
// SyncVS.Synchronizer.Sync(); (SyncVS is an internal class, so call it with Reflection)
if (CodeEditor.CurrentEditor.GetType().Name == "DefaultExternalCodeEditor")
{
// SyncVS.Synchronizer.Sync(); (SyncVS is an internal class, so call it with Reflection)

var syncVsType = Type.GetType("UnityEditor.SyncVS, UnityEditor");
ThrowIfNull(syncVsType, "Type 'UnityEditor.SyncVS' is not found on the editor.");
var syncVsType = Type.GetType("UnityEditor.SyncVS, UnityEditor");
ThrowIfNull(syncVsType, "Type 'UnityEditor.SyncVS' is not found on the editor.");

var slnSynchronizerType = Type.GetType("UnityEditor.VisualStudioIntegration.SolutionSynchronizer, UnityEditor");
ThrowIfNull(slnSynchronizerType, "Type 'UnityEditor.VisualStudioIntegration.SolutionSynchronizer' is not found on the editor.");
var slnSynchronizerType = Type.GetType("UnityEditor.VisualStudioIntegration.SolutionSynchronizer, UnityEditor");
ThrowIfNull(slnSynchronizerType, "Type 'UnityEditor.VisualStudioIntegration.SolutionSynchronizer' is not found on the editor.");

var solutionSynchronizerField = syncVsType.GetField("Synchronizer", BindingFlags.Static | BindingFlags.NonPublic);
ThrowIfNull(solutionSynchronizerField, "Field 'Synchronizer' is not found in 'SolutionSynchronizer'.");
var solutionSynchronizerField = syncVsType.GetField("Synchronizer", BindingFlags.Static | BindingFlags.NonPublic);
ThrowIfNull(solutionSynchronizerField, "Field 'Synchronizer' is not found in 'SolutionSynchronizer'.");

var syncMethod = slnSynchronizerType.GetMethod("Sync", BindingFlags.Instance | BindingFlags.Public);
ThrowIfNull(syncMethod, "Method 'Sync' is not found in 'Synchronizer'.");
var syncMethod = slnSynchronizerType.GetMethod("Sync", BindingFlags.Instance | BindingFlags.Public);
ThrowIfNull(syncMethod, "Method 'Sync' is not found in 'Synchronizer'.");

syncMethod.Invoke(solutionSynchronizerField.GetValue(null), Array.Empty<object>());
syncMethod.Invoke(solutionSynchronizerField.GetValue(null), Array.Empty<object>());
}
else
{
// HACK: Make it look like a dummy file has been added.
CodeEditor.CurrentEditor.SyncIfNeeded(new [] { "RegenerateProjectFeature.cs" }, Array.Empty<string>(), Array.Empty<string>(), Array.Empty<string>(), Array.Empty<string>());
}
}
}

Expand Down

0 comments on commit def1bb6

Please sign in to comment.