Browse Source

feature: Add XamlXRawNameReferenceXamlParser (#4)

* Add XAML parser based on XamlX
pull/10407/head
Artyom V. Gorchakov 5 years ago
committed by GitHub
parent
commit
2c8d46da09
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      .gitignore
  2. 3
      .gitmodules
  3. 0
      external/.gitkeep.txt
  4. 1
      external/XamlX
  5. 0
      src/XamlNameReferenceGenerator.Sandbox/App.xaml
  6. 0
      src/XamlNameReferenceGenerator.Sandbox/App.xaml.cs
  7. 0
      src/XamlNameReferenceGenerator.Sandbox/Controls/CustomTextBox.cs
  8. 4
      src/XamlNameReferenceGenerator.Sandbox/Program.cs
  9. 16
      src/XamlNameReferenceGenerator.Sandbox/SignUpView.xaml
  10. 0
      src/XamlNameReferenceGenerator.Sandbox/SignUpView.xaml.cs
  11. 6
      src/XamlNameReferenceGenerator.Sandbox/XamlNameReferenceGenerator.Sandbox.csproj
  12. 0
      src/XamlNameReferenceGenerator.sln
  13. 0
      src/XamlNameReferenceGenerator/NameReferenceDebugger.cs
  14. 5
      src/XamlNameReferenceGenerator/NameReferenceGenerator.cs
  15. 0
      src/XamlNameReferenceGenerator/NameReferenceSyntaxReceiver.cs
  16. 9
      src/XamlNameReferenceGenerator/Parsers/INameReferenceXamlParser.cs
  17. 12
      src/XamlNameReferenceGenerator/Parsers/XamlXCompiledNameReferenceXamlParser.cs
  18. 67
      src/XamlNameReferenceGenerator/Parsers/XamlXRawNameReferenceXamlParser.cs
  19. 8
      src/XamlNameReferenceGenerator/Parsers/XmlDocumentNameReferenceXamlParser.cs
  20. 7
      src/XamlNameReferenceGenerator/XamlNameReferenceGenerator.csproj

2
.gitignore

@ -4,7 +4,7 @@
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
.idea
**/.idea
*.rsuser
*.suo
*.user

3
.gitmodules

@ -0,0 +1,3 @@
[submodule "external/XamlX"]
path = external/XamlX
url = git@github.com:kekekeks/XamlX.git

0
external/.gitkeep.txt

1
external/XamlX

@ -0,0 +1 @@
Subproject commit 5420df861ce6f2be5ead9efa078fe7242ce88f18

0
XamlNameReferenceGenerator.Sandbox/App.xaml → src/XamlNameReferenceGenerator.Sandbox/App.xaml

0
XamlNameReferenceGenerator.Sandbox/App.xaml.cs → src/XamlNameReferenceGenerator.Sandbox/App.xaml.cs

0
XamlNameReferenceGenerator.Sandbox/Controls/CustomTextBox.cs → src/XamlNameReferenceGenerator.Sandbox/Controls/CustomTextBox.cs

4
XamlNameReferenceGenerator.Sandbox/Program.cs → src/XamlNameReferenceGenerator.Sandbox/Program.cs

@ -1,6 +1,4 @@
using System;
using Avalonia;
using Avalonia.Logging.Serilog;
using Avalonia;
using Avalonia.ReactiveUI;
namespace XamlNameReferenceGenerator.Sandbox

16
XamlNameReferenceGenerator.Sandbox/SignUpView.xaml → src/XamlNameReferenceGenerator.Sandbox/SignUpView.xaml

@ -4,23 +4,24 @@
xmlns:controls="clr-namespace:XamlNameReferenceGenerator.Sandbox.Controls"
x:Class="XamlNameReferenceGenerator.Sandbox.SignUpView">
<StackPanel>
<!-- Regular name directives. -->
<controls:CustomTextBox Margin="0 10 0 0"
x:Name="UserNameTextBox"
Watermark="Please, enter user name..."
UseFloatingWatermark="True" />
<TextBlock x:Name="UserNameValidation"
Name="UserNameTextBox"
Watermark="Please, enter user name..."
UseFloatingWatermark="True" />
<TextBlock Name="UserNameValidation"
Foreground="Red"
FontSize="12" />
<TextBox Margin="0 10 0 0"
x:Name="PasswordTextBox"
Name="PasswordTextBox"
Watermark="Please, enter your password..."
UseFloatingWatermark="True"
PasswordChar="*" />
<TextBlock x:Name="PasswordValidation"
<TextBlock Name="PasswordValidation"
Foreground="Red"
FontSize="12" />
<!-- x:Name directives. -->
<TextBox Margin="0 10 0 0"
x:Name="ConfirmPasswordTextBox"
Watermark="Please, confirm the password..."
@ -30,7 +31,6 @@
TextWrapping="Wrap"
Foreground="Red"
FontSize="12" />
<Button Margin="0 10 0 5"
Content="Sign up"
x:Name="SignUpButton" />

0
XamlNameReferenceGenerator.Sandbox/SignUpView.xaml.cs → src/XamlNameReferenceGenerator.Sandbox/SignUpView.xaml.cs

6
XamlNameReferenceGenerator.Sandbox/XamlNameReferenceGenerator.Sandbox.csproj → src/XamlNameReferenceGenerator.Sandbox/XamlNameReferenceGenerator.Sandbox.csproj

@ -5,9 +5,9 @@
<LangVersion>preview</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Avalonia" Version="0.9.10" />
<PackageReference Include="Avalonia.Desktop" Version="0.9.10" />
<PackageReference Include="Avalonia.ReactiveUI" Version="0.9.10" />
<PackageReference Include="Avalonia" Version="0.10.0-preview5" />
<PackageReference Include="Avalonia.Desktop" Version="0.10.0-preview5" />
<PackageReference Include="Avalonia.ReactiveUI" Version="0.10.0-preview5" />
<PackageReference Include="Citrus.Avalonia" Version="1.2.6" />
</ItemGroup>
<ItemGroup>

0
XamlNameReferenceGenerator.sln → src/XamlNameReferenceGenerator.sln

0
XamlNameReferenceGenerator/NameReferenceDebugger.cs → src/XamlNameReferenceGenerator/NameReferenceDebugger.cs

5
XamlNameReferenceGenerator/NameReferenceGenerator.cs → src/XamlNameReferenceGenerator/NameReferenceGenerator.cs

@ -4,6 +4,7 @@ using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Text;
using System.Text;
using Microsoft.CodeAnalysis.CSharp;
using XamlNameReferenceGenerator.Parsers;
namespace XamlNameReferenceGenerator
{
@ -28,7 +29,7 @@ namespace XamlNameReferenceGenerator
}
";
private const string DebugPath = @"C:\Users\prizr\Documents\GitHub\XamlNameReferenceGenerator\debug.txt";
private static readonly NameReferenceXamlParser XamlParser = new NameReferenceXamlParser();
private static readonly INameReferenceXamlParser XamlParser = new XamlXRawNameReferenceXamlParser();
private static readonly NameReferenceDebugger Debugger = new NameReferenceDebugger(DebugPath);
private static readonly SymbolDisplayFormat SymbolDisplayFormat = new SymbolDisplayFormat(
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces,
@ -70,7 +71,7 @@ namespace XamlNameReferenceGenerator
var nameSpace = classSymbol.ContainingNamespace.ToDisplayString(SymbolDisplayFormat);
var namespaces = additionalNamespaces.Select(name => $"using {name};");
var namedControls = XamlParser
.GetNamedControls(xamlFile)
.GetNamedControls(xamlFile.GetText()!.ToString())
.Select(info => " " +
$"public {info.TypeName} {info.Name} => " +
$"this.FindControl<{info.TypeName}>(\"{info.Name}\");");

0
XamlNameReferenceGenerator/NameReferenceSyntaxReceiver.cs → src/XamlNameReferenceGenerator/NameReferenceSyntaxReceiver.cs

9
src/XamlNameReferenceGenerator/Parsers/INameReferenceXamlParser.cs

@ -0,0 +1,9 @@
using System.Collections.Generic;
namespace XamlNameReferenceGenerator.Parsers
{
public interface INameReferenceXamlParser
{
List<(string TypeName, string Name)> GetNamedControls(string xaml);
}
}

12
src/XamlNameReferenceGenerator/Parsers/XamlXCompiledNameReferenceXamlParser.cs

@ -0,0 +1,12 @@
using System.Collections.Generic;
namespace XamlNameReferenceGenerator.Parsers
{
public class XamlXCompiledNameReferenceXamlParser : INameReferenceXamlParser
{
public List<(string TypeName, string Name)> GetNamedControls(string xaml)
{
throw new System.NotImplementedException();
}
}
}

67
src/XamlNameReferenceGenerator/Parsers/XamlXRawNameReferenceXamlParser.cs

@ -0,0 +1,67 @@
using System.Collections.Generic;
using XamlX;
using XamlX.Ast;
using XamlX.Parsers;
namespace XamlNameReferenceGenerator.Parsers
{
public class XamlXRawNameReferenceXamlParser : INameReferenceXamlParser
{
public List<(string TypeName, string Name)> GetNamedControls(string xaml)
{
var parsed = XDocumentXamlParser.Parse(xaml, new Dictionary<string, string>
{
{XamlNamespaces.Blend2008, XamlNamespaces.Blend2008}
});
var visitor = new XamlAstCollector();
parsed.Root.Visit(visitor);
parsed.Root.VisitChildren(visitor);
return visitor.Controls;
}
private class XamlAstCollector : IXamlAstVisitor
{
public List<(string TypeName, string Name)> Controls { get; } = new List<(string TypeName, string Name)>();
public IXamlAstNode Visit(IXamlAstNode node)
{
if (node is XamlAstObjectNode element && element.Type is XamlAstXmlTypeReference type)
{
foreach (var child in element.Children)
{
var nameValue = ResolveNameDirectiveOrDefault(child);
if (nameValue == null) continue;
var typeNamePair = (type.Name, nameValue);
if (!Controls.Contains(typeNamePair))
Controls.Add(typeNamePair);
}
}
return node;
}
public void Push(IXamlAstNode node) { }
public void Pop() { }
private static string ResolveNameDirectiveOrDefault(IXamlAstNode node) =>
node switch
{
XamlAstXamlPropertyValueNode propertyValueNode when
propertyValueNode.Property is XamlAstNamePropertyReference reference &&
reference.Name == "Name" &&
propertyValueNode.Values.Count > 0 &&
propertyValueNode.Values[0] is XamlAstTextNode nameNode => nameNode.Text,
XamlAstXmlDirective xmlDirective when
xmlDirective.Name == "Name" &&
xmlDirective.Values.Count > 0 &&
xmlDirective.Values[0] is XamlAstTextNode xNameNode => xNameNode.Text,
_ => null
};
}
}
}

8
XamlNameReferenceGenerator/NameReferenceXamlParser.cs → src/XamlNameReferenceGenerator/Parsers/XmlDocumentNameReferenceXamlParser.cs

@ -1,15 +1,13 @@
using System;
using System.Collections.Generic;
using System.Xml;
using Microsoft.CodeAnalysis;
namespace XamlNameReferenceGenerator
namespace XamlNameReferenceGenerator.Parsers
{
internal class NameReferenceXamlParser
internal class XmlDocumentNameReferenceXamlParser : INameReferenceXamlParser
{
public List<(string TypeName, string Name)> GetNamedControls(AdditionalText additionalText)
public List<(string TypeName, string Name)> GetNamedControls(string xaml)
{
var xaml = additionalText.GetText()!.ToString();
var document = new XmlDocument();
document.LoadXml(xaml);

7
XamlNameReferenceGenerator/XamlNameReferenceGenerator.csproj → src/XamlNameReferenceGenerator/XamlNameReferenceGenerator.csproj

@ -4,10 +4,11 @@
<LangVersion>preview</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Avalonia" Version="0.9.10" />
<PackageReference Include="Avalonia.Desktop" Version="0.9.10" />
<PackageReference Include="Avalonia.ReactiveUI" Version="0.9.10" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.8.0-3.final" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.0.0" PrivateAssets="all" />
</ItemGroup>
<ItemGroup>
<Compile Link="XamlX\filename" Include="../../external/XamlX/src/XamlX/**/*.cs" />
<Compile Remove="../../external/XamlX/src/XamlX/**/SreTypeSystem.cs" />
</ItemGroup>
</Project>
Loading…
Cancel
Save