aboutsummaryrefslogtreecommitdiffstats
path: root/src/Qt.DotNet.Generator/Qt/DotNet/Extensions/AttributeExtensions.cs
blob: d39723c083d3d62b0d7976107a7dd86ce6b70244 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
/***************************************************************************************************
 Copyright (C) 2025 The Qt Company Ltd.
 SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
***************************************************************************************************/

using System.Reflection;

namespace Qt.DotNet.Extensions
{
    using CodeGeneration;
    using Qt.Quick;
    using System.Linq;
    using static CodeGeneration.Rule;

    public static class AttributeExtensions
    {
        public static IEnumerable<CustomAttributeData> QtAttributeData<TAttrib>(this object self)
            where TAttrib : Attribute
        {
            var attribType = TypeOf<TAttrib>();
            return self.QtAttributeData()
                .Where(a => a.AttributeType.IsAssignableTo(attribType));
        }

        public static IEnumerable<CustomAttributeData> QtAttributeData(this object self)
        {
            var attribData = self switch
            {
                Assembly dll => dll.GetCustomAttributesData(),
                Type type when type.IsRootNode() => type.Assembly.GetCustomAttributesData(),
                Type type => type.GetCustomAttributesData(),
                MemberInfo memberInfo => memberInfo.GetCustomAttributesData(),
                _ => []
            };
            var adapterAssembly = TypeOf<Adapter>().Assembly;
            return attribData.Where(x => x.AttributeType.Assembly == adapterAssembly);
        }

        public static bool HasProperty(this CustomAttributeData self, string name)
        {
            var namedArguments = self?.NamedArguments ?? new List<CustomAttributeNamedArgument>();
            return namedArguments.Any(arg => arg.MemberName == name);
        }

        public static object Property(this CustomAttributeData self, string name)
        {
            var namedArguments = self?.NamedArguments ?? new List<CustomAttributeNamedArgument>();
            if (!self.HasProperty(name))
                throw new ArgumentException($"Property '{name}' not found.", nameof(name));
            return namedArguments.FirstOrDefault(arg => arg.MemberName == name)
                .TypedValue.Value;
        }

        public static bool TryProperty(this CustomAttributeData self, string name, out object value)
        {
            value = null;
            if (!self.HasProperty(name))
                return false;
            value = self.Property(name);
            return true;
        }

        public static T Property<T>(this CustomAttributeData self, string name)
        {
            var namedArguments = self?.NamedArguments ?? new List<CustomAttributeNamedArgument>();
            if (!self.HasProperty(name))
                throw new ArgumentException($"Property '{name}' not found.", nameof(name));
            var arg = namedArguments.FirstOrDefault(arg => arg.MemberName == name).TypedValue;
            if (arg.ArgumentType != TypeOf<T>() || arg.Value is not T argValue)
                return default;
            return argValue;
        }

        public static bool TryProperty<T>(this CustomAttributeData self, string name, out T value)
        {
            value = default;
            if (!self.HasProperty(name))
                return false;
            value = self.Property<T>(name);
            return true;
        }
    }
}