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)); }