diff --git a/AutoInterfaceSample/Program.cs b/AutoInterfaceSample/Program.cs index 0bfc0ed..b672239 100644 --- a/AutoInterfaceSample/Program.cs +++ b/AutoInterfaceSample/Program.cs @@ -13,60 +13,41 @@ public static void Main() //p.Method(1, out f, ref g, "t", 1, 2, 3); IPrintableComplex p = new Person2(); - //p.Print(); + p.Print(); p.PrintComplex(); } } interface IPrintableComplex { - [Obsolete("ok", false)] void Print(); void PrintComplex(); - - [Obsolete("12")] - int Count - { - get; - [Obsolete("ok3")] - set; - } - - int Count2 - { - //[Obsolete("cd2")] - get; - } - - [Obsolete("cd")] - int this[int a] - { - [Obsolete("cd3")] - get; - } } - public class SimplePrinter + public class SimplePrinter //: IPrintableComplex { public void Print() { Console.WriteLine("OK"); } - public void PrintComplex() { Console.WriteLine("OK2"); } - - public int Count - { - get; - set; - } - - public int Count2 => 10; - public int this[int a] => 10; + public void PrintComplex() { Console.WriteLine("OKC"); } } - public partial class Person2 : IPrintableComplex + public partial class Person2 //: IPrintableComplex { - [BeaKona.AutoInterface(typeof(IPrintableComplex), AllowMissingMembers = false)] - private readonly SimplePrinter aspect1 = new SimplePrinter(); + //[BeaKona.AutoInterface(typeof(IPrintableComplex), AllowMissingMembers = true, MemberMatch = BeaKona.MemberMatchTypes.Public)] + //private readonly SimplePrinter aspect1 = new SimplePrinter(); + + //[BeaKona.AutoInterface(typeof(IPrintableComplex), AllowMissingMembers = true, MemberMatch = BeaKona.MemberMatchTypes.Explicit)] + //private readonly SimplePrinter aspect2 = new SimplePrinter(); + + [BeaKona.AutoInterface(typeof(IPrintableComplex), AllowMissingMembers = true)] + private readonly SimplePrinter aspect3 = new SimplePrinter(); + + //[BeaKona.AutoInterface(typeof(IPrintableComplex), AllowMissingMembers = true, MemberMatch = BeaKona.MemberMatchTypes.Any)] + //private readonly SimplePrinter aspect4 = new SimplePrinter(); + + //void IPrintableComplex.PrintComplex() => Console.WriteLine("OKC2"); public void PrintComplex() { Console.WriteLine("Oh, K."); } + //void IPrintableComplex.PrintComplex() { Console.WriteLine("Oh, K."); } } diff --git a/BeaKona.AutoInterfaceAttributes/AutoInterfaceAttribute.cs b/BeaKona.AutoInterfaceAttributes/AutoInterfaceAttribute.cs index c3b7905..aa1817e 100644 --- a/BeaKona.AutoInterfaceAttributes/AutoInterfaceAttribute.cs +++ b/BeaKona.AutoInterfaceAttributes/AutoInterfaceAttribute.cs @@ -23,4 +23,5 @@ public AutoInterfaceAttribute(Type type) public string? TemplateBody { get; set; } public string? TemplateFileName { get; set; } public bool AllowMissingMembers { get; set; } + public MemberMatchTypes MemberMatch { get; set; } } diff --git a/BeaKona.AutoInterfaceAttributes/MemberMatchTypes.cs b/BeaKona.AutoInterfaceAttributes/MemberMatchTypes.cs new file mode 100644 index 0000000..bb0b219 --- /dev/null +++ b/BeaKona.AutoInterfaceAttributes/MemberMatchTypes.cs @@ -0,0 +1,8 @@ +namespace BeaKona; + +public enum MemberMatchTypes +{ + Explicit, + Public, + Any, +} diff --git a/BeaKona.AutoInterfaceGenerator/AutoInterfaceRecord.cs b/BeaKona.AutoInterfaceGenerator/AutoInterfaceRecord.cs index b83e8db..9cfb309 100644 --- a/BeaKona.AutoInterfaceGenerator/AutoInterfaceRecord.cs +++ b/BeaKona.AutoInterfaceGenerator/AutoInterfaceRecord.cs @@ -4,7 +4,7 @@ namespace BeaKona.AutoInterfaceGenerator; internal sealed class AutoInterfaceRecord : IMemberInfo { - public AutoInterfaceRecord(ISymbol member, ITypeSymbol receiverType, INamedTypeSymbol interfaceType, TemplateDefinition? template, List templateParts, bool bySignature, bool preferCoalesce, bool allowMissingMembers) + public AutoInterfaceRecord(ISymbol member, ITypeSymbol receiverType, INamedTypeSymbol interfaceType, TemplateDefinition? template, List templateParts, bool bySignature, bool preferCoalesce, bool allowMissingMembers, MemberMatchTypes memberMatch) { this.Member = member; this.ReceiverType = receiverType; @@ -14,6 +14,7 @@ public AutoInterfaceRecord(ISymbol member, ITypeSymbol receiverType, INamedTypeS this.BySignature = bySignature; this.PreferCoalesce = preferCoalesce; this.AllowMissingMembers = allowMissingMembers; + this.MemberMatch = memberMatch; } public ISymbol Member { get; } @@ -24,4 +25,5 @@ public AutoInterfaceRecord(ISymbol member, ITypeSymbol receiverType, INamedTypeS public bool BySignature { get; } public bool PreferCoalesce { get; } public bool AllowMissingMembers { get; } + public MemberMatchTypes MemberMatch { get; } } diff --git a/BeaKona.AutoInterfaceGenerator/AutoInterfaceSourceGenerator.cs b/BeaKona.AutoInterfaceGenerator/AutoInterfaceSourceGenerator.cs index 551a019..0f9e74c 100644 --- a/BeaKona.AutoInterfaceGenerator/AutoInterfaceSourceGenerator.cs +++ b/BeaKona.AutoInterfaceGenerator/AutoInterfaceSourceGenerator.cs @@ -54,7 +54,7 @@ public void Execute(GeneratorExecutionContext context) { if (property.IsWriteOnly) { - Helpers.ReportDiagnostic(context, "BK-AG06", nameof(AutoInterfaceResource.AG06_title), nameof(AutoInterfaceResource.AG06_message), nameof(AutoInterfaceResource.AG06_description), DiagnosticSeverity.Error, property, + Helpers.ReportDiagnostic(context, "BKAG06", nameof(AutoInterfaceResource.AG06_title), nameof(AutoInterfaceResource.AG06_message), nameof(AutoInterfaceResource.AG06_description), DiagnosticSeverity.Error, property, property.Name); continue; } @@ -71,21 +71,21 @@ public void Execute(GeneratorExecutionContext context) if (containingType.IsPartial() == false) { - Helpers.ReportDiagnostic(context, "BK-AG01", nameof(AutoInterfaceResource.AG01_title), nameof(AutoInterfaceResource.AG01_message), nameof(AutoInterfaceResource.AG01_description), DiagnosticSeverity.Error, containingType, + Helpers.ReportDiagnostic(context, "BKAG01", nameof(AutoInterfaceResource.AG01_title), nameof(AutoInterfaceResource.AG01_message), nameof(AutoInterfaceResource.AG01_description), DiagnosticSeverity.Error, containingType, containingType.ToDisplayString(SymbolDisplayFormat.CSharpErrorMessageFormat)); continue; } if (containingType.IsStatic) { - Helpers.ReportDiagnostic(context, "BK-AG02", nameof(AutoInterfaceResource.AG02_title), nameof(AutoInterfaceResource.AG02_message), nameof(AutoInterfaceResource.AG02_description), DiagnosticSeverity.Error, containingType, + Helpers.ReportDiagnostic(context, "BKAG02", nameof(AutoInterfaceResource.AG02_title), nameof(AutoInterfaceResource.AG02_message), nameof(AutoInterfaceResource.AG02_description), DiagnosticSeverity.Error, containingType, containingType.ToDisplayString(SymbolDisplayFormat.CSharpErrorMessageFormat)); continue; } if (containingType.TypeKind != TypeKind.Class && containingType.TypeKind != TypeKind.Struct) { - Helpers.ReportDiagnostic(context, "BK-AG08", nameof(AutoInterfaceResource.AG08_title), nameof(AutoInterfaceResource.AG08_message), nameof(AutoInterfaceResource.AG08_description), DiagnosticSeverity.Error, recordsByContainingType.First().Member); + Helpers.ReportDiagnostic(context, "BKAG08", nameof(AutoInterfaceResource.AG08_title), nameof(AutoInterfaceResource.AG08_message), nameof(AutoInterfaceResource.AG08_description), DiagnosticSeverity.Error, recordsByContainingType.First().Member); continue; } @@ -104,7 +104,7 @@ public void Execute(GeneratorExecutionContext context) } catch (Exception ex) { - Helpers.ReportDiagnostic(context, "BK-AG09", nameof(AutoInterfaceResource.AG09_title), nameof(AutoInterfaceResource.AG09_message), nameof(AutoInterfaceResource.AG09_description), DiagnosticSeverity.Error, containingType, + Helpers.ReportDiagnostic(context, "BKAG09", nameof(AutoInterfaceResource.AG09_title), nameof(AutoInterfaceResource.AG09_message), nameof(AutoInterfaceResource.AG09_description), DiagnosticSeverity.Error, containingType, ex.ToString().Replace("\r", "").Replace("\n", "")); } } @@ -144,7 +144,7 @@ private static List CollectRecords(GeneratorExecutionContex { if (type is INamedTypeSymbol interfaceType) { - if (receiverType.IsMatchByTypeOrImplementsInterface(type)) + if (IsImplementedDirectly(receiverType, interfaceType)) { string? templateBody = null; string? templateFileName = null; @@ -198,7 +198,7 @@ private static List CollectRecords(GeneratorExecutionContex { if (templateFileName != null && templateFileName.Trim().Length > 0) { - Helpers.ReportDiagnostic(context, "BK-AG12", nameof(AutoInterfaceResource.AG12_title), nameof(AutoInterfaceResource.AG12_message), nameof(AutoInterfaceResource.AG12_description), DiagnosticSeverity.Error, attribute.ApplicationSyntaxReference?.GetSyntax() + Helpers.ReportDiagnostic(context, "BKAG12", nameof(AutoInterfaceResource.AG12_title), nameof(AutoInterfaceResource.AG12_message), nameof(AutoInterfaceResource.AG12_description), DiagnosticSeverity.Error, attribute.ApplicationSyntaxReference?.GetSyntax() ); continue; } @@ -212,7 +212,7 @@ private static List CollectRecords(GeneratorExecutionContex } catch { - Helpers.ReportDiagnostic(context, "BK-AG15", nameof(AutoInterfaceResource.AG15_title), nameof(AutoInterfaceResource.AG15_message), nameof(AutoInterfaceResource.AG15_description), DiagnosticSeverity.Error, attribute.ApplicationSyntaxReference?.GetSyntax(), + Helpers.ReportDiagnostic(context, "BKAG15", nameof(AutoInterfaceResource.AG15_title), nameof(AutoInterfaceResource.AG15_message), nameof(AutoInterfaceResource.AG15_description), DiagnosticSeverity.Error, attribute.ApplicationSyntaxReference?.GetSyntax(), memberFilter); continue; } @@ -237,7 +237,7 @@ private static List CollectRecords(GeneratorExecutionContex } else { - Helpers.ReportDiagnostic(context, "BK-AG11", nameof(AutoInterfaceResource.AG11_title), nameof(AutoInterfaceResource.AG11_message), nameof(AutoInterfaceResource.AG11_description), DiagnosticSeverity.Error, attribute.ApplicationSyntaxReference?.GetSyntax(), + Helpers.ReportDiagnostic(context, "BKAG11", nameof(AutoInterfaceResource.AG11_title), nameof(AutoInterfaceResource.AG11_message), nameof(AutoInterfaceResource.AG11_description), DiagnosticSeverity.Error, attribute.ApplicationSyntaxReference?.GetSyntax(), templateFileName); continue; } @@ -261,7 +261,7 @@ private static List CollectRecords(GeneratorExecutionContex } catch { - Helpers.ReportDiagnostic(context, "BK-AG15", nameof(AutoInterfaceResource.AG15_title), nameof(AutoInterfaceResource.AG15_message), nameof(AutoInterfaceResource.AG15_description), DiagnosticSeverity.Error, attribute.ApplicationSyntaxReference?.GetSyntax(), + Helpers.ReportDiagnostic(context, "BKAG15", nameof(AutoInterfaceResource.AG15_title), nameof(AutoInterfaceResource.AG15_message), nameof(AutoInterfaceResource.AG15_description), DiagnosticSeverity.Error, attribute.ApplicationSyntaxReference?.GetSyntax(), memberFilter); continue; } @@ -277,28 +277,28 @@ private static List CollectRecords(GeneratorExecutionContex } else { - Helpers.ReportDiagnostic(context, "BK-AG14", nameof(AutoInterfaceResource.AG14_title), nameof(AutoInterfaceResource.AG14_message), nameof(AutoInterfaceResource.AG14_description), DiagnosticSeverity.Error, attribute.ApplicationSyntaxReference?.GetSyntax() + Helpers.ReportDiagnostic(context, "BKAG14", nameof(AutoInterfaceResource.AG14_title), nameof(AutoInterfaceResource.AG14_message), nameof(AutoInterfaceResource.AG14_description), DiagnosticSeverity.Error, attribute.ApplicationSyntaxReference?.GetSyntax() ); continue; } } else { - Helpers.ReportDiagnostic(context, "BK-AG04", nameof(AutoInterfaceResource.AG04_title), nameof(AutoInterfaceResource.AG04_message), nameof(AutoInterfaceResource.AG04_description), DiagnosticSeverity.Error, attribute.ApplicationSyntaxReference?.GetSyntax(), + Helpers.ReportDiagnostic(context, "BKAG04", nameof(AutoInterfaceResource.AG04_title), nameof(AutoInterfaceResource.AG04_message), nameof(AutoInterfaceResource.AG04_description), DiagnosticSeverity.Error, attribute.ApplicationSyntaxReference?.GetSyntax(), receiverType.ToDisplayString(SymbolDisplayFormat.CSharpErrorMessageFormat), type.ToDisplayString(SymbolDisplayFormat.CSharpErrorMessageFormat)); continue; } } else { - Helpers.ReportDiagnostic(context, "BK-AG09", nameof(AutoInterfaceResource.AG09_title), nameof(AutoInterfaceResource.AG09_message), nameof(AutoInterfaceResource.AG09_description), DiagnosticSeverity.Error, attribute.ApplicationSyntaxReference?.GetSyntax(), + Helpers.ReportDiagnostic(context, "BKAG09", nameof(AutoInterfaceResource.AG09_title), nameof(AutoInterfaceResource.AG09_message), nameof(AutoInterfaceResource.AG09_description), DiagnosticSeverity.Error, attribute.ApplicationSyntaxReference?.GetSyntax(), 157834); continue; } } else { - Helpers.ReportDiagnostic(context, "BK-AG03", nameof(AutoInterfaceResource.AG03_title), nameof(AutoInterfaceResource.AG03_message), nameof(AutoInterfaceResource.AG03_description), DiagnosticSeverity.Error, attribute.ApplicationSyntaxReference?.GetSyntax(), + Helpers.ReportDiagnostic(context, "BKAG03", nameof(AutoInterfaceResource.AG03_title), nameof(AutoInterfaceResource.AG03_message), nameof(AutoInterfaceResource.AG03_description), DiagnosticSeverity.Error, attribute.ApplicationSyntaxReference?.GetSyntax(), type.ToDisplayString(SymbolDisplayFormat.CSharpErrorMessageFormat)); continue; } @@ -315,6 +315,7 @@ private static List CollectRecords(GeneratorExecutionContex bool? includeBaseInterfaces = null; bool? preferCoalesce = null; bool? allowMissingMembers = null; + MemberMatchTypes? memberMatch = null; if (attribute.ConstructorArguments.Length == 0) { @@ -330,7 +331,7 @@ private static List CollectRecords(GeneratorExecutionContex if (type == null) { - Helpers.ReportDiagnostic(context, "BK-AG07", nameof(AutoInterfaceResource.AG07_title), nameof(AutoInterfaceResource.AG07_message), nameof(AutoInterfaceResource.AG07_description), DiagnosticSeverity.Error, attribute.ApplicationSyntaxReference?.GetSyntax()); + Helpers.ReportDiagnostic(context, "BKAG07", nameof(AutoInterfaceResource.AG07_title), nameof(AutoInterfaceResource.AG07_message), nameof(AutoInterfaceResource.AG07_description), DiagnosticSeverity.Error, attribute.ApplicationSyntaxReference?.GetSyntax()); continue; } else if (type.TypeKind == TypeKind.Interface) @@ -395,6 +396,14 @@ private static List CollectRecords(GeneratorExecutionContex } } break; + case nameof(AutoInterfaceAttribute.MemberMatch): + { + if (arg.Value.Value is object value) + { + memberMatch = (MemberMatchTypes)Convert.ChangeType(value, typeof(MemberMatchTypes).GetEnumUnderlyingType()); + } + } + break; } } @@ -405,7 +414,7 @@ private static List CollectRecords(GeneratorExecutionContex { if (templateFileName != null && templateFileName.Trim().Length > 0) { - Helpers.ReportDiagnostic(context, "BK-AG12", nameof(AutoInterfaceResource.AG12_title), nameof(AutoInterfaceResource.AG12_message), nameof(AutoInterfaceResource.AG12_description), DiagnosticSeverity.Error, attribute.ApplicationSyntaxReference?.GetSyntax() + Helpers.ReportDiagnostic(context, "BKAG12", nameof(AutoInterfaceResource.AG12_title), nameof(AutoInterfaceResource.AG12_message), nameof(AutoInterfaceResource.AG12_description), DiagnosticSeverity.Error, attribute.ApplicationSyntaxReference?.GetSyntax() ); continue; } @@ -423,7 +432,7 @@ private static List CollectRecords(GeneratorExecutionContex } else { - Helpers.ReportDiagnostic(context, "BK-AG11", nameof(AutoInterfaceResource.AG11_title), nameof(AutoInterfaceResource.AG11_message), nameof(AutoInterfaceResource.AG11_description), DiagnosticSeverity.Error, attribute.ApplicationSyntaxReference?.GetSyntax(), + Helpers.ReportDiagnostic(context, "BKAG11", nameof(AutoInterfaceResource.AG11_title), nameof(AutoInterfaceResource.AG11_message), nameof(AutoInterfaceResource.AG11_description), DiagnosticSeverity.Error, attribute.ApplicationSyntaxReference?.GetSyntax(), templateFileName); continue; } @@ -440,7 +449,7 @@ private static List CollectRecords(GeneratorExecutionContex if (templateParts.Count > 0) { - Helpers.ReportDiagnostic(context, "BK-AG13", nameof(AutoInterfaceResource.AG13_title), nameof(AutoInterfaceResource.AG13_message), nameof(AutoInterfaceResource.AG13_description), DiagnosticSeverity.Error, attribute.ApplicationSyntaxReference?.GetSyntax() + Helpers.ReportDiagnostic(context, "BKAG13", nameof(AutoInterfaceResource.AG13_title), nameof(AutoInterfaceResource.AG13_message), nameof(AutoInterfaceResource.AG13_description), DiagnosticSeverity.Error, attribute.ApplicationSyntaxReference?.GetSyntax() ); continue; } @@ -451,49 +460,50 @@ private static List CollectRecords(GeneratorExecutionContex includeBaseInterfaces ??= false; preferCoalesce ??= true; allowMissingMembers ??= false; + memberMatch ??= MemberMatchTypes.Explicit; if (IsImplementedDirectly(receiverType, type)) { danglingInterfaceTypesBySymbols.Remove(symbol); - records.Add(new AutoInterfaceRecord(symbol, receiverType, interfaceType, template, templateParts, false, preferCoalesce.Value, allowMissingMembers.Value)); + records.Add(new AutoInterfaceRecord(symbol, receiverType, interfaceType, template, templateParts, false, preferCoalesce.Value, allowMissingMembers.Value, memberMatch.Value)); if (includeBaseInterfaces.Value) { foreach (INamedTypeSymbol baseInterfaceType in interfaceType.AllInterfaces) { - records.Add(new AutoInterfaceRecord(symbol, receiverType, baseInterfaceType, template, templateParts, false, preferCoalesce.Value, allowMissingMembers.Value)); + records.Add(new AutoInterfaceRecord(symbol, receiverType, baseInterfaceType, template, templateParts, false, preferCoalesce.Value, allowMissingMembers.Value, memberMatch.Value)); } } } else if (IsDuckImplementation(receiverType, type, includeBaseInterfaces.Value, allowMissingMembers.Value)) { danglingInterfaceTypesBySymbols.Remove(symbol); - records.Add(new AutoInterfaceRecord(symbol, receiverType, interfaceType, template, templateParts, true, preferCoalesce.Value, allowMissingMembers.Value)); + records.Add(new AutoInterfaceRecord(symbol, receiverType, interfaceType, template, templateParts, true, preferCoalesce.Value, allowMissingMembers.Value, memberMatch.Value)); if (includeBaseInterfaces.Value) { foreach (INamedTypeSymbol baseInterfaceType in interfaceType.AllInterfaces) { bool byType = receiverType.IsMatchByTypeOrImplementsInterface(baseInterfaceType); - records.Add(new AutoInterfaceRecord(symbol, receiverType, baseInterfaceType, template, templateParts, !byType, preferCoalesce.Value, allowMissingMembers.Value)); + records.Add(new AutoInterfaceRecord(symbol, receiverType, baseInterfaceType, template, templateParts, !byType, preferCoalesce.Value, allowMissingMembers.Value, memberMatch.Value)); } } } else { - Helpers.ReportDiagnostic(context, "BK-AG04", nameof(AutoInterfaceResource.AG04_title), nameof(AutoInterfaceResource.AG04_message), nameof(AutoInterfaceResource.AG04_description), DiagnosticSeverity.Error, attribute.ApplicationSyntaxReference?.GetSyntax(), + Helpers.ReportDiagnostic(context, "BKAG04", nameof(AutoInterfaceResource.AG04_title), nameof(AutoInterfaceResource.AG04_message), nameof(AutoInterfaceResource.AG04_description), DiagnosticSeverity.Error, attribute.ApplicationSyntaxReference?.GetSyntax(), receiverType.ToDisplayString(SymbolDisplayFormat.CSharpErrorMessageFormat), type.ToDisplayString(SymbolDisplayFormat.CSharpErrorMessageFormat)); continue; } } else { - Helpers.ReportDiagnostic(context, "BK-AG09", nameof(AutoInterfaceResource.AG09_title), nameof(AutoInterfaceResource.AG09_message), nameof(AutoInterfaceResource.AG09_description), DiagnosticSeverity.Error, attribute.ApplicationSyntaxReference?.GetSyntax(), + Helpers.ReportDiagnostic(context, "BKAG09", nameof(AutoInterfaceResource.AG09_title), nameof(AutoInterfaceResource.AG09_message), nameof(AutoInterfaceResource.AG09_description), DiagnosticSeverity.Error, attribute.ApplicationSyntaxReference?.GetSyntax(), 157834); continue; } } else { - Helpers.ReportDiagnostic(context, "BK-AG03", nameof(AutoInterfaceResource.AG03_title), nameof(AutoInterfaceResource.AG03_message), nameof(AutoInterfaceResource.AG03_description), DiagnosticSeverity.Error, attribute.ApplicationSyntaxReference?.GetSyntax(), + Helpers.ReportDiagnostic(context, "BKAG03", nameof(AutoInterfaceResource.AG03_title), nameof(AutoInterfaceResource.AG03_message), nameof(AutoInterfaceResource.AG03_description), DiagnosticSeverity.Error, attribute.ApplicationSyntaxReference?.GetSyntax(), type.ToDisplayString(SymbolDisplayFormat.CSharpErrorMessageFormat)); continue; } @@ -504,7 +514,7 @@ private static List CollectRecords(GeneratorExecutionContex { foreach (INamedTypeSymbol interfaceType in danglingInterfaceTypes.Value) { - records.Add(new AutoInterfaceRecord(danglingInterfaceTypes.Key, receiverType, interfaceType, null, templateParts, false, false, false)); + records.Add(new AutoInterfaceRecord(danglingInterfaceTypes.Key, receiverType, interfaceType, null, templateParts, false, false, false, MemberMatchTypes.Explicit)); } } @@ -593,7 +603,7 @@ private static bool IsDuckImplementation(ITypeSymbol receiverType, ITypeSymbol i if (g.Template.Equals(td) == false) { error = true; - Helpers.ReportDiagnostic(context, "BK-AG10", nameof(AutoInterfaceResource.AG10_title), nameof(AutoInterfaceResource.AG10_message), nameof(AutoInterfaceResource.AG10_description), DiagnosticSeverity.Error, reference.Member); + Helpers.ReportDiagnostic(context, "BKAG10", nameof(AutoInterfaceResource.AG10_title), nameof(AutoInterfaceResource.AG10_message), nameof(AutoInterfaceResource.AG10_description), DiagnosticSeverity.Error, reference.Member); continue; } } @@ -607,37 +617,58 @@ private static bool IsDuckImplementation(ITypeSymbol receiverType, ITypeSymbol i INamedTypeSymbol @interface = group.Key; List references = group.DistinctBy(i => i.Member).ToList(); - var allowAnyMissingMember = references.Any(i => i.AllowMissingMembers); - var allowAnyStrict = references.Any(i => i.AllowMissingMembers == false); - bool ShouldGenerate(ISymbol member) { - if (allowAnyStrict) + foreach (var reference in references) { - //any strict case - return type.IsMemberImplementedExplicitly(member) == false; + if (reference.AllowMissingMembers) + { + if (reference.ReceiverType.IsMemberImplementedBySignature(member) == false) + { + return false; + } + } } - else + + var memberImplementedBySignature = type.IsMemberImplementedBySignature(member); + var memberImplementedExplicitly = type.IsMemberImplementedExplicitly(member); + + foreach (var reference in references) { - //at least one AllowMissingMembers case - return allowAnyMissingMember && type.IsMemberImplemented(member) == false; + if (IsMemberImplemented(reference.MemberMatch, memberImplementedBySignature, memberImplementedExplicitly)) + { + return false; + } } + + return true; } bool ShouldBeReferenced(ISymbol member, IMemberInfo reference) { - if (reference.AllowMissingMembers == false) + if (reference.AllowMissingMembers) { - //strict case - return true; + //AllowMissingMembers case + return reference.ReceiverType.IsMemberImplementedBySignature(member); } else { - //AllowMissingMembers case - return reference.ReceiverType.IsMemberImplementedBySignature(member); + //strict case + return true; } } + static bool IsMemberImplemented(MemberMatchTypes memberMatchType, bool memberImplementedBySignature, bool memberImplementedExplicitly) + { + return memberMatchType switch + { + MemberMatchTypes.Public => memberImplementedBySignature, + MemberMatchTypes.Explicit => memberImplementedExplicitly, + MemberMatchTypes.Any => memberImplementedBySignature || memberImplementedExplicitly, + _ => throw new NotSupportedException(), + }; + } + if (generator != null) { var model = new StandaloneModel(); diff --git a/BeaKona.AutoInterfaceGenerator/BeaKona.AutoInterfaceGenerator.csproj b/BeaKona.AutoInterfaceGenerator/BeaKona.AutoInterfaceGenerator.csproj index 569c7ec..874fe08 100644 --- a/BeaKona.AutoInterfaceGenerator/BeaKona.AutoInterfaceGenerator.csproj +++ b/BeaKona.AutoInterfaceGenerator/BeaKona.AutoInterfaceGenerator.csproj @@ -13,7 +13,7 @@ https://github.com/beakona/AutoInterface git $(TargetsForTfmSpecificContentInPackage);_AddAnalyzersToOutput - 1.0.30 + 1.0.31 true true diff --git a/BeaKona.AutoInterfaceGenerator/ComparerBySignature.cs b/BeaKona.AutoInterfaceGenerator/ComparerBySignature.cs index dc5944c..9fd433b 100644 --- a/BeaKona.AutoInterfaceGenerator/ComparerBySignature.cs +++ b/BeaKona.AutoInterfaceGenerator/ComparerBySignature.cs @@ -8,6 +8,8 @@ public sealed class ComparerBySignature : IEqualityComparer public bool Equals(ISymbol s1, ISymbol s2) { + //should we check s1/s2.DeclaredAccessibility to be Accessibility.Public || Accessibility.NotApplicable?? + if (s1.Kind == s2.Kind) { if (s1.Kind == SymbolKind.Method) diff --git a/BeaKona.AutoInterfaceGenerator/Helpers.cs b/BeaKona.AutoInterfaceGenerator/Helpers.cs index 9b2ffdf..fa4f724 100644 --- a/BeaKona.AutoInterfaceGenerator/Helpers.cs +++ b/BeaKona.AutoInterfaceGenerator/Helpers.cs @@ -21,6 +21,7 @@ public static void ReportDiagnostic(GeneratorExecutionContext context, string id var lDescription = new LocalizableResourceString(description, AutoInterfaceResource.ResourceManager, typeof(AutoInterfaceResource)); var category = typeof(AutoInterfaceSourceGenerator).Namespace; var link = "https://github.com/beakona/AutoInterface"; + var dd = new DiagnosticDescriptor(id, lTitle, lMessage, category, severity, true, lDescription, link, WellKnownDiagnosticTags.NotConfigurable); var d = Diagnostic.Create(dd, location, messageArgs); context.ReportDiagnostic(d); diff --git a/BeaKona.AutoInterfaceGenerator/IMemberInfo.cs b/BeaKona.AutoInterfaceGenerator/IMemberInfo.cs index dbfe0c7..552be33 100644 --- a/BeaKona.AutoInterfaceGenerator/IMemberInfo.cs +++ b/BeaKona.AutoInterfaceGenerator/IMemberInfo.cs @@ -12,4 +12,5 @@ internal interface IMemberInfo bool BySignature { get; } bool PreferCoalesce { get; } bool AllowMissingMembers { get; } + MemberMatchTypes MemberMatch { get; } } diff --git a/BeaKona.AutoInterfaceGenerator/ITypeSymbolExtensions.cs b/BeaKona.AutoInterfaceGenerator/ITypeSymbolExtensions.cs index 16a7b9d..8c2bc15 100644 --- a/BeaKona.AutoInterfaceGenerator/ITypeSymbolExtensions.cs +++ b/BeaKona.AutoInterfaceGenerator/ITypeSymbolExtensions.cs @@ -73,12 +73,12 @@ public static bool IsMemberImplementedExplicitly(this ITypeSymbol @this, ISymbol }; } - public static bool IsMemberImplemented(this ITypeSymbol @this, ISymbol member) - { - ISymbol? implementation = @this.FindImplementationForInterfaceMember(member); + //public static bool IsMemberImplemented(this ITypeSymbol @this, ISymbol member) + //{ + // ISymbol? implementation = @this.FindImplementationForInterfaceMember(member); - return implementation is not null && implementation.IsStatic == false && implementation.ContainingType.Equals(@this, SymbolEqualityComparer.Default); - } + // return implementation is not null && implementation.IsStatic == false && implementation.ContainingType.Equals(@this, SymbolEqualityComparer.Default); + //} public static ISymbol? FindImplementationForInterfaceMemberBySignature(this ITypeSymbol @this, ISymbol interfaceMember) { diff --git a/BeaKona.AutoInterfaceGenerator/Templates/PartialTemplate.cs b/BeaKona.AutoInterfaceGenerator/Templates/PartialTemplate.cs index 5e00428..be7e08d 100644 --- a/BeaKona.AutoInterfaceGenerator/Templates/PartialTemplate.cs +++ b/BeaKona.AutoInterfaceGenerator/Templates/PartialTemplate.cs @@ -30,7 +30,7 @@ public PartialTemplate(AutoInterfaceTargets memberTargets, Regex? memberFilter, { if (ts[1].template.MemberFilter != null) { - Helpers.ReportDiagnostic(context, "BK-AG16", nameof(AutoInterfaceResource.AG16_title), nameof(AutoInterfaceResource.AG16_message), nameof(AutoInterfaceResource.AG16_description), DiagnosticSeverity.Error, ts[0].reference, + Helpers.ReportDiagnostic(context, "BKAG16", nameof(AutoInterfaceResource.AG16_title), nameof(AutoInterfaceResource.AG16_message), nameof(AutoInterfaceResource.AG16_description), DiagnosticSeverity.Error, ts[0].reference, name); return null; } @@ -47,13 +47,13 @@ public PartialTemplate(AutoInterfaceTargets memberTargets, Regex? memberFilter, } else { - Helpers.ReportDiagnostic(context, "BK-AG16", nameof(AutoInterfaceResource.AG16_title), nameof(AutoInterfaceResource.AG16_message), nameof(AutoInterfaceResource.AG16_description), DiagnosticSeverity.Error, ts[0].reference, + Helpers.ReportDiagnostic(context, "BKAG16", nameof(AutoInterfaceResource.AG16_title), nameof(AutoInterfaceResource.AG16_message), nameof(AutoInterfaceResource.AG16_description), DiagnosticSeverity.Error, ts[0].reference, name); return null; } } default: - Helpers.ReportDiagnostic(context, "BK-AG16", nameof(AutoInterfaceResource.AG16_title), nameof(AutoInterfaceResource.AG16_message), nameof(AutoInterfaceResource.AG16_description), DiagnosticSeverity.Error, ts[0].reference, + Helpers.ReportDiagnostic(context, "BKAG16", nameof(AutoInterfaceResource.AG16_title), nameof(AutoInterfaceResource.AG16_message), nameof(AutoInterfaceResource.AG16_description), DiagnosticSeverity.Error, ts[0].reference, name); return null; }