diff --git a/InterfaceGenerator.Tests/SameName/SameNameClass.1.cs b/InterfaceGenerator.Tests/SameName/SameNameClass.1.cs
new file mode 100644
index 0000000..e3906f2
--- /dev/null
+++ b/InterfaceGenerator.Tests/SameName/SameNameClass.1.cs
@@ -0,0 +1,12 @@
+// ReSharper disable CheckNamespace
+namespace InterfaceGenerator.Tests.SameName_1;
+
+///
+/// A class with the same name as . It exists to test if the generated source units have fully
+/// qualified names.
+///
+[GenerateAutoInterface]
+internal class SameNameClass : ISameNameClass
+{
+
+}
\ No newline at end of file
diff --git a/InterfaceGenerator.Tests/SameName/SameNameClass.2.cs b/InterfaceGenerator.Tests/SameName/SameNameClass.2.cs
new file mode 100644
index 0000000..9147b4f
--- /dev/null
+++ b/InterfaceGenerator.Tests/SameName/SameNameClass.2.cs
@@ -0,0 +1,8 @@
+// ReSharper disable CheckNamespace
+namespace InterfaceGenerator.Tests.SameName_2;
+
+[GenerateAutoInterface]
+internal class SameNameClass : ISameNameClass
+{
+
+}
\ No newline at end of file
diff --git a/InterfaceGenerator/AutoInterfaceGenerator.cs b/InterfaceGenerator/AutoInterfaceGenerator.cs
index 026ed36..c7b2852 100644
--- a/InterfaceGenerator/AutoInterfaceGenerator.cs
+++ b/InterfaceGenerator/AutoInterfaceGenerator.cs
@@ -1,6 +1,7 @@
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
@@ -21,6 +22,14 @@ namespace InterfaceGenerator
public void Initialize(GeneratorInitializationContext context)
{
context.RegisterForSyntaxNotifications(() => new SyntaxReceiver());
+
+ #if DEBUG
+ if (!Debugger.IsAttached)
+ {
+ // sadly this is Windows only so as of now :(
+ Debugger.Launch();
+ }
+ #endif
}
public void Execute(GeneratorExecutionContext context)
@@ -83,6 +92,8 @@ namespace InterfaceGenerator
var classSymbols = GetImplTypeSymbols(compilation, receiver);
+ List classSymbolNames = new List();
+
foreach (var implTypeSymbol in classSymbols)
{
if (!implTypeSymbol.TryGetAttribute(_generateAutoInterfaceAttribute, out var attributes))
@@ -90,9 +101,17 @@ namespace InterfaceGenerator
continue;
}
+ if(classSymbolNames.Contains(implTypeSymbol.GetFullMetadataName(useNameWhenNotFound: true)))
+ {
+ continue; // partial class, already added
+ }
+
+ classSymbolNames.Add(implTypeSymbol.GetFullMetadataName(useNameWhenNotFound: true));
+
var attribute = attributes.Single();
var source = SourceText.From(GenerateInterfaceCode(implTypeSymbol, attribute), Encoding.UTF8);
- context.AddSource($"{implTypeSymbol.Name}_AutoInterface.cs", source);
+
+ context.AddSource($"{implTypeSymbol.GetFullMetadataName(useNameWhenNotFound: true)}_AutoInterface.cs", source);
}
}
diff --git a/InterfaceGenerator/SymbolExtensions.cs b/InterfaceGenerator/SymbolExtensions.cs
index bb1fbce..5f309ae 100644
--- a/InterfaceGenerator/SymbolExtensions.cs
+++ b/InterfaceGenerator/SymbolExtensions.cs
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Linq;
+using System.Text;
using Microsoft.CodeAnalysis;
namespace InterfaceGenerator
@@ -21,5 +22,47 @@ namespace InterfaceGenerator
return symbol.GetAttributes()
.Any(a => SymbolEqualityComparer.Default.Equals(a.AttributeClass, attributeType));
}
+
+ //Ref: https://stackoverflow.com/questions/27105909/get-fully-qualified-metadata-name-in-roslyn
+ public static string GetFullMetadataName(this ISymbol symbol, bool useNameWhenNotFound = false)
+ {
+ if (IsRootNamespace(symbol))
+ {
+ return useNameWhenNotFound ? symbol.Name : string.Empty;
+ }
+
+ var stringBuilder = new StringBuilder(symbol.MetadataName);
+ var last = symbol;
+
+ symbol = symbol.ContainingSymbol;
+
+ while (!IsRootNamespace(symbol))
+ {
+ if (symbol is ITypeSymbol && last is ITypeSymbol)
+ {
+ stringBuilder.Insert(0, '+');
+ }
+ else
+ {
+ stringBuilder.Insert(0, '.');
+ }
+
+ stringBuilder.Insert(0, symbol.OriginalDefinition.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat));
+ symbol = symbol.ContainingSymbol;
+ }
+
+ var retVal = stringBuilder.ToString();
+ if (string.IsNullOrWhiteSpace(retVal) && useNameWhenNotFound)
+ {
+ return symbol.Name;
+ }
+
+ return retVal;
+ }
+
+ private static bool IsRootNamespace(ISymbol symbol)
+ {
+ return symbol is INamespaceSymbol { IsGlobalNamespace: true };
+ }
}
}
\ No newline at end of file