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

Sholtee / proxygen / 961

04 Apr 2025 04:54PM UTC coverage: 90.185% (-0.1%) from 90.282%
961

push

appveyor

Sholtee
introduce IInterceptorAccess interface, simplify proxy activation

4815 of 5339 relevant lines covered (90.19%)

0.9 hits per line

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

75.79
/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 = new();
1✔
68

69
            BlockSyntax?
1✔
70
                get = BuildBody
1✔
71
                (
1✔
72
                    prop.GetMethod,
1✔
73
                    (_, locals) => PropertyAccess
×
74
                    (
×
75
                        prop,
×
76
                        BaseExpression(),
×
77
                        castTargetTo: null,
×
78
                        indices: locals.Select(ResolveArgument)
×
79
                    )
×
80
                ),
1✔
81
                set = BuildBody
1✔
82
                (
1✔
83
                    prop.SetMethod,
1✔
84
                    (_, locals) => AssignmentExpression // base.Prop = _value
×
85
                    (
×
86
                        kind: SyntaxKind.SimpleAssignmentExpression,
×
87
                        left: PropertyAccess
×
88
                        (
×
89
                            prop,
×
90
                            BaseExpression(),
×
91
                            castTargetTo: null,
×
92
                            indices: locals
×
93
                                .Take(locals.Count - 1)
×
94
                                .Select(ResolveArgument)
×
95
                        ),
×
96
                        right: ResolveIdentifierName(locals.Last())
×
97
                    )
×
98
                );
1✔
99

100
            BlockSyntax? BuildBody(IMethodInfo? backingMethod, Func<IReadOnlyList<ParameterSyntax>, IReadOnlyList<LocalDeclarationStatementSyntax>, ExpressionSyntax> invocationFactory)
101
            {
1✔
102
                if (backingMethod is null)
1✔
103
                    return null;
×
104

105
                //
106
                // Check if the method is visible.
107
                //
108

109
                Visibility.Check(backingMethod, ContainingAssembly, allowProtected: true);
1✔
110

111
                FieldDeclarationSyntax field = ResolveField<ExtendedMemberInfo>
1✔
112
                (
1✔
113
                    $"F{backingMethod.GetMD5HashCode()}",
1✔
114
                    @readonly: false
1✔
115
                );
1✔
116

117
                members.Add(field);
1✔
118

119
                LocalDeclarationStatementSyntax argsArray = ResolveArgumentsArray(backingMethod);
1✔
120

121
                InvocationExpressionSyntax interceptorInvocation = InvokeInterceptor
1✔
122
                (
1✔
123
                    Argument
1✔
124
                    (
1✔
125
                        StaticMemberAccess(cls, field)
1✔
126
                    ),
1✔
127
                    Argument
1✔
128
                    (
1✔
129
                        backingMethod.IsAbstract ? ResolveNotImplemented() : ResolveInvokeTarget
1✔
130
                        (
1✔
131
                            backingMethod,
1✔
132
                            hasTarget: false,
1✔
133
                            invocationFactory
1✔
134
                        )
1✔
135
                    ),
1✔
136
                    Argument
1✔
137
                    (
1✔
138
                        ResolveIdentifierName(argsArray)
1✔
139
                    ),
1✔
140
                    Argument
1✔
141
                    (
1✔
142
                        ResolveArray<Type>([])
1✔
143
                    )
1✔
144
                );
1✔
145

146
                return Block
1✔
147
                (
1✔
148
                    argsArray,
1✔
149
                    backingMethod.ReturnValue.Type.IsVoid
1✔
150
                        ? ExpressionStatement(interceptorInvocation)
1✔
151
                        : ReturnResult(backingMethod.ReturnValue.Type, interceptorInvocation)
1✔
152
                );
1✔
153
            }
1✔
154

155
            members.Add
1✔
156
            (
1✔
157
                prop.Indices.Any()
1✔
158
                    ? ResolveIndexer(prop, get, set, false)
1✔
159
                    : ResolveProperty(prop, get, set, false)
1✔
160
            );
1✔
161

162
            return cls.AddMembers(members.ToArray());
1✔
163
        }
1✔
164
    }
165
}
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