1 // Licensed to the .NET Foundation under one or more agreements. 2 // The .NET Foundation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using System; 6 using System.Collections.Generic; 7 using System.Diagnostics; 8 using System.Runtime.InteropServices; 9 using Microsoft.CSharp.RuntimeBinder.Syntax; 10 11 namespace Microsoft.CSharp.RuntimeBinder.Semantics 12 { 13 // ---------------------------------------------------------------------------- 14 // 15 // MethodOrPropertySymbol 16 // 17 // MethodOrPropertySymbol - abstract class representing a method or a property. There 18 // are a bunch of algorithms in the compiler (e.g., override and overload 19 // resolution) that want to treat methods and properties the same. This 20 // abstract base class has the common parts. 21 // 22 // Changed to a ParentSymbol to allow generic methods to parent their type 23 // variables. 24 // ---------------------------------------------------------------------------- 25 26 internal abstract class MethodOrPropertySymbol : ParentSymbol 27 { 28 public uint modOptCount; // number of CMOD_OPTs in signature and return type 29 30 public new bool isStatic; // Static member? 31 public bool isOverride; // Overrides an inherited member. Only valid if isVirtual is set. 32 // false implies that a new vtable slot is required for this method. 33 public bool isOperator; // a user defined operator (or default indexed property) 34 public bool isParamArray; // new style varargs 35 public bool isHideByName; // this property hides all below it regardless of signature 36 public List<Name> ParameterNames { get; private set; } 37 private bool[] _optionalParameterIndex; 38 private bool[] _defaultParameterIndex; 39 private ConstVal[] _defaultParameters; 40 private CType[] _defaultParameterConstValTypes; 41 private bool[] _marshalAsIndex; 42 private UnmanagedType[] _marshalAsBuffer; 43 44 // This indicates the base member that this member overrides or implements. 45 // For an explicit interface member implementation, this is the interface member (and type) 46 // that the member implements. For an override member, this is the base member that is 47 // being overridden. This is not affected by implicit interface member implementation. 48 // If this symbol is a property and an explicit interface member implementation, the swtSlot 49 // may be an event. This is filled in during prepare. 50 public SymWithType swtSlot; 51 public CType RetType; // Return type. 52 53 private TypeArray _Params; 54 public TypeArray Params 55 { 56 get 57 { 58 return _Params; 59 } 60 set 61 { 62 Debug.Assert(_Params == null, "Should only be set once"); 63 _Params = value; 64 int count = value.Count; 65 if (count == 0) 66 { 67 _optionalParameterIndex = _defaultParameterIndex = _marshalAsIndex = Array.Empty<bool>(); 68 _defaultParameters = Array.Empty<ConstVal>(); 69 _defaultParameterConstValTypes = Array.Empty<CType>(); 70 _marshalAsBuffer = Array.Empty<UnmanagedType>(); 71 } 72 else 73 { 74 _optionalParameterIndex = new bool[count]; 75 _defaultParameterIndex = new bool[count]; 76 _defaultParameters = new ConstVal[count]; 77 _defaultParameterConstValTypes = new CType[count]; 78 _marshalAsIndex = new bool[count]; 79 _marshalAsBuffer = new UnmanagedType[count]; 80 } 81 } 82 } 83 MethodOrPropertySymbol()84 public MethodOrPropertySymbol() 85 { 86 ParameterNames = new List<Name>(); 87 } 88 89 ///////////////////////////////////////////////////////////////////////////////// 90 IsParameterOptional(int index)91 public bool IsParameterOptional(int index) 92 { 93 Debug.Assert(index < Params.Count); 94 95 if (_optionalParameterIndex == null) 96 { 97 return false; 98 } 99 return _optionalParameterIndex[index]; 100 } 101 SetOptionalParameter(int index)102 public void SetOptionalParameter(int index) 103 { 104 Debug.Assert(_optionalParameterIndex != null); 105 _optionalParameterIndex[index] = true; 106 } 107 HasOptionalParameters()108 public bool HasOptionalParameters() 109 { 110 if (_optionalParameterIndex == null) 111 { 112 return false; 113 } 114 foreach (bool b in _optionalParameterIndex) 115 { 116 if (b) 117 { 118 return true; 119 } 120 } 121 return false; 122 } 123 HasDefaultParameterValue(int index)124 public bool HasDefaultParameterValue(int index) 125 { 126 Debug.Assert(index < Params.Count); 127 Debug.Assert(_defaultParameterIndex != null); 128 return _defaultParameterIndex[index]; 129 } 130 SetDefaultParameterValue(int index, CType type, ConstVal cv)131 public void SetDefaultParameterValue(int index, CType type, ConstVal cv) 132 { 133 Debug.Assert(_defaultParameterIndex != null); 134 _defaultParameterIndex[index] = true; 135 _defaultParameters[index] = cv; 136 _defaultParameterConstValTypes[index] = type; 137 } 138 GetDefaultParameterValue(int index)139 public ConstVal GetDefaultParameterValue(int index) 140 { 141 Debug.Assert(HasDefaultParameterValue(index)); 142 Debug.Assert(_defaultParameterIndex != null); 143 return _defaultParameters[index]; 144 } 145 GetDefaultParameterValueConstValType(int index)146 public CType GetDefaultParameterValueConstValType(int index) 147 { 148 Debug.Assert(HasDefaultParameterValue(index)); 149 return _defaultParameterConstValTypes[index]; 150 } 151 IsMarshalAsParameter(int index)152 private bool IsMarshalAsParameter(int index) 153 { 154 return _marshalAsIndex[index]; 155 } 156 SetMarshalAsParameter(int index, UnmanagedType umt)157 public void SetMarshalAsParameter(int index, UnmanagedType umt) 158 { 159 _marshalAsIndex[index] = true; 160 _marshalAsBuffer[index] = umt; 161 } 162 GetMarshalAsParameterValue(int index)163 private UnmanagedType GetMarshalAsParameterValue(int index) 164 { 165 Debug.Assert(IsMarshalAsParameter(index)); 166 return _marshalAsBuffer[index]; 167 } 168 MarshalAsObject(int index)169 public bool MarshalAsObject(int index) 170 { 171 if (IsMarshalAsParameter(index)) 172 { 173 UnmanagedType marshalAsType = GetMarshalAsParameterValue(index); 174 return marshalAsType == UnmanagedType.Interface || marshalAsType == UnmanagedType.IUnknown || marshalAsType == UnmanagedType.IDispatch; 175 } 176 177 return false; 178 } 179 getClass()180 public AggregateSymbol getClass() => parent as AggregateSymbol; 181 IsExpImpl()182 public bool IsExpImpl() 183 { 184 return name == null; 185 } 186 } 187 } 188