private void EnsureSignatureIsLoaded() { if (_lazyType == null) { var moduleSymbol = _containingType.ContainingPEModule; bool isVolatile; ImmutableArray <ModifierInfo <TypeSymbol> > customModifiers; TypeSymbol typeSymbol = (new MetadataDecoder(moduleSymbol, _containingType)).DecodeFieldSignature(_handle, out isVolatile, out customModifiers); ImmutableArray <CustomModifier> customModifiersArray = CSharpCustomModifier.Convert(customModifiers); typeSymbol = DynamicTypeDecoder.TransformType(typeSymbol, customModifiersArray.Length, _handle, moduleSymbol); typeSymbol = NativeIntegerTypeDecoder.TransformType(typeSymbol, _handle, moduleSymbol); // We start without annotations var type = TypeWithAnnotations.Create(typeSymbol, customModifiers: customModifiersArray); // Decode nullable before tuple types to avoid converting between // NamedTypeSymbol and TupleTypeSymbol unnecessarily. type = NullableTypeDecoder.TransformType(type, _handle, moduleSymbol, accessSymbol: this, nullableContext: _containingType); type = TupleTypeDecoder.DecodeTupleTypesIfApplicable(type, _handle, moduleSymbol); _lazyIsVolatile = isVolatile; TypeSymbol fixedElementType; int fixedSize; if (customModifiersArray.IsEmpty && IsFixedBuffer(out fixedSize, out fixedElementType)) { _lazyFixedSize = fixedSize; _lazyFixedImplementationType = type.Type as NamedTypeSymbol; type = TypeWithAnnotations.Create(new PointerTypeSymbol(TypeWithAnnotations.Create(fixedElementType))); } Interlocked.CompareExchange(ref _lazyType, new TypeWithAnnotations.Boxed(type), null); } }
internal static TypeSymbol TransformType(TypeSymbol type, ImmutableArray <bool> transformFlags) { var decoder = new NativeIntegerTypeDecoder(transformFlags); try { var result = decoder.TransformType(type); if (decoder._index == transformFlags.Length) { return(result); } else { return(new UnsupportedMetadataTypeSymbol()); } } catch (UnsupportedSignatureContent) { return(new UnsupportedMetadataTypeSymbol()); } catch (ErrorTypeException) { // If we failed to decode because there was an error type involved, marking the // metadata as unsupported means that we'll cover up the error that would otherwise // be reported for the type. This would likely lead to a worse error message as we // would just report a BindToBogus, so return the type unchanged. Debug.Assert(type.ContainsErrorType()); return(type); } }
private void EnsureSignatureIsLoaded() { if (_lazyType == null) { var moduleSymbol = _containingType.ContainingPEModule; FieldInfo <TypeSymbol> fieldInfo = new MetadataDecoder(moduleSymbol, _containingType).DecodeFieldSignature(_handle); TypeSymbol typeSymbol = fieldInfo.Type; ImmutableArray <CustomModifier> customModifiersArray = CSharpCustomModifier.Convert(fieldInfo.CustomModifiers); typeSymbol = DynamicTypeDecoder.TransformType(typeSymbol, customModifiersArray.Length, _handle, moduleSymbol); typeSymbol = NativeIntegerTypeDecoder.TransformType(typeSymbol, _handle, moduleSymbol, _containingType); // We start without annotations var type = TypeWithAnnotations.Create(typeSymbol, customModifiers: customModifiersArray); // Decode nullable before tuple types to avoid converting between // NamedTypeSymbol and TupleTypeSymbol unnecessarily. type = NullableTypeDecoder.TransformType(type, _handle, moduleSymbol, accessSymbol: this, nullableContext: _containingType); type = TupleTypeDecoder.DecodeTupleTypesIfApplicable(type, _handle, moduleSymbol); RefKind refKind = fieldInfo.IsByRef ? moduleSymbol.Module.HasIsReadOnlyAttribute(_handle) ? RefKind.RefReadOnly : RefKind.Ref : RefKind.None; _packedFlags.SetRefKind(refKind); _packedFlags.SetIsVolatile(customModifiersArray.Any(static m => !m.IsOptional && ((CSharpCustomModifier)m).ModifierSymbol.SpecialType == SpecialType.System_Runtime_CompilerServices_IsVolatile));
private static TypeSymbol TransformType(TypeSymbol type, ImmutableArray <bool> transformFlags) { var decoder = new NativeIntegerTypeDecoder(transformFlags); try { var result = decoder.TransformType(type); if (decoder._index == transformFlags.Length) { return(result); } } catch (ArgumentException) { } return(type); }
private void EnsureSignatureIsLoaded() { if (_lazyType == null) { var moduleSymbol = _containingType.ContainingPEModule; ImmutableArray <ModifierInfo <TypeSymbol> > customModifiers; TypeSymbol typeSymbol = (new MetadataDecoder(moduleSymbol, _containingType)).DecodeFieldSignature(_handle, out customModifiers); ImmutableArray <CustomModifier> customModifiersArray = CSharpCustomModifier.Convert(customModifiers); typeSymbol = DynamicTypeDecoder.TransformType(typeSymbol, customModifiersArray.Length, _handle, moduleSymbol); typeSymbol = NativeIntegerTypeDecoder.TransformType(typeSymbol, _handle, moduleSymbol, _containingType); // We start without annotations var type = TypeWithAnnotations.Create(typeSymbol, customModifiers: customModifiersArray); // Decode nullable before tuple types to avoid converting between // NamedTypeSymbol and TupleTypeSymbol unnecessarily. type = NullableTypeDecoder.TransformType(type, _handle, moduleSymbol, accessSymbol: this, nullableContext: _containingType); type = TupleTypeDecoder.DecodeTupleTypesIfApplicable(type, _handle, moduleSymbol); _lazyIsVolatile = customModifiersArray.Any(static m => !m.IsOptional && ((CSharpCustomModifier)m).ModifierSymbol.SpecialType == SpecialType.System_Runtime_CompilerServices_IsVolatile);
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; } }
private PEParameterSymbol( PEModuleSymbol moduleSymbol, Symbol containingSymbol, int ordinal, bool isByRef, TypeWithAnnotations typeWithAnnotations, ParameterHandle handle, Symbol nullableContext, int countOfCustomModifiers, out bool isBad) { Debug.Assert((object)moduleSymbol != null); Debug.Assert((object)containingSymbol != null); Debug.Assert(ordinal >= 0); Debug.Assert(typeWithAnnotations.HasType); isBad = false; _moduleSymbol = moduleSymbol; _containingSymbol = containingSymbol; _ordinal = (ushort)ordinal; _handle = handle; RefKind refKind = RefKind.None; if (handle.IsNil) { refKind = isByRef ? RefKind.Ref : RefKind.None; byte?value = nullableContext.GetNullableContextValue(); if (value.HasValue) { typeWithAnnotations = NullableTypeDecoder.TransformType(typeWithAnnotations, value.GetValueOrDefault(), default); } _lazyCustomAttributes = ImmutableArray <CSharpAttributeData> .Empty; _lazyHiddenAttributes = ImmutableArray <CSharpAttributeData> .Empty; _lazyDefaultValue = ConstantValue.NotAvailable; _lazyIsParams = ThreeState.False; } else { try { moduleSymbol.Module.GetParamPropsOrThrow(handle, out _name, out _flags); } catch (BadImageFormatException) { isBad = true; } if (isByRef) { ParameterAttributes inOutFlags = _flags & (ParameterAttributes.Out | ParameterAttributes.In); if (inOutFlags == ParameterAttributes.Out) { refKind = RefKind.Out; } else if (moduleSymbol.Module.HasIsReadOnlyAttribute(handle)) { refKind = RefKind.In; } else { refKind = RefKind.Ref; } } var typeSymbol = DynamicTypeDecoder.TransformType(typeWithAnnotations.Type, countOfCustomModifiers, handle, moduleSymbol, refKind); typeSymbol = NativeIntegerTypeDecoder.TransformType(typeSymbol, handle, moduleSymbol); typeWithAnnotations = typeWithAnnotations.WithTypeAndModifiers(typeSymbol, typeWithAnnotations.CustomModifiers); // Decode nullable before tuple types to avoid converting between // NamedTypeSymbol and TupleTypeSymbol unnecessarily. // The containing type is passed to NullableTypeDecoder.TransformType to determine access // for property parameters because the property does not have explicit accessibility in metadata. var accessSymbol = containingSymbol.Kind == SymbolKind.Property ? containingSymbol.ContainingSymbol : containingSymbol; typeWithAnnotations = NullableTypeDecoder.TransformType(typeWithAnnotations, handle, moduleSymbol, accessSymbol: accessSymbol, nullableContext: nullableContext); typeWithAnnotations = TupleTypeDecoder.DecodeTupleTypesIfApplicable(typeWithAnnotations, handle, moduleSymbol); } _typeWithAnnotations = typeWithAnnotations; bool hasNameInMetadata = !string.IsNullOrEmpty(_name); if (!hasNameInMetadata) { // As was done historically, if the parameter doesn't have a name, we give it the name "value". _name = "value"; } _packedFlags = new PackedFlags(refKind, attributesAreComplete: handle.IsNil, hasNameInMetadata: hasNameInMetadata); Debug.Assert(refKind == this.RefKind); Debug.Assert(hasNameInMetadata == this.HasNameInMetadata); }
internal PEEventSymbol( PEModuleSymbol moduleSymbol, PENamedTypeSymbol containingType, EventDefinitionHandle handle, PEMethodSymbol addMethod, PEMethodSymbol removeMethod, MultiDictionary <string, PEFieldSymbol> privateFieldNameToSymbols) { RoslynDebug.Assert((object)moduleSymbol != null); RoslynDebug.Assert((object)containingType != null); Debug.Assert(!handle.IsNil); RoslynDebug.Assert((object)addMethod != null); RoslynDebug.Assert((object)removeMethod != null); _addMethod = addMethod; _removeMethod = removeMethod; _handle = handle; _containingType = containingType; EventAttributes mdFlags = 0; EntityHandle eventType = default(EntityHandle); try { var module = moduleSymbol.Module; module.GetEventDefPropsOrThrow(handle, out _name, out mdFlags, out eventType); } catch (BadImageFormatException mrEx) { _name = _name ?? string.Empty; _lazyCachedUseSiteInfo.Initialize(new CSDiagnosticInfo(ErrorCode.ERR_BindToBogus, this)); if (eventType.IsNil) { _eventTypeWithAnnotations = TypeWithAnnotations.Create(new UnsupportedMetadataTypeSymbol(mrEx)); } } TypeSymbol originalEventType = _eventTypeWithAnnotations.Type; if (!_eventTypeWithAnnotations.HasType) { var metadataDecoder = new MetadataDecoder(moduleSymbol, containingType); originalEventType = metadataDecoder.GetTypeOfToken(eventType); const int targetSymbolCustomModifierCount = 0; var typeSymbol = DynamicTypeDecoder.TransformType(originalEventType, targetSymbolCustomModifierCount, handle, moduleSymbol); typeSymbol = NativeIntegerTypeDecoder.TransformType(typeSymbol, handle, moduleSymbol, _containingType); // We start without annotation (they will be decoded below) var type = TypeWithAnnotations.Create(typeSymbol); // 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 event does not have explicit accessibility in metadata. type = NullableTypeDecoder.TransformType(type, handle, moduleSymbol, accessSymbol: _containingType, nullableContext: _containingType); type = TupleTypeDecoder.DecodeTupleTypesIfApplicable(type, handle, moduleSymbol); _eventTypeWithAnnotations = type; } // IsWindowsRuntimeEvent checks the signatures, so we just have to check the accessors. bool isWindowsRuntimeEvent = IsWindowsRuntimeEvent; bool callMethodsDirectly = isWindowsRuntimeEvent ? !DoModifiersMatch(_addMethod, _removeMethod) : !DoSignaturesMatch(moduleSymbol, originalEventType, _addMethod, _removeMethod); if (callMethodsDirectly) { _flags |= Flags.CallMethodsDirectly; } else { _addMethod.SetAssociatedEvent(this, MethodKind.EventAdd); _removeMethod.SetAssociatedEvent(this, MethodKind.EventRemove); PEFieldSymbol?associatedField = GetAssociatedField(privateFieldNameToSymbols, isWindowsRuntimeEvent); if ((object?)associatedField != null) { _associatedFieldOpt = associatedField; associatedField.SetAssociatedEvent(this); } } if ((mdFlags & EventAttributes.SpecialName) != 0) { _flags |= Flags.IsSpecialName; } if ((mdFlags & EventAttributes.RTSpecialName) != 0) { _flags |= Flags.IsRuntimeSpecialName; } }