summaryrefslogtreecommitdiff
path: root/VRCSDK3Worlds/Assets/Udon/Serialization/OdinSerializer/Utilities/Misc/MemberAliasFieldInfo.cs
blob: a1230b3708ad0212a8460a6ffece2a80cdcfe8ff (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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
//-----------------------------------------------------------------------
// <copyright file="MemberAliasFieldInfo.cs" company="Sirenix IVS">
// Copyright (c) 2018 Sirenix IVS
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>
//-----------------------------------------------------------------------

namespace VRC.Udon.Serialization.OdinSerializer.Utilities
{
    using System;
    using System.Globalization;
    using System.Reflection;

    /// <summary>
    /// Provides a methods of representing imaginary fields which are unique to serialization.
    /// <para />
    /// We aggregate the FieldInfo associated with this member and return a mangled form of the name.
    /// </summary>
    /// <seealso cref="System.Reflection.FieldInfo" />
    public sealed class MemberAliasFieldInfo : FieldInfo
    {
        /// <summary>
        /// The default fake name separator string.
        /// </summary>
        private const string FAKE_NAME_SEPARATOR_STRING = "+";

        private FieldInfo aliasedField;
        private string mangledName;

        /// <summary>
        /// Initializes a new instance of the <see cref="MemberAliasFieldInfo"/> class.
        /// </summary>
        /// <param name="field">The field to alias.</param>
        /// <param name="namePrefix">The name prefix to use.</param>
        public MemberAliasFieldInfo(FieldInfo field, string namePrefix)
        {
            this.aliasedField = field;
            this.mangledName = string.Concat(namePrefix, FAKE_NAME_SEPARATOR_STRING, this.aliasedField.Name);
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="MemberAliasFieldInfo"/> class.
        /// </summary>
        /// <param name="field">The field to alias.</param>
        /// <param name="namePrefix">The name prefix to use.</param>
        /// <param name="separatorString">The separator string to use.</param>
        public MemberAliasFieldInfo(FieldInfo field, string namePrefix, string separatorString)
        {
            this.aliasedField = field;
            this.mangledName = string.Concat(namePrefix, separatorString, this.aliasedField.Name);
        }

        /// <summary>
        /// Gets the aliased field.
        /// </summary>
        /// <value>
        /// The aliased field.
        /// </value>
        public FieldInfo AliasedField { get { return this.aliasedField; } }

        /// <summary>
        /// Gets the module in which the type that declares the member represented by the current <see cref="T:System.Reflection.MemberInfo" /> is defined.
        /// </summary>
        public override Module Module { get { return this.aliasedField.Module; } }

        /// <summary>
        /// Gets a value that identifies a metadata element.
        /// </summary>
        public override int MetadataToken { get { return this.aliasedField.MetadataToken; } }

        /// <summary>
        /// Gets the name of the current member.
        /// </summary>
        public override string Name { get { return this.mangledName; } }

        /// <summary>
        /// Gets the class that declares this member.
        /// </summary>
        public override Type DeclaringType { get { return this.aliasedField.DeclaringType; } }

        /// <summary>
        /// Gets the class object that was used to obtain this instance of MemberInfo.
        /// </summary>
        public override Type ReflectedType { get { return this.aliasedField.ReflectedType; } }

        /// <summary>
        /// Gets the type of the field.
        /// </summary>
        /// <value>
        /// The type of the field.
        /// </value>
        public override Type FieldType { get { return this.aliasedField.FieldType; } }

        /// <summary>
        /// Gets a RuntimeFieldHandle, which is a handle to the internal metadata representation of a field.
        /// </summary>
        public override RuntimeFieldHandle FieldHandle { get { return this.aliasedField.FieldHandle; } }

        /// <summary>
        /// Gets the attributes.
        /// </summary>
        /// <value>
        /// The attributes.
        /// </value>
        public override FieldAttributes Attributes { get { return this.aliasedField.Attributes; } }

        /// <summary>
        /// When overridden in a derived class, returns an array of all custom attributes applied to this member.
        /// </summary>
        /// <param name="inherit">True to search this member's inheritance chain to find the attributes; otherwise, false. This parameter is ignored for properties and events; see Remarks.</param>
        /// <returns>
        /// An array that contains all the custom attributes applied to this member, or an array with zero elements if no attributes are defined.
        /// </returns>
        public override object[] GetCustomAttributes(bool inherit)
        {
            return this.aliasedField.GetCustomAttributes(inherit);
        }

        /// <summary>
        /// When overridden in a derived class, returns an array of custom attributes applied to this member and identified by <see cref="T:System.Type" />.
        /// </summary>
        /// <param name="attributeType">The type of attribute to search for. Only attributes that are assignable to this type are returned.</param>
        /// <param name="inherit">True to search this member's inheritance chain to find the attributes; otherwise, false. This parameter is ignored for properties and events; see Remarks.</param>
        /// <returns>
        /// An array of custom attributes applied to this member, or an array with zero elements if no attributes assignable to <paramref name="attributeType" /> have been applied.
        /// </returns>
        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
        {
            return this.aliasedField.GetCustomAttributes(attributeType, inherit);
        }

        /// <summary>
        /// When overridden in a derived class, indicates whether one or more attributes of the specified type or of its derived types is applied to this member.
        /// </summary>
        /// <param name="attributeType">The type of custom attribute to search for. The search includes derived types.</param>
        /// <param name="inherit">True to search this member's inheritance chain to find the attributes; otherwise, false. This parameter is ignored for properties and events; see Remarks.</param>
        /// <returns>
        /// True if one or more instances of <paramref name="attributeType" /> or any of its derived types is applied to this member; otherwise, false.
        /// </returns>
        public override bool IsDefined(Type attributeType, bool inherit)
        {
            return this.aliasedField.IsDefined(attributeType, inherit);
        }

        /// <summary>
        /// Gets the value of the field.
        /// </summary>
        /// <param name="obj">The object instance to get the value from.</param>
        /// <returns>The value of the field.</returns>
        public override object GetValue(object obj)
        {
            return this.aliasedField.GetValue(obj);
        }

        /// <summary>
        /// When overridden in a derived class, sets the value of the field supported by the given object.
        /// </summary>
        /// <param name="obj">The object whose field value will be set.</param>
        /// <param name="value">The value to assign to the field.</param>
        /// <param name="invokeAttr">A field of Binder that specifies the type of binding that is desired (for example, Binder.CreateInstance or Binder.ExactBinding).</param>
        /// <param name="binder">A set of properties that enables the binding, coercion of argument types, and invocation of members through reflection. If <paramref name="binder" /> is null, then Binder.DefaultBinding is used.</param>
        /// <param name="culture">The software preferences of a particular culture.</param>
        public override void SetValue(object obj, object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture)
        {
            this.aliasedField.SetValue(obj, value, invokeAttr, binder, culture);
        }
    }
}