internal override int GetTargetAttributeSignatureIndex(Symbol targetSymbol, AttributeDescription description) { if (!IsTargetAttribute(description.Namespace, description.Name)) { return(-1); } var ctor = this.AttributeConstructor; // Ensure that the attribute data really has a constructor before comparing the signature. if (ctor is null) { return(-1); } // Lazily loaded System.Type type symbol TypeSymbol?lazySystemType = null; ImmutableArray <ParameterSymbol> parameters = ctor.Parameters; bool foundMatch = false; for (int i = 0; i < description.Signatures.Length; i++) { byte[] targetSignature = description.Signatures[i]; if (targetSignature[0] != (byte)SignatureAttributes.Instance) { continue; } byte parameterCount = targetSignature[1]; if (parameterCount != parameters.Length) { continue; } if ((SignatureTypeCode)targetSignature[2] != SignatureTypeCode.Void) { continue; } foundMatch = (targetSignature.Length == 3); int k = 0; for (int j = 3; j < targetSignature.Length; j++) { if (k >= parameters.Length) { break; } TypeSymbol parameterType = parameters[k].Type; SpecialType specType = parameterType.SpecialType; byte targetType = targetSignature[j]; if (targetType == (byte)SignatureTypeCode.TypeHandle) { j++; if (parameterType.Kind != SymbolKind.NamedType && parameterType.Kind != SymbolKind.ErrorType) { foundMatch = false; break; } var namedType = (NamedTypeSymbol)parameterType; AttributeDescription.TypeHandleTargetInfo targetInfo = AttributeDescription.TypeHandleTargets[targetSignature[j]]; // Compare name and containing symbol name. Uses HasNameQualifier // extension method to avoid string allocations. if (!string.Equals(namedType.MetadataName, targetInfo.Name, System.StringComparison.Ordinal) || !namedType.HasNameQualifier(targetInfo.Namespace)) { foundMatch = false; break; } targetType = (byte)targetInfo.Underlying; if (parameterType.IsEnumType()) { specType = parameterType.GetEnumUnderlyingType() !.SpecialType; } } else if (parameterType.IsArray()) { specType = ((ArrayTypeSymbol)parameterType).ElementType.SpecialType; } switch (targetType) { case (byte)SignatureTypeCode.Boolean: foundMatch = specType == SpecialType.System_Boolean; k += 1; break; case (byte)SignatureTypeCode.Char: foundMatch = specType == SpecialType.System_Char; k += 1; break; case (byte)SignatureTypeCode.SByte: foundMatch = specType == SpecialType.System_SByte; k += 1; break; case (byte)SignatureTypeCode.Byte: foundMatch = specType == SpecialType.System_Byte; k += 1; break; case (byte)SignatureTypeCode.Int16: foundMatch = specType == SpecialType.System_Int16; k += 1; break; case (byte)SignatureTypeCode.UInt16: foundMatch = specType == SpecialType.System_UInt16; k += 1; break; case (byte)SignatureTypeCode.Int32: foundMatch = specType == SpecialType.System_Int32; k += 1; break; case (byte)SignatureTypeCode.UInt32: foundMatch = specType == SpecialType.System_UInt32; k += 1; break; case (byte)SignatureTypeCode.Int64: foundMatch = specType == SpecialType.System_Int64; k += 1; break; case (byte)SignatureTypeCode.UInt64: foundMatch = specType == SpecialType.System_UInt64; k += 1; break; case (byte)SignatureTypeCode.Single: foundMatch = specType == SpecialType.System_Single; k += 1; break; case (byte)SignatureTypeCode.Double: foundMatch = specType == SpecialType.System_Double; k += 1; break; case (byte)SignatureTypeCode.String: foundMatch = specType == SpecialType.System_String; k += 1; break; case (byte)SignatureTypeCode.Object: foundMatch = specType == SpecialType.System_Object; k += 1; break; case (byte)SerializationTypeCode.Type: if (lazySystemType is null) { lazySystemType = GetSystemType(targetSymbol); } foundMatch = TypeSymbol.Equals(parameterType, lazySystemType, TypeCompareKind.ConsiderEverything2); k += 1; break; case (byte)SignatureTypeCode.SZArray: // Skip over and check the next byte foundMatch = parameterType.IsArray(); break; default: return(-1); } if (!foundMatch) { break; } } if (foundMatch) { return(i); } } Debug.Assert(!foundMatch); return(-1); }
internal override int GetTargetAttributeSignatureIndex(Symbol targetSymbol, AttributeDescription description) { if (!IsTargetAttribute(description.Namespace, description.Name)) { return(-1); } var ctor = this.AttributeConstructor; // Ensure that the attribute data really has a constructor before comparing the signature. if (ctor is null) { return(-1); } // Lazily loaded System.Type type symbol TypeSymbol?lazySystemType = null; ImmutableArray <ParameterSymbol> parameters = ctor.Parameters; for (int signatureIndex = 0; signatureIndex < description.Signatures.Length; signatureIndex++) { byte[] targetSignature = description.Signatures[signatureIndex]; if (matches(targetSignature, parameters, ref lazySystemType)) { return(signatureIndex); } } return(-1); bool matches(byte[] targetSignature, ImmutableArray <ParameterSymbol> parameters, ref TypeSymbol?lazySystemType) { if (targetSignature[0] != (byte)SignatureAttributes.Instance) { return(false); } byte parameterCount = targetSignature[1]; if (parameterCount != parameters.Length) { return(false); } if ((SignatureTypeCode)targetSignature[2] != SignatureTypeCode.Void) { return(false); } int parameterIndex = 0; for (int signatureByteIndex = 3; signatureByteIndex < targetSignature.Length; signatureByteIndex++) { if (parameterIndex >= parameters.Length) { return(false); } TypeSymbol parameterType = parameters[parameterIndex].Type; SpecialType specType = parameterType.SpecialType; byte targetType = targetSignature[signatureByteIndex]; if (targetType == (byte)SignatureTypeCode.TypeHandle) { signatureByteIndex++; if (parameterType.Kind != SymbolKind.NamedType && parameterType.Kind != SymbolKind.ErrorType) { return(false); } var namedType = (NamedTypeSymbol)parameterType; AttributeDescription.TypeHandleTargetInfo targetInfo = AttributeDescription.TypeHandleTargets[targetSignature[signatureByteIndex]]; // Compare name and containing symbol name. Uses HasNameQualifier // extension method to avoid string allocations. if (!string.Equals(namedType.MetadataName, targetInfo.Name, System.StringComparison.Ordinal) || !namedType.HasNameQualifier(targetInfo.Namespace)) { return(false); } targetType = (byte)targetInfo.Underlying; if (parameterType.IsEnumType()) { specType = parameterType.GetEnumUnderlyingType() !.SpecialType; } } else if (targetType != (byte)SignatureTypeCode.SZArray && parameterType.IsArray()) { if (targetSignature[signatureByteIndex - 1] != (byte)SignatureTypeCode.SZArray) { return(false); } specType = ((ArrayTypeSymbol)parameterType).ElementType.SpecialType; } switch (targetType) { case (byte)SignatureTypeCode.Boolean: if (specType != SpecialType.System_Boolean) { return(false); } parameterIndex += 1; break; case (byte)SignatureTypeCode.Char: if (specType != SpecialType.System_Char) { return(false); } parameterIndex += 1; break; case (byte)SignatureTypeCode.SByte: if (specType != SpecialType.System_SByte) { return(false); } parameterIndex += 1; break; case (byte)SignatureTypeCode.Byte: if (specType != SpecialType.System_Byte) { return(false); } parameterIndex += 1; break; case (byte)SignatureTypeCode.Int16: if (specType != SpecialType.System_Int16) { return(false); } parameterIndex += 1; break; case (byte)SignatureTypeCode.UInt16: if (specType != SpecialType.System_UInt16) { return(false); } parameterIndex += 1; break; case (byte)SignatureTypeCode.Int32: if (specType != SpecialType.System_Int32) { return(false); } parameterIndex += 1; break; case (byte)SignatureTypeCode.UInt32: if (specType != SpecialType.System_UInt32) { return(false); } parameterIndex += 1; break; case (byte)SignatureTypeCode.Int64: if (specType != SpecialType.System_Int64) { return(false); } parameterIndex += 1; break; case (byte)SignatureTypeCode.UInt64: if (specType != SpecialType.System_UInt64) { return(false); } parameterIndex += 1; break; case (byte)SignatureTypeCode.Single: if (specType != SpecialType.System_Single) { return(false); } parameterIndex += 1; break; case (byte)SignatureTypeCode.Double: if (specType != SpecialType.System_Double) { return(false); } parameterIndex += 1; break; case (byte)SignatureTypeCode.String: if (specType != SpecialType.System_String) { return(false); } parameterIndex += 1; break; case (byte)SignatureTypeCode.Object: if (specType != SpecialType.System_Object) { return(false); } parameterIndex += 1; break; case (byte)SerializationTypeCode.Type: lazySystemType ??= GetSystemType(targetSymbol); if (!TypeSymbol.Equals(parameterType, lazySystemType, TypeCompareKind.ConsiderEverything)) { return(false); } parameterIndex += 1; break; case (byte)SignatureTypeCode.SZArray: // Skip over and check the next byte if (!parameterType.IsArray()) { return(false); } break; default: return(false); } } return(true); } }