internal static InstanceProvider?ForMethod( Compilation compilation, AttributedMembers attrMembers, DeserializerTypes types, Location?loc, INamedTypeSymbol rowType, INamedTypeSymbol hostType, string mtdName, ref ImmutableArray <Diagnostic> diags ) { var instanceProviderMtd = Utils.GetMethod(hostType, mtdName, loc, ref diags); if (instanceProviderMtd == null) { return(null); } var instanceProviderLoc = instanceProviderMtd.Locations.FirstOrDefault(); var methodReturnType = instanceProviderMtd.ReturnType; if (methodReturnType.SpecialType != SpecialType.System_Boolean) { var diag = Diagnostics.MethodMustReturnBool(instanceProviderLoc, instanceProviderMtd); diags = diags.Add(diag); return(null); } if (!instanceProviderMtd.IsStatic) { var diag = Diagnostics.MethodNotStatic(instanceProviderLoc, instanceProviderMtd); diags = diags.Add(diag); return(null); } var accessible = instanceProviderMtd.IsAccessible(attrMembers); if (!accessible) { var diag = Diagnostics.MethodNotPublicOrInternal(instanceProviderLoc, instanceProviderMtd); diags = diags.Add(diag); return(null); } var ps = instanceProviderMtd.Parameters; if (ps.Length != 2) { var diag = Diagnostics.BadInstanceProviderParameters(instanceProviderLoc, instanceProviderMtd); diags = diags.Add(diag); return(null); } var p0 = ps[0]; if (!p0.IsInReadContext(types.OurTypes)) { var diag = Diagnostics.BadInstanceProviderParameters(instanceProviderLoc, instanceProviderMtd); diags = diags.Add(diag); return(null); } var p1 = ps[1]; if (p1.RefKind != RefKind.Out) { var diag = Diagnostics.BadInstanceProviderParameters(instanceProviderLoc, instanceProviderMtd); diags = diags.Add(diag); return(null); } var conversion = compilation.ClassifyConversion(p1.Type, rowType); var canConvert = conversion.IsImplicit || conversion.IsIdentity; if (!canConvert) { var diag = Diagnostics.BadInstanceProviderParameters(instanceProviderLoc, instanceProviderMtd); diags = diags.Add(diag); return(null); } return(new InstanceProvider(false, instanceProviderMtd, p1.Type)); }
private static Parser?GetParser( Compilation compilation, AttributedMembers attrMembers, DeserializerTypes types, ITypeSymbol toParseType, Location?location, ImmutableArray <AttributeSyntax> attrs, ref ImmutableArray <Diagnostic> diags ) { var parser = Utils.GetMethodFromAttribute( attrMembers, "ParserType", Diagnostics.ParserTypeSpecifiedMultipleTimes, "ParserMethodName", Diagnostics.ParserMethodNameSpecifiedMultipleTimes, Diagnostics.ParserBothMustBeSet, location, attrs, ref diags ); if (parser == null) { return(null); } var(type, name) = parser.Value; var parserMtd = Utils.GetMethod(type, name, location, ref diags); if (parserMtd == null) { return(null); } var methodReturnType = parserMtd.ReturnType; if (methodReturnType.SpecialType != SpecialType.System_Boolean) { var diag = Diagnostics.MethodMustReturnBool(location, parserMtd); diags = diags.Add(diag); return(null); } if (!parserMtd.IsStatic) { var diag = Diagnostics.MethodNotStatic(location, parserMtd); diags = diags.Add(diag); return(null); } var accessible = parserMtd.IsAccessible(attrMembers); if (!accessible) { var diag = Diagnostics.MethodNotPublicOrInternal(location, parserMtd); diags = diags.Add(diag); return(null); } var ps = parserMtd.Parameters; if (ps.Length != 3) { var diag = Diagnostics.BadParserParameters(location, parserMtd); diags = diags.Add(diag); return(null); } // Parameters // * ReadOnlySpan(char) // * in ReadContext, // * out assignable to outputType var p0 = ps[0]; if (!p0.IsNormalParameterOfType(compilation, types.Framework.ReadOnlySpanOfChar)) { var diag = Diagnostics.BadParserParameters(location, parserMtd); diags = diags.Add(diag); return(null); } var p1 = ps[1]; if (!p1.IsInReadContext(types.OurTypes)) { var diag = Diagnostics.BadParserParameters(location, parserMtd); diags = diags.Add(diag); return(null); } var p2 = ps[2]; if (p2.RefKind != RefKind.Out) { var diag = Diagnostics.BadParserParameters(location, parserMtd); diags = diags.Add(diag); return(null); } var conversion = compilation.ClassifyConversion(p2.Type, toParseType); var canConvert = conversion.IsImplicit || conversion.IsIdentity; if (!canConvert) { var diag = Diagnostics.BadParserParameters(location, parserMtd); diags = diags.Add(diag); return(null); } return(new Parser(parserMtd, p2.Type)); }
private static Formatter?GetFormatter( Compilation compilation, AttributedMembers attrMembers, SerializerTypes types, ITypeSymbol toFormatType, Location?location, ImmutableArray <AttributeSyntax> attrs, ref ImmutableArray <Diagnostic> diags ) { var formatter = Utils.GetMethodFromAttribute( attrMembers, "FormatterType", Diagnostics.FormatterTypeSpecifiedMultipleTimes, "FormatterMethodName", Diagnostics.FormatterMethodNameSpecifiedMultipleTimes, Diagnostics.FormatterBothMustBeSet, location, attrs, ref diags ); if (formatter == null) { return(null); } var(type, mtd) = formatter.Value; var formatterMtd = Utils.GetMethod(type, mtd, location, ref diags); if (formatterMtd == null) { return(null); } if (formatterMtd.IsGenericMethod) { var diag = Diagnostics.MethodCannotBeGeneric(location, formatterMtd); diags = diags.Add(diag); return(null); } var accessible = formatterMtd.IsAccessible(attrMembers); if (!accessible) { var diag = Diagnostics.MethodNotPublicOrInternal(location, formatterMtd); diags = diags.Add(diag); return(null); } if (!formatterMtd.IsStatic) { var diag = Diagnostics.MethodNotStatic(location, formatterMtd); diags = diags.Add(diag); return(null); } if (!formatterMtd.ReturnType.Equals(types.BuiltIn.Bool, SymbolEqualityComparer.Default)) { var diag = Diagnostics.MethodMustReturnBool(location, formatterMtd); diags = diags.Add(diag); return(null); } var formatterParams = formatterMtd.Parameters; if (formatterParams.Length != 3) { var diag = Diagnostics.BadFormatterParameters(location, formatterMtd, toFormatType); diags = diags.Add(diag); return(null); } var p0 = formatterParams[0]; if (!p0.IsNormalParameterOfType(compilation, toFormatType)) { var diag = Diagnostics.BadFormatterParameters(location, formatterMtd, toFormatType); diags = diags.Add(diag); return(null); } var p1 = formatterParams[1]; if (!p1.IsInWriteContext(types.OurTypes)) { var diag = Diagnostics.BadFormatterParameters(location, formatterMtd, toFormatType); diags = diags.Add(diag); return(null); } var p2 = formatterParams[2]; if (!p2.IsNormalParameterOfType(compilation, types.Framework.IBufferWriterOfChar)) { var diag = Diagnostics.BadFormatterParameters(location, formatterMtd, toFormatType); diags = diags.Add(diag); return(null); } return(new Formatter(formatterMtd, toFormatType)); }