DIForFunctions–improving generating of a constructor for a existing class with Roslyn

It is not so difficult to generate a new constructor for a existing class with Roslyn – however , there are some difficulties:

1. The original class must be declared “partial” – you cannot declare the second as partial if the first was not

2.  The new class must be in the same namespace ( or without namespace) as the original

3. The constructor must have the types declared with  full names  / or get the usings from the existing class ( or , maybe , put the developer to use global usings: https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-10

For 1 the dotnet compiler shows an error  – but you can add yours too:

private static bool HasPartial(ClassDeclarationSyntax cds)
         {
             if (cds.Modifiers.Count < 1)
                 return false;
             foreach(var modif in cds.Modifiers)
             {
                 if (modif.Text == “partial”)
                     return true;
             }
             return false;
         }

if (!HasPartial(cds))
                 {
                     var dd = new DiagnosticDescriptor(DiagnosticId, Title, “Please add partial to ” + cds.Identifier.Text, Category, DiagnosticSeverity.Error, isEnabledByDefault: true, description: “Please add partial to ” + cds.Identifier.Text);
                     Location? loc = cds.GetLocation();
                     var dg = Diagnostic.Create(dd, loc);
                     context.ReportDiagnostic(dg);
                     return;
                 }

For 2 is somehow more difficult

private static Tuple<string,string> NameAndNameSpace(ClassDeclarationSyntax c)
         {
             var nameClass = c.Identifier.Text;
             var p = c.Parent;
             var namespaceClass = “”;
             while (true)
             {
                 if (p is BaseNamespaceDeclarationSyntax bnsds)
                 {
                     namespaceClass = bnsds.Name.ToFullString();
                     break;
                 }
                 p = p?.Parent;
                 if (p == null)
                     break;
             }
             return Tuple.Create(nameClass, namespaceClass);
         }

And verify if the namespace is null – if it is, do NOT generate namespace declaration

For 3 it is more complicated

private static string? FullTypeVar(SemanticModel? sem,TypeSyntax? ts)
         {
             if (sem == null)
                 return null;
             if (ts is null)
                 return null;
             var typeInfo = sem.GetTypeInfo(ts);
             if (typeInfo.Type is null)
                 return null;

            var theType = ((INamedTypeSymbol)typeInfo.Type);

            var typeField = theType?.ToDisplayString();
             return typeField;
         }

And that it is!