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

Sholtee / proxygen / 985

12 Apr 2025 04:09AM UTC coverage: 91.662% (-0.3%) from 91.971%
985

push

appveyor

Sholtee
greenify tests

4903 of 5349 relevant lines covered (91.66%)

0.92 hits per line

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

80.37
/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 BaseType.Properties)
1✔
25
            {
1✔
26
                IMethodInfo targetMethod = prop.GetMethod ?? prop.SetMethod!;
1✔
27
                if (targetMethod.IsAbstract || targetMethod.IsVirtual)
1✔
28
                    cls = ResolveProperty(cls, context, prop);
1✔
29
            }
1✔
30

31
            return base.ResolveProperties(cls, context);
1✔
32
        }
1✔
33

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

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

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

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

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

109
            members.Add
1✔
110
            (
1✔
111
                prop.Indices.Any()
1✔
112
                    ? ResolveIndexer(prop, get, set)
1✔
113
                    : ResolveProperty(prop, get, set)
1✔
114
            );
1✔
115

116
            return cls.AddMembers([.. members]);
1✔
117

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

126
                members.Add(field);
1✔
127

128
                LocalDeclarationStatementSyntax argsArray = ResolveArgumentsArray(backingMethod);
1✔
129

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

155
                return Block
1✔
156
                (
1✔
157
                    ExpressionStatement
1✔
158
                    (
1✔
159
                        InvokeMethod
1✔
160
                        (
1✔
161
                            FGetBase,
1✔
162
                            arguments: Argument
1✔
163
                            (
1✔
164
                                StaticMemberAccess(cls, field)
1✔
165
                            )
1✔
166
                        )
1✔
167
                    ),
1✔
168
                    argsArray,
1✔
169
                    backingMethod.ReturnValue.Type.IsVoid
1✔
170
                        ? ExpressionStatement(interceptorInvocation)
1✔
171
                        : ReturnResult(backingMethod.ReturnValue.Type, interceptorInvocation)
1✔
172
                );
1✔
173
            }
1✔
174
        }
1✔
175
    }
176
}
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