beakona / AutoInterface

C# interface-to-member source generator
MIT License
73 stars 9 forks source link

Generated source have trippled namespacing #8

Closed Dblm0 closed 2 years ago

Dblm0 commented 2 years ago

Given dotted namespace TestInterfaces.A.B , declared in the same compile unit, I have the following generated code output:

#nullable enable

namespace AutoInterfaceSample
{
    partial class Person : TestInterfaces.A.B.TestInterfaces.A.B.TestInterfaces.A.B.ITestable, TestInterfaces.A.B.TestInterfaces.A.B.TestInterfaces.A.B.IPrintable<int>, TestInterfaces.A.B.TestInterfaces.A.B.TestInterfaces.A.B.IPrintable2
    {
        void TestInterfaces.A.B.TestInterfaces.A.B.TestInterfaces.A.B.ITestable.PrintTest() => (this.aspect1 as TestInterfaces.A.B.TestInterfaces.A.B.TestInterfaces.A.B.ITestable)!.PrintTest();

        void TestInterfaces.A.B.TestInterfaces.A.B.TestInterfaces.A.B.IPrintable<int>.Print1() => (this.aspect2 as TestInterfaces.A.B.TestInterfaces.A.B.TestInterfaces.A.B.IPrintable<int>)!.Print1();

        void TestInterfaces.A.B.TestInterfaces.A.B.TestInterfaces.A.B.IPrintable<int>.Print2() => (this.aspect2 as TestInterfaces.A.B.TestInterfaces.A.B.TestInterfaces.A.B.IPrintable<int>)!.Print2();

        int TestInterfaces.A.B.TestInterfaces.A.B.TestInterfaces.A.B.IPrintable<int>.Length => (this.aspect2 as TestInterfaces.A.B.TestInterfaces.A.B.TestInterfaces.A.B.IPrintable<int>)!.Length;

        int TestInterfaces.A.B.TestInterfaces.A.B.TestInterfaces.A.B.IPrintable<int>.Count => (this.aspect2 as TestInterfaces.A.B.TestInterfaces.A.B.TestInterfaces.A.B.IPrintable<int>)!.Count;

        void TestInterfaces.A.B.TestInterfaces.A.B.TestInterfaces.A.B.IPrintable2.Print3() => (this.aspect2 as TestInterfaces.A.B.TestInterfaces.A.B.TestInterfaces.A.B.IPrintable2)!.Print3();
    }
}

If the interface is located in a separate project, generated code, peeked in analyzers explorer, looks like the same, but it is right in the result. The solution compiles and you can see the desired code stepping intro it while debugging.

I've created a more complex example in forked repo, where the resulting namespace combination is more confusing.

Sorry for annoying you this whole week

Thanks in advance!

beakona commented 2 years ago

Most of problems I have with this project are within method that generates string as name of ISymbol... It seems that "namespace" is "concatenated" 3 times.. once for each namespace component for namespace A.B it would be generated A.B.A.B for namespace A.B.C it would be generated A.B.C.A.B.C.A.B.C... etc I'll fix it later tonight...

beakona commented 2 years ago

I hope I've fixed this Main reason I traverse over syntax nodes instead of simply calling ISymbol.Name for each element is scenario when two generic parameters from different elements have same name. In such case there is mapping between generic parameters on entire scope and I am pretty confident it works Here is an example. This conflict exists only on source level. During initial development of AutoInterface I considered generating SyntaxNode objects and then directly append them to compilation unit context. At that time such approach seemed inappropriate because I couldn't find way user to view generated source. Since then visualizer is added to Solution ToolWindow as you described.. When I find time, I'll try to add such code generation. Code will be generated much faster because there is no need for source parsing, and code is forward-only so limited set of new features would affect AutoInterface changes. Source templating in such case would be off...