private static void DecodeMarshalAsCustom(ref DecodeWellKnownAttributeArguments <TAttributeSyntax, TAttributeData, TAttributeLocation> arguments, CommonMessageProvider messageProvider) { Debug.Assert((object)arguments.AttributeSyntaxOpt != null); ITypeSymbol typeSymbol = null; string typeName = null; string cookie = null; bool hasTypeName = false; bool hasTypeSymbol = false; bool hasErrors = false; int position = 1; foreach (var namedArg in arguments.Attribute.NamedArguments) { switch (namedArg.Key) { case "MarshalType": typeName = namedArg.Value.DecodeValue <string>(SpecialType.System_String); if (!MetadataHelpers.IsValidUnicodeString(typeName)) { messageProvider.ReportInvalidNamedArgument(arguments.Diagnostics, arguments.AttributeSyntaxOpt, position, arguments.Attribute.AttributeClass, namedArg.Key); hasErrors = true; } hasTypeName = true; // even if MarshalType == null break; case "MarshalTypeRef": typeSymbol = namedArg.Value.DecodeValue <ITypeSymbol>(SpecialType.None); hasTypeSymbol = true; // even if MarshalTypeRef == null break; case "MarshalCookie": cookie = namedArg.Value.DecodeValue <string>(SpecialType.System_String); if (!MetadataHelpers.IsValidUnicodeString(cookie)) { messageProvider.ReportInvalidNamedArgument(arguments.Diagnostics, arguments.AttributeSyntaxOpt, position, arguments.Attribute.AttributeClass, namedArg.Key); hasErrors = true; } break; // other parameters ignored with no error } position++; } if (!hasTypeName && !hasTypeSymbol) { // MarshalType or MarshalTypeRef must be specified: messageProvider.ReportAttributeParameterRequired(arguments.Diagnostics, arguments.AttributeSyntaxOpt, "MarshalType", "MarshalTypeRef"); hasErrors = true; } if (!hasErrors) { arguments.GetOrCreateData <TWellKnownAttributeData>().GetOrCreateData().SetMarshalAsCustom(hasTypeName ? (object)typeName : typeSymbol, cookie); } }
private static void DecodeMarshalAsFixedString(ref DecodeWellKnownAttributeArguments <TAttributeSyntax, TAttributeData, TAttributeLocation> arguments, CommonMessageProvider messageProvider) { Debug.Assert((object)arguments.AttributeSyntaxOpt != null); int elementCount = -1; int position = 1; bool hasErrors = false; foreach (var namedArg in arguments.Attribute.NamedArguments) { switch (namedArg.Key) { case "SizeConst": elementCount = namedArg.Value.DecodeValue <int>(SpecialType.System_Int32); if (elementCount < 0 || elementCount > MarshalPseudoCustomAttributeData.MaxMarshalInteger) { messageProvider.ReportInvalidNamedArgument(arguments.Diagnostics, arguments.AttributeSyntaxOpt, position, arguments.Attribute.AttributeClass, namedArg.Key); hasErrors = true; } break; case "ArraySubType": case "SizeParamIndex": messageProvider.ReportParameterNotValidForType(arguments.Diagnostics, arguments.AttributeSyntaxOpt, position); hasErrors = true; break; // other parameters ignored with no error } position++; } if (elementCount < 0) { // SizeConst must be specified: messageProvider.ReportAttributeParameterRequired(arguments.Diagnostics, arguments.AttributeSyntaxOpt, "SizeConst"); hasErrors = true; } if (!hasErrors) { arguments.GetOrCreateData <TWellKnownAttributeData>().GetOrCreateData().SetMarshalAsFixedString(elementCount); } }