private static bool DoesSignatureMatch( PEModuleSymbol moduleSymbol, TypeSymbol eventType, PEMethodSymbol method) { // CONSIDER: It would be nice if we could reuse this signature information in the PEMethodSymbol. var metadataDecoder = new MetadataDecoder(moduleSymbol, method); SignatureHeader signatureHeader; BadImageFormatException mrEx; var methodParams = metadataDecoder.GetSignatureForMethod(method.Handle, out signatureHeader, out mrEx, setParamHandles: false); if (mrEx != null) { return(false); } return(metadataDecoder.DoesSignatureMatchEvent(eventType, methodParams)); }
internal static PEPropertySymbol Create( PEModuleSymbol moduleSymbol, PENamedTypeSymbol containingType, PropertyDefinitionHandle handle, PEMethodSymbol getMethod, PEMethodSymbol setMethod) { Debug.Assert((object)moduleSymbol != null); Debug.Assert((object)containingType != null); #if !XSHARP Debug.Assert(!handle.IsNil); #endif var metadataDecoder = new MetadataDecoder(moduleSymbol, containingType); SignatureHeader callingConvention; BadImageFormatException propEx; #if XSHARP var propertyParams = handle.IsNil ? metadataDecoder.GetSignatureForMethod(getMethod.Handle, out callingConvention, out propEx) : metadataDecoder.GetSignatureForProperty(handle, out callingConvention, out propEx); #else var propertyParams = metadataDecoder.GetSignatureForProperty(handle, out callingConvention, out propEx); #endif Debug.Assert(propertyParams.Length > 0); var returnInfo = propertyParams[0]; PEPropertySymbol result = returnInfo.CustomModifiers.IsDefaultOrEmpty && returnInfo.RefCustomModifiers.IsDefaultOrEmpty ? new PEPropertySymbol(moduleSymbol, containingType, handle, getMethod, setMethod, 0, propertyParams, metadataDecoder) : new PEPropertySymbolWithCustomModifiers(moduleSymbol, containingType, handle, getMethod, setMethod, propertyParams, metadataDecoder); // A property should always have this modreq, and vice versa. var isBad = (result.RefKind == RefKind.In) != result.RefCustomModifiers.HasInAttributeModifier(); if (propEx != null || isBad) { result._lazyUseSiteDiagnostic = new CSDiagnosticInfo(ErrorCode.ERR_BindToBogus, result); } return(result); }
private PEPropertySymbol( PEModuleSymbol moduleSymbol, PENamedTypeSymbol containingType, PropertyDefinitionHandle handle, PEMethodSymbol getMethod, PEMethodSymbol setMethod, ParamInfo <TypeSymbol>[] propertyParams, MetadataDecoder metadataDecoder) { _containingType = containingType; var module = moduleSymbol.Module; PropertyAttributes mdFlags = 0; BadImageFormatException mrEx = null; try { module.GetPropertyDefPropsOrThrow(handle, out _name, out mdFlags); } catch (BadImageFormatException e) { mrEx = e; if ((object)_name == null) { _name = string.Empty; } } _getMethod = getMethod; _setMethod = setMethod; _handle = handle; SignatureHeader unusedCallingConvention; BadImageFormatException getEx = null; var getMethodParams = (object)getMethod == null ? null : metadataDecoder.GetSignatureForMethod(getMethod.Handle, out unusedCallingConvention, out getEx); BadImageFormatException setEx = null; var setMethodParams = (object)setMethod == null ? null : metadataDecoder.GetSignatureForMethod(setMethod.Handle, out unusedCallingConvention, out setEx); // NOTE: property parameter names are not recorded in metadata, so we have to // use the parameter names from one of the indexers // NB: prefer setter names to getter names if both are present. bool isBad; _parameters = setMethodParams is null ? GetParameters(moduleSymbol, this, propertyParams, getMethodParams, getMethod.IsMetadataVirtual(), out isBad) : GetParameters(moduleSymbol, this, propertyParams, setMethodParams, setMethod.IsMetadataVirtual(), out isBad); if (getEx != null || setEx != null || mrEx != null || isBad) { _lazyUseSiteDiagnostic = new CSDiagnosticInfo(ErrorCode.ERR_BindToBogus, this); } var returnInfo = propertyParams[0]; var typeCustomModifiers = CSharpCustomModifier.Convert(returnInfo.CustomModifiers); if (returnInfo.IsByRef) { if (moduleSymbol.Module.HasIsReadOnlyAttribute(handle)) { _refKind = RefKind.RefReadOnly; } else { _refKind = RefKind.Ref; } } else { _refKind = RefKind.None; } // CONSIDER: Can we make parameter type computation lazy? TypeSymbol originalPropertyType = returnInfo.Type; originalPropertyType = DynamicTypeDecoder.TransformType(originalPropertyType, typeCustomModifiers.Length, handle, moduleSymbol, _refKind); originalPropertyType = NativeIntegerTypeDecoder.TransformType(originalPropertyType, handle, moduleSymbol); // Dynamify object type if necessary originalPropertyType = originalPropertyType.AsDynamicIfNoPia(_containingType); // We start without annotation (they will be decoded below) var propertyTypeWithAnnotations = TypeWithAnnotations.Create(originalPropertyType, customModifiers: typeCustomModifiers); // Decode nullable before tuple types to avoid converting between // NamedTypeSymbol and TupleTypeSymbol unnecessarily. // The containing type is passed to NullableTypeDecoder.TransformType to determine access // because the property does not have explicit accessibility in metadata. propertyTypeWithAnnotations = NullableTypeDecoder.TransformType(propertyTypeWithAnnotations, handle, moduleSymbol, accessSymbol: _containingType, nullableContext: _containingType); propertyTypeWithAnnotations = TupleTypeDecoder.DecodeTupleTypesIfApplicable(propertyTypeWithAnnotations, handle, moduleSymbol); _propertyTypeWithAnnotations = propertyTypeWithAnnotations; // A property is bogus and must be accessed by calling its accessors directly if the // accessor signatures do not agree, both with each other and with the property, // or if it has parameters and is not an indexer or indexed property. bool callMethodsDirectly = !DoSignaturesMatch(module, metadataDecoder, propertyParams, _getMethod, getMethodParams, _setMethod, setMethodParams) || MustCallMethodsDirectlyCore(); if (!callMethodsDirectly) { if ((object)_getMethod != null) { _getMethod.SetAssociatedProperty(this, MethodKind.PropertyGet); } if ((object)_setMethod != null) { _setMethod.SetAssociatedProperty(this, MethodKind.PropertySet); } } if (callMethodsDirectly) { _flags |= Flags.CallMethodsDirectly; } if ((mdFlags & PropertyAttributes.SpecialName) != 0) { _flags |= Flags.IsSpecialName; } if ((mdFlags & PropertyAttributes.RTSpecialName) != 0) { _flags |= Flags.IsRuntimeSpecialName; } }
internal PEPropertySymbol( PEModuleSymbol moduleSymbol, PENamedTypeSymbol containingType, PropertyDefinitionHandle handle, PEMethodSymbol getMethod, PEMethodSymbol setMethod) { Debug.Assert((object)moduleSymbol != null); Debug.Assert((object)containingType != null); Debug.Assert(!handle.IsNil); _containingType = containingType; var module = moduleSymbol.Module; PropertyAttributes mdFlags = 0; BadImageFormatException mrEx = null; try { module.GetPropertyDefPropsOrThrow(handle, out _name, out mdFlags); } catch (BadImageFormatException e) { mrEx = e; if ((object)_name == null) { _name = string.Empty; } } _getMethod = getMethod; _setMethod = setMethod; _handle = handle; var metadataDecoder = new MetadataDecoder(moduleSymbol, containingType); SignatureHeader callingConvention; BadImageFormatException propEx; var propertyParams = metadataDecoder.GetSignatureForProperty(handle, out callingConvention, out propEx, allowByRefReturn: true); Debug.Assert(propertyParams.Length > 0); SignatureHeader unusedCallingConvention; BadImageFormatException getEx = null; var getMethodParams = (object)getMethod == null ? null : metadataDecoder.GetSignatureForMethod(getMethod.Handle, out unusedCallingConvention, out getEx, allowByRefReturn: true); BadImageFormatException setEx = null; var setMethodParams = (object)setMethod == null ? null : metadataDecoder.GetSignatureForMethod(setMethod.Handle, out unusedCallingConvention, out setEx, allowByRefReturn: false); // NOTE: property parameter names are not recorded in metadata, so we have to // use the parameter names from one of the indexers // NB: prefer setter names to getter names if both are present. bool isBad; _parameters = GetParameters(moduleSymbol, this, propertyParams, setMethodParams ?? getMethodParams, out isBad); if (propEx != null || getEx != null || setEx != null || mrEx != null || isBad) { _lazyUseSiteDiagnostic = new CSDiagnosticInfo(ErrorCode.ERR_BindToBogus, this); } _typeCustomModifiers = CSharpCustomModifier.Convert(propertyParams[0].CustomModifiers); _refKind = propertyParams[0].IsByRef ? RefKind.Ref : RefKind.None; // CONSIDER: Can we make parameter type computation lazy? TypeSymbol originalPropertyType = propertyParams[0].Type; _propertyType = DynamicTypeDecoder.TransformType(originalPropertyType, _typeCustomModifiers.Length, handle, moduleSymbol); // Dynamify object type if necessary _propertyType = _propertyType.AsDynamicIfNoPia(_containingType); _propertyType = TupleTypeDecoder.DecodeTupleTypesIfApplicable(_propertyType, handle, moduleSymbol); // A property is bogus and must be accessed by calling its accessors directly if the // accessor signatures do not agree, both with each other and with the property, // or if it has parameters and is not an indexer or indexed property. bool callMethodsDirectly = !DoSignaturesMatch(module, metadataDecoder, propertyParams, _getMethod, getMethodParams, _setMethod, setMethodParams) || MustCallMethodsDirectlyCore(); if (!callMethodsDirectly) { if ((object)_getMethod != null) { _getMethod.SetAssociatedProperty(this, MethodKind.PropertyGet); } if ((object)_setMethod != null) { _setMethod.SetAssociatedProperty(this, MethodKind.PropertySet); } } if (callMethodsDirectly) { _flags |= Flags.CallMethodsDirectly; } if ((mdFlags & PropertyAttributes.SpecialName) != 0) { _flags |= Flags.IsSpecialName; } if ((mdFlags & PropertyAttributes.RTSpecialName) != 0) { _flags |= Flags.IsRuntimeSpecialName; } }
private PEPropertySymbol( PEModuleSymbol moduleSymbol, PENamedTypeSymbol containingType, PropertyDefinitionHandle handle, PEMethodSymbol getMethod, PEMethodSymbol setMethod, int countOfCustomModifiers, ParamInfo <TypeSymbol>[] propertyParams, MetadataDecoder metadataDecoder) { _containingType = containingType; var module = moduleSymbol.Module; PropertyAttributes mdFlags = 0; BadImageFormatException mrEx = null; try { module.GetPropertyDefPropsOrThrow(handle, out _name, out mdFlags); } catch (BadImageFormatException e) { mrEx = e; if ((object)_name == null) { _name = string.Empty; } } _getMethod = getMethod; _setMethod = setMethod; _handle = handle; SignatureHeader unusedCallingConvention; BadImageFormatException getEx = null; var getMethodParams = (object)getMethod == null ? null : metadataDecoder.GetSignatureForMethod(getMethod.Handle, out unusedCallingConvention, out getEx); BadImageFormatException setEx = null; var setMethodParams = (object)setMethod == null ? null : metadataDecoder.GetSignatureForMethod(setMethod.Handle, out unusedCallingConvention, out setEx); // NOTE: property parameter names are not recorded in metadata, so we have to // use the parameter names from one of the indexers // NB: prefer setter names to getter names if both are present. bool isBad; _parameters = setMethodParams is null ? GetParameters(moduleSymbol, this, propertyParams, getMethodParams, getMethod.IsMetadataVirtual(), out isBad) : GetParameters(moduleSymbol, this, propertyParams, setMethodParams, setMethod.IsMetadataVirtual(), out isBad); if (getEx != null || setEx != null || mrEx != null || isBad) { _lazyUseSiteDiagnostic = new CSDiagnosticInfo(ErrorCode.ERR_BindToBogus, this); } var returnInfo = propertyParams[0]; if (returnInfo.IsByRef) { if (moduleSymbol.Module.HasIsReadOnlyAttribute(handle)) { _refKind = RefKind.RefReadOnly; } else { _refKind = RefKind.Ref; } } else { _refKind = RefKind.None; } // CONSIDER: Can we make parameter type computation lazy? TypeSymbol originalPropertyType = returnInfo.Type; #if XSHARP _propertyType = DynamicTypeDecoder.TransformType(originalPropertyType, countOfCustomModifiers, handle.IsNil ? (EntityHandle)getMethod.Handle : handle, moduleSymbol, _refKind); #else _propertyType = DynamicTypeDecoder.TransformType(originalPropertyType, countOfCustomModifiers, handle, moduleSymbol, _refKind); #endif // Dynamify object type if necessary _propertyType = _propertyType.AsDynamicIfNoPia(_containingType); _propertyType = TupleTypeDecoder.DecodeTupleTypesIfApplicable(_propertyType, handle, moduleSymbol); // A property is bogus and must be accessed by calling its accessors directly if the // accessor signatures do not agree, both with each other and with the property, // or if it has parameters and is not an indexer or indexed property. bool callMethodsDirectly = !DoSignaturesMatch(module, metadataDecoder, propertyParams, _getMethod, getMethodParams, _setMethod, setMethodParams) || MustCallMethodsDirectlyCore(); #if XSHARP if (handle.IsNil) { callMethodsDirectly = true; } #endif if (!callMethodsDirectly) { if ((object)_getMethod != null) { _getMethod.SetAssociatedProperty(this, MethodKind.PropertyGet); } if ((object)_setMethod != null) { _setMethod.SetAssociatedProperty(this, MethodKind.PropertySet); } } if (callMethodsDirectly) { _flags |= Flags.CallMethodsDirectly; } if ((mdFlags & PropertyAttributes.SpecialName) != 0) { _flags |= Flags.IsSpecialName; } if ((mdFlags & PropertyAttributes.RTSpecialName) != 0) { _flags |= Flags.IsRuntimeSpecialName; } }