AvaloniaXamlIlConstructorServiceProviderTransformer.cs 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. using System.Linq;
  2. using XamlX.Ast;
  3. using XamlX.Emit;
  4. using XamlX.IL;
  5. using XamlX.Transform;
  6. using XamlX.TypeSystem;
  7. namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
  8. {
  9. class AvaloniaXamlIlConstructorServiceProviderTransformer : IXamlAstTransformer
  10. {
  11. public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode node)
  12. {
  13. if (node is XamlAstObjectNode on && on.Arguments.Count == 0)
  14. {
  15. var ctors = on.Type.GetClrType().Constructors;
  16. if (!ctors.Any(c => c.IsPublic && !c.IsStatic && c.Parameters.Count == 0))
  17. {
  18. var sp = context.Configuration.TypeMappings.ServiceProvider;
  19. if (ctors.Any(c =>
  20. c.IsPublic && !c.IsStatic && c.Parameters.Count == 1 && c.Parameters[0]
  21. .Equals(sp)))
  22. {
  23. on.Arguments.Add(new InjectServiceProviderNode(sp, on));
  24. }
  25. }
  26. }
  27. return node;
  28. }
  29. class InjectServiceProviderNode : XamlAstNode, IXamlAstValueNode,IXamlAstNodeNeedsParentStack,
  30. IXamlAstEmitableNode<IXamlILEmitter, XamlILNodeEmitResult>
  31. {
  32. public InjectServiceProviderNode(IXamlType type, IXamlLineInfo lineInfo) : base(lineInfo)
  33. {
  34. Type = new XamlAstClrTypeReference(lineInfo, type, false);
  35. }
  36. public IXamlAstTypeReference Type { get; }
  37. public bool NeedsParentStack => true;
  38. public XamlILNodeEmitResult Emit(XamlEmitContext<IXamlILEmitter, XamlILNodeEmitResult> context, IXamlILEmitter codeGen)
  39. {
  40. codeGen.Ldloc(context.ContextLocal);
  41. return XamlILNodeEmitResult.Type(0, Type.GetClrType());
  42. }
  43. }
  44. }
  45. }