Skip to content

Use embed JSON parser instead of Regex while parsing Deps file #14287

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jan 21, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -66,5 +66,5 @@ public record RuntimeXamlDiagnostic(
int? LineNumber,
int? LinePosition)
{
public string? Document { get; init; }
public string? Document { get; set; }
}
45 changes: 38 additions & 7 deletions src/tools/Avalonia.Designer.HostApp/DesignXamlLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using Avalonia.Markup.Xaml;
using Avalonia.Markup.Xaml.XamlIl;
using TinyJson;

namespace Avalonia.Designer.HostApp;

Expand Down Expand Up @@ -41,7 +40,7 @@ private void PreloadDepsAssemblies(Assembly targetAssembly)
/*
We can't use any references in the Avalonia.Designer.HostApp. Including even json.
Ideally we would prefer Microsoft.Extensions.DependencyModel package, but can't use it here.
So, instead we need to fallback to some JSON parsing using pretty easy regex.
So, instead we need to fallback to some JSON parsing with copy-paste tiny json.

Json part example:
"Avalonia.Xaml.Interactions/11.0.0-preview5": {
Expand All @@ -61,21 +60,53 @@ No need to resolve real path of ref assemblies.
No need to handle special cases with .NET Framework and GAC.
*/
var text = new StreamReader(stream).ReadToEnd();
var matches = Regex.Matches( text, """runtime"\s*:\s*{\s*"([^"]+)""");
var deps = ParseRuntimeDeps(text);

foreach (Match match in matches)
foreach (var dependencyRuntimeLibs in deps)
{
if (match.Groups[1] is { Success: true } g)
foreach (var runtimeLib in dependencyRuntimeLibs)
{
var assemblyName = Path.GetFileNameWithoutExtension(g.Value);
var assemblyName = Path.GetFileNameWithoutExtension(runtimeLib);
try
{
_ = Assembly.Load(new AssemblyName(assemblyName));
}
catch
{
}
}
}
}

private static List<IEnumerable<string>> ParseRuntimeDeps(string text)
{
var runtimeDeps = new List<IEnumerable<string>>();
try
{
var value = JSONParser.FromJson<Dictionary<string, object>>(text);
if (value?.TryGetValue("targets", out var targetsObj) == true
&& targetsObj is Dictionary<string, object> targets)
{
foreach (var target in targets)
{
if (target.Value is Dictionary<string, object> libraries)
{
foreach (var library in libraries)
{
if ((library.Value as Dictionary<string, object>)?.TryGetValue("runtime", out var runtimeObj) == true
&& runtimeObj is Dictionary<string, object> runtime)
{
runtimeDeps.Add(runtime.Keys);
}
}
}
}
}
}
catch (Exception ex)
{
Console.WriteLine(".deps.json file parsing failed, it might affect previewer stability.\r\n" + ex);
}
return runtimeDeps;
}
}
Loading