• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Sholtee / proxygen / 976

08 Apr 2025 02:56PM UTC coverage: 91.686% (+1.6%) from 90.091%
976

push

appveyor

Sholtee
introduce PlatformAssemblies class, drop TargetFramework settings

4819 of 5256 relevant lines covered (91.69%)

0.92 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

78.18
/SRC/Private/SyntaxFactories/ClassProxySyntaxFactory.PropertyInterceptorFactory.cs
1
/********************************************************************************
2
* ClassProxySyntaxFactory.PropertyInterceptorFactory.cs                         *
3
*                                                                               *
4
* Author: Denes Solti                                                           *
5
********************************************************************************/
6
using System;
7
using System.Collections.Generic;
8
using System.Linq;
9

10
using Microsoft.CodeAnalysis.CSharp;
11
using Microsoft.CodeAnalysis.CSharp.Syntax;
12

13
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
14

15
namespace Solti.Utils.Proxy.Internals
16
{
17
    internal partial class ClassProxySyntaxFactory
18
    {
19
        #if DEBUG
20
        internal
21
        #endif
22
        protected override ClassDeclarationSyntax ResolveProperties(ClassDeclarationSyntax cls, object context)
23
        {
1✔
24
            foreach (IPropertyInfo prop in TargetType.Properties)
1✔
25
            {
1✔
26
                IMethodInfo targetMethod = prop.GetMethod ?? prop.SetMethod!;
×
27
                if (targetMethod.IsAbstract || targetMethod.IsVirtual)
1✔
28
                    cls = ResolveProperty(cls, context, prop);
1✔
29
            }
1✔
30

31
            return cls.AddMembers
1✔
32
            (
1✔
33
                ResolveProperty(FInterceptor, null, null)
1✔
34
            );
1✔
35
        }
1✔
36

37
        /// <summary>
38
        /// <code>
39
        /// private static ExtendedMemberInfo FXxX;
40
        /// public override T Prop
41
        /// {
42
        ///     get
43
        ///     {
44
        ///         CurrentMethod.GetBase(ref FXxX);
45
        ///     
46
        ///         object[] args = new object[] {value};
47
        ///         
48
        ///         return (T) FInterceptor.Invoke
49
        ///         (
50
        ///             new ClassInvocationContext
51
        ///             (
52
        ///                 FXxX,
53
        ///                 args => base.Prop;
54
        ///                 args,
55
        ///                 new Type[] {}
56
        ///             )
57
        ///         ); 
58
        ///     }
59
        /// }
60
        /// </code>
61
        /// </summary>
62
        #if DEBUG
63
        internal
64
        #endif
65
        protected override ClassDeclarationSyntax ResolveProperty(ClassDeclarationSyntax cls, object context, IPropertyInfo prop)
66
        {
1✔
67
            List<MemberDeclarationSyntax> members = [];
1✔
68

69
            BlockSyntax? get;
70
            if (prop.GetMethod is null) get = null; else
×
71
            {
1✔
72
                if (!IsVisible(prop.GetMethod))
1✔
73
                    return cls;
×
74

75
                get = BuildBody
1✔
76
                (
1✔
77
                    prop.GetMethod,
1✔
78
                    (_, locals) => PropertyAccess
×
79
                    (
×
80
                        prop,
×
81
                        BaseExpression(),
×
82
                        indices: locals.Select(ResolveArgument)
×
83
                    )
×
84
                );
1✔
85
            }
1✔
86

87
            BlockSyntax? set;
88
            if (prop.SetMethod is null) set = null; else
×
89
            {
1✔
90
                if (!IsVisible(prop.SetMethod))
1✔
91
                    return cls;
×
92

93
                set = BuildBody
1✔
94
                (
1✔
95
                    prop.SetMethod,
1✔
96
                    (_, locals) => AssignmentExpression // base.Prop = _value
×
97
                    (
×
98
                        kind: SyntaxKind.SimpleAssignmentExpression,
×
99
                        left: PropertyAccess
×
100
                        (
×
101
                            prop,
×
102
                            BaseExpression(),
×
103
                            indices: locals
×
104
                                .Take(locals.Count - 1)
×
105
                                .Select(ResolveArgument)
×
106
                        ),
×
107
                        right: ResolveIdentifierName(locals.Last())
×
108
                    )
×
109
                );
1✔
110
            }
1✔
111

112
            members.Add
1✔
113
            (
1✔
114
                prop.Indices.Any()
1✔
115
                    ? ResolveIndexer(prop, get, set)
1✔
116
                    : ResolveProperty(prop, get, set)
1✔
117
            );
1✔
118

119
            return cls.AddMembers([.. members]);
1✔
120

121
            BlockSyntax? BuildBody(IMethodInfo backingMethod, Func<IReadOnlyList<ParameterSyntax>, IReadOnlyList<LocalDeclarationStatementSyntax>, ExpressionSyntax> invocationFactory)
122
            {
1✔
123
                FieldDeclarationSyntax field = ResolveField<ExtendedMemberInfo>
1✔
124
                (
1✔
125
                    $"F{backingMethod.GetMD5HashCode()}",
1✔
126
                    @readonly: false
1✔
127
                );
1✔
128

129
                members.Add(field);
1✔
130

131
                LocalDeclarationStatementSyntax argsArray = ResolveArgumentsArray(backingMethod);
1✔
132

133
                InvocationExpressionSyntax interceptorInvocation = InvokeInterceptor
1✔
134
                (
1✔
135
                    Argument
1✔
136
                    (
1✔
137
                        StaticMemberAccess(cls, field)
1✔
138
                    ),
1✔
139
                    Argument
1✔
140
                    (
1✔
141
                        backingMethod.IsAbstract ? ResolveNotImplemented() : ResolveInvokeTarget
1✔
142
                        (
1✔
143
                            backingMethod,
1✔
144
                            hasTarget: false,
1✔
145
                            invocationFactory
1✔
146
                        )
1✔
147
                    ),
1✔
148
                    Argument
1✔
149
                    (
1✔
150
                        ResolveIdentifierName(argsArray)
1✔
151
                    ),
1✔
152
                    Argument
1✔
153
                    (
1✔
154
                        ResolveArray<Type>([])
1✔
155
                    )
1✔
156
                );
1✔
157

158
                return Block
1✔
159
                (
1✔
160
                    ExpressionStatement
1✔
161
                    (
1✔
162
                        InvokeMethod
1✔
163
                        (
1✔
164
                            FGetBase,
1✔
165
                            arguments: Argument
1✔
166
                            (
1✔
167
                                StaticMemberAccess(cls, field)
1✔
168
                            )
1✔
169
                        )
1✔
170
                    ),
1✔
171
                    argsArray,
1✔
172
                    backingMethod.ReturnValue.Type.IsVoid
1✔
173
                        ? ExpressionStatement(interceptorInvocation)
1✔
174
                        : ReturnResult(backingMethod.ReturnValue.Type, interceptorInvocation)
1✔
175
                );
1✔
176
            }
1✔
177
        }
1✔
178
    }
179
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc