More workarounding for Rider Avalonia faking

This commit is contained in:
Pieter-Jan Briers
2021-04-19 01:47:33 +02:00
parent 0d37ff3f20
commit ffa908bf27
7 changed files with 33 additions and 7 deletions

View File

@@ -0,0 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
</Project>

2
Avalonia.Base/README.md Normal file
View File

@@ -0,0 +1,2 @@
See `Robust.Client/UserInterface/XAML/RiderNotes.md` for why this project exists.
We are not actually using Avalonia (yet).

View File

@@ -30,6 +30,7 @@
<ProjectReference Include="..\Robust.Shared.Scripting\Robust.Shared.Scripting.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Avalonia.Base\Avalonia.Base.csproj" />
<ProjectReference Include="..\Lidgren.Network\Lidgren.Network.csproj" />
<ProjectReference Include="..\OpenToolkit.GraphicsLibraryFramework\OpenToolkit.GraphicsLibraryFramework.csproj" />
<ProjectReference Include="..\Robust.LoaderApi\Robust.LoaderApi\Robust.LoaderApi.csproj" />

View File

@@ -8,19 +8,23 @@ XAML support in both Rider and VS is pretty hardcoded for all supported framewor
The primary XAML support in Rider appears to be in `lib/ReSharperHost/JetBrains.ReSharper.Psi.Xaml.dll`. I recommend you decompile it with DotPeek to a project for navigating around. You can then look around the decompiled code (it's not obfuscated at all) to figure out how Rider does all this stuff.
**JetBrains, if you're reading this, please don't sue me or take away our licenses pls I only reverse engineered your program to avoid wasting time on your issue tracker.**
## SDK Detection
Rider uses heuristics to determine which UI library you are using (WPF, Silverlight, Xamarin, Avalonia, ...). I would write "obviously, Rider needs to detect Avalonia to support Avalonia" but this actually didn't used to be the case until 2021.1 for half the features like XMLNS support.
However yes we live in a post-2021.1 society and Rider now needs to detect Avalonia to support Avalonia. The detection is that it looks for a project/assembly reference named `Avalonia.Base`. That's where that project in our tree comes from.
## Attributes
Attributes like `XmlnsAttributionAttribute` are hardcoded for full name with namespace. That's also where it stops, so we just define our own `Avalonia.Metadata.XmlnsDefinitionAttribute` and this fools Rider into recognizing it and working. Hooray!
Attributes like `XmlnsAttributionAttribute` are hardcoded for full name with namespace. So we just define our own `Avalonia.Metadata.XmlnsDefinitionAttribute` and this is enough to satisfy Rider.
## `http://schemas.microsoft.com/winfx/2006/xaml` Namespace
As far as I can tell, at least in Avalonia, the things in this namespace are not backed by any real .NET symbols and are just made up by Rider. This is a problem because it only does this making up if it detects that you're using Avalonia.
This is the namespace that contains important markup extensions like `{x:Type}`. These types however are not backed by a real type at runtime, normally. Rider automatically "understands" them if it detects the Avalonia SDK.
The heuristic for "are we using Avalonia" appears to be finding an assembly or project reference for `Avalonia.Base`. You can see this in `XamlModulePlatformCache.cs` in the decompiled ReSharper source code and also the `XamlPlatform` flags enum.
It does appear that XamlIL still needs them to exist though, so we manually define things like `StaticExtension` in this namespace to appease XamlIL. Well...
For the time being I decided to hold off on actually fully pretending we're Avalonia so did *not* commit to a reference to `Avalonia.Base` yet. Instead we just manually created stuff like a dummy `StaticExtension` class (with a constructor that always throws) and put it into the `http://schemas.microsoft.com/winfx/2006/xaml` namespace. This seems to satisfy Rider without interfering with the actual XamlIL compilation.
I can't find equivalent types for these in the Avalonia repo, so it stands to reason XamlIL should have a better way to recognize them. The thing is that originally I had these types here to fool Rider without tricking it with SDK detection, but that's anymore (because the SDK detection is now 100% required). However when I removed the types XamlIL/GenerateTypeNameReferences broke, so... Yeah I can't be bothered to investigate further it seems to work currently.
## Markup Extensions

View File

@@ -11,7 +11,7 @@ namespace Robust.Client.UserInterface.XAML.XNamespace
public StaticExtension(string _)
{
throw new InvalidOperationException(
"This type only exists to make Rider work and should never be instantiated.");
"This type only exists for compile-time XAML support and should never be instantiated.");
}
public static object ProvideValue()

View File

@@ -1,6 +1,7 @@
using System;
using JetBrains.Annotations;
/*
// ReSharper disable once CheckNamespace
namespace Robust.Client.UserInterface.XAML.XNamespace
{
@@ -11,7 +12,7 @@ namespace Robust.Client.UserInterface.XAML.XNamespace
public TypeExtension(string _)
{
throw new InvalidOperationException(
"This type only exists to make Rider work and should never be instantiated.");
"This type only exists for compile-time XAML support and should never be instantiated");
}
public static object ProvideValue()
@@ -20,3 +21,4 @@ namespace Robust.Client.UserInterface.XAML.XNamespace
}
}
}
*/

View File

@@ -47,6 +47,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XamlX.Runtime", "XamlX\src\
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Robust.Analyzers", "Robust.Analyzers\Robust.Analyzers.csproj", "{3173712A-9E75-4685-B657-9AF9B7D54EFB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Base", "Avalonia.Base\Avalonia.Base.csproj", "{C60905B4-072F-4376-BCEC-C91186644127}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -199,6 +201,14 @@ Global
{3173712A-9E75-4685-B657-9AF9B7D54EFB}.Release|Any CPU.Build.0 = Release|Any CPU
{3173712A-9E75-4685-B657-9AF9B7D54EFB}.Release|x64.ActiveCfg = Release|Any CPU
{3173712A-9E75-4685-B657-9AF9B7D54EFB}.Release|x64.Build.0 = Release|Any CPU
{C60905B4-072F-4376-BCEC-C91186644127}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C60905B4-072F-4376-BCEC-C91186644127}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C60905B4-072F-4376-BCEC-C91186644127}.Debug|x64.ActiveCfg = Debug|Any CPU
{C60905B4-072F-4376-BCEC-C91186644127}.Debug|x64.Build.0 = Debug|Any CPU
{C60905B4-072F-4376-BCEC-C91186644127}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C60905B4-072F-4376-BCEC-C91186644127}.Release|Any CPU.Build.0 = Release|Any CPU
{C60905B4-072F-4376-BCEC-C91186644127}.Release|x64.ActiveCfg = Release|Any CPU
{C60905B4-072F-4376-BCEC-C91186644127}.Release|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE