diff --git a/src-examples/ProxyInterfaceConsumer/Address.cs b/src-examples/ProxyInterfaceConsumer/Address.cs
index c4db154..0d15551 100644
--- a/src-examples/ProxyInterfaceConsumer/Address.cs
+++ b/src-examples/ProxyInterfaceConsumer/Address.cs
@@ -1,4 +1,4 @@
-namespace ProxyInterfaceConsumer
+namespace DifferentNamespace
{
public class Address
{
diff --git a/src-examples/ProxyInterfaceConsumer/IAddress.cs b/src-examples/ProxyInterfaceConsumer/IAddress.cs
index d44b0f6..70b8fcb 100644
--- a/src-examples/ProxyInterfaceConsumer/IAddress.cs
+++ b/src-examples/ProxyInterfaceConsumer/IAddress.cs
@@ -1,6 +1,10 @@
-namespace ProxyInterfaceConsumer
+using DifferentNamespace;
+using System;
+using System.Linq;
+
+namespace ProxyInterfaceConsumer
{
- // [ProxyInterfaceGenerator.Proxy(typeof(ProxyInterfaceConsumer.Address))]
+ [ProxyInterfaceGenerator.Proxy(typeof(Address))]
public partial interface IAddress
{
}
diff --git a/src-examples/ProxyInterfaceConsumer/Person.cs b/src-examples/ProxyInterfaceConsumer/Person.cs
index 84efcc1..09c0e34 100644
--- a/src-examples/ProxyInterfaceConsumer/Person.cs
+++ b/src-examples/ProxyInterfaceConsumer/Person.cs
@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using DifferentNamespace;
+using System.Collections.Generic;
using System.Threading.Tasks;
namespace ProxyInterfaceConsumer
diff --git a/src/ProxyInterfaceSourceGenerator/Compatibility/NullableAttributes.cs b/src/ProxyInterfaceSourceGenerator/Compatibility/NullableAttributes.cs
new file mode 100644
index 0000000..82dfeb2
--- /dev/null
+++ b/src/ProxyInterfaceSourceGenerator/Compatibility/NullableAttributes.cs
@@ -0,0 +1,18 @@
+// https://stackoverflow.com/questions/61573959/how-to-resolve-error-notnullwhen-attribute-is-inaccessible-due-to-its-protectio
+
+namespace System.Diagnostics.CodeAnalysis
+{
+ /// Specifies that when a method returns , the parameter will not be null even if the corresponding type allows it.
+ [AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
+ internal sealed class NotNullWhenAttribute : Attribute
+ {
+ /// Initializes the attribute with the specified return value condition.
+ ///
+ /// The return value condition. If the method returns this value, the associated parameter will not be null.
+ ///
+ public NotNullWhenAttribute(bool returnValue) => ReturnValue = returnValue;
+
+ /// Gets the return value condition.
+ public bool ReturnValue { get; }
+ }
+}
\ No newline at end of file
diff --git a/src/ProxyInterfaceSourceGenerator/Extensions/SyntaxNodeUtils.cs b/src/ProxyInterfaceSourceGenerator/Extensions/SyntaxNodeUtils.cs
index fb2c780..a8bed5e 100644
--- a/src/ProxyInterfaceSourceGenerator/Extensions/SyntaxNodeUtils.cs
+++ b/src/ProxyInterfaceSourceGenerator/Extensions/SyntaxNodeUtils.cs
@@ -1,11 +1,12 @@
using Microsoft.CodeAnalysis;
+using System.Diagnostics.CodeAnalysis;
namespace ProxyInterfaceSourceGenerator.Extensions
{
internal static class SyntaxNodeUtils
{
// https://stackoverflow.com/questions/20458457/getting-class-fullname-including-namespace-from-roslyn-classdeclarationsyntax
- public static bool TryGetParentSyntax(this SyntaxNode? syntaxNode, out T? result) where T : SyntaxNode
+ public static bool TryGetParentSyntax(this SyntaxNode? syntaxNode, [NotNullWhen(true)] out T? result) where T : SyntaxNode
{
result = null;
@@ -25,7 +26,7 @@ namespace ProxyInterfaceSourceGenerator.Extensions
if (syntaxNode.GetType() == typeof(T))
{
- result = syntaxNode as T;
+ result = (T)syntaxNode;
return true;
}
diff --git a/src/ProxyInterfaceSourceGenerator/FileGenerators/BaseGenerator.cs b/src/ProxyInterfaceSourceGenerator/FileGenerators/BaseGenerator.cs
index 36bcec8..a570541 100644
--- a/src/ProxyInterfaceSourceGenerator/FileGenerators/BaseGenerator.cs
+++ b/src/ProxyInterfaceSourceGenerator/FileGenerators/BaseGenerator.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using System.Linq;
using Microsoft.CodeAnalysis;
@@ -67,16 +68,28 @@ namespace ProxyInterfaceSourceGenerator.FileGenerators
return typeSymbolAsString;
}
- protected INamedTypeSymbol GetNamedTypeSymbolByFullName(string fullName)
+ protected INamedTypeSymbol GetNamedTypeSymbolByFullName(string name, IEnumerable? usings = null)
{
// The GetTypeByMetadataName method returns null if no type matches the full name or if 2 or more types (in different assemblies) match the full name.
- var symbol = _context.GeneratorExecutionContext.Compilation.GetTypeByMetadataName(fullName);
- if (symbol is null)
- {
- throw new Exception($"The type '{fullName}' is not found.");
+ var symbol = _context.GeneratorExecutionContext.Compilation.GetTypeByMetadataName(name);
+ if (symbol is not null)
+ {
+ return symbol;
+ }
+
+ if (usings is not null)
+ {
+ foreach (var @using in usings)
+ {
+ symbol = _context.GeneratorExecutionContext.Compilation.GetTypeByMetadataName($"{@using}.{name}");
+ if (symbol is not null)
+ {
+ return symbol;
+ }
+ }
}
- return symbol;
+ throw new Exception($"The type '{name}' is not found.");
}
}
}
\ No newline at end of file
diff --git a/src/ProxyInterfaceSourceGenerator/FileGenerators/PartialInterfacesGenerator.cs b/src/ProxyInterfaceSourceGenerator/FileGenerators/PartialInterfacesGenerator.cs
index 301dc4a..ee422dc 100644
--- a/src/ProxyInterfaceSourceGenerator/FileGenerators/PartialInterfacesGenerator.cs
+++ b/src/ProxyInterfaceSourceGenerator/FileGenerators/PartialInterfacesGenerator.cs
@@ -26,7 +26,7 @@ namespace ProxyInterfaceSourceGenerator.FileGenerators
private FileData GenerateFile(ProxyData pd)
{
- var targetClassSymbol = GetNamedTypeSymbolByFullName(pd.TypeName);
+ var targetClassSymbol = GetNamedTypeSymbolByFullName(pd.TypeName, pd.Usings);
var interfaceName = targetClassSymbol.ResolveInterfaceNameWithOptionalTypeConstraints(pd.InterfaceName);
var file = new FileData(
diff --git a/src/ProxyInterfaceSourceGenerator/FileGenerators/ProxyClassesGenerator.cs b/src/ProxyInterfaceSourceGenerator/FileGenerators/ProxyClassesGenerator.cs
index 202731a..fdb69ac 100644
--- a/src/ProxyInterfaceSourceGenerator/FileGenerators/ProxyClassesGenerator.cs
+++ b/src/ProxyInterfaceSourceGenerator/FileGenerators/ProxyClassesGenerator.cs
@@ -26,7 +26,7 @@ namespace ProxyInterfaceSourceGenerator.FileGenerators
private FileData GenerateFile(ProxyData pd)
{
- var targetClassSymbol = GetNamedTypeSymbolByFullName(pd.TypeName);
+ var targetClassSymbol = GetNamedTypeSymbolByFullName(pd.TypeName, pd.Usings);
var interfaceName = targetClassSymbol.ResolveInterfaceNameWithOptionalTypeConstraints(pd.InterfaceName);
var className = targetClassSymbol.ResolveProxyClassName();
var constructorName = $"{targetClassSymbol.Name}Proxy";
diff --git a/src/ProxyInterfaceSourceGenerator/SyntaxReceiver/ProxyData.cs b/src/ProxyInterfaceSourceGenerator/SyntaxReceiver/ProxyData.cs
index 411b5c7..9729900 100644
--- a/src/ProxyInterfaceSourceGenerator/SyntaxReceiver/ProxyData.cs
+++ b/src/ProxyInterfaceSourceGenerator/SyntaxReceiver/ProxyData.cs
@@ -1,6 +1,8 @@
-namespace ProxyInterfaceSourceGenerator.SyntaxReceiver
+using System.Collections.Generic;
+
+namespace ProxyInterfaceSourceGenerator.SyntaxReceiver
{
- internal record ProxyData(string Namespace, string InterfaceName, string RawTypeName, string TypeName, bool ProxyAll)
+ internal record ProxyData(string Namespace, string InterfaceName, string RawTypeName, string TypeName, List Usings, bool ProxyAll)
{
public string FileName => TypeName.Replace('.', '_').Replace('`', '_');
}
diff --git a/src/ProxyInterfaceSourceGenerator/SyntaxReceiver/ProxySyntaxReceiver.cs b/src/ProxyInterfaceSourceGenerator/SyntaxReceiver/ProxySyntaxReceiver.cs
index 7b9e6a8..0047e60 100644
--- a/src/ProxyInterfaceSourceGenerator/SyntaxReceiver/ProxySyntaxReceiver.cs
+++ b/src/ProxyInterfaceSourceGenerator/SyntaxReceiver/ProxySyntaxReceiver.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
@@ -20,9 +21,9 @@ namespace ProxyInterfaceSourceGenerator.SyntaxReceiver
}
}
- private static bool TryGet(InterfaceDeclarationSyntax interfaceDeclarationSyntax, out ProxyData data)
+ private static bool TryGet(InterfaceDeclarationSyntax interfaceDeclarationSyntax, [NotNullWhen(true)] out ProxyData? data)
{
- data = new(string.Empty, string.Empty, string.Empty, string.Empty, false);
+ data = null;
if (interfaceDeclarationSyntax.Modifiers.Select(m => m.ToString()).Except(Modifiers).Count() != 0)
{
@@ -42,27 +43,39 @@ namespace ProxyInterfaceSourceGenerator.SyntaxReceiver
return false;
}
+ var usings = new List();
+
string ns = string.Empty;
- if (SyntaxNodeUtils.TryGetParentSyntax(interfaceDeclarationSyntax, out NamespaceDeclarationSyntax namespaceDeclarationSyntax))
+ if (SyntaxNodeUtils.TryGetParentSyntax(interfaceDeclarationSyntax, out NamespaceDeclarationSyntax? namespaceDeclarationSyntax))
{
ns = namespaceDeclarationSyntax.Name.ToString();
+ usings.Add(ns);
+ }
+
+ if (SyntaxNodeUtils.TryGetParentSyntax(interfaceDeclarationSyntax, out CompilationUnitSyntax? cc))
+ {
+ foreach (var @using in cc.Usings)
+ {
+ usings.Add(@using.Name.ToString());
+ }
}
- string rawTypename = ((TypeOfExpressionSyntax)argumentList.Arguments[0].Expression).Type.ToString();
+ string rawTypeName = ((TypeOfExpressionSyntax)argumentList.Arguments[0].Expression).Type.ToString();
data = new
(
ns,
interfaceDeclarationSyntax.Identifier.ToString(),
- rawTypename,
- ResolveType(rawTypename),
+ rawTypeName,
+ ConvertTypeName(rawTypeName),
+ usings,
false //bool.Parse(argumentList.Arguments[1].Expression.GetText().ToString())
);
return true;
}
- private static string ResolveType(string typeName)
+ private static string ConvertTypeName(string typeName)
{
return !(typeName.Contains('<') && typeName.Contains('>')) ?
typeName :