IIncrementalGenerator - Get namespace of property type

69 views Asked by At

Based on my property list I want to generated new code. For that I need to add the corresponding usings too.

How can I get the namespace of my property type? In this case prop.Type.ToString()

private static void Execute(Compilation item1, ImmutableArray<(ClassDeclarationSyntax classDeclaration, AttributeData attribute)> classes, SourceProductionContext context)
{
    foreach (var (classDeclaration, attribute) in classes)
    {
         var properties = classDeclaration.Members.AsEnumerable().Where(o => o.IsKind(SyntaxKind.PropertyDeclaration));
         var props = properties.Select(o => o.ChildTokens().Single(n => n.IsKind(SyntaxKind.IdentifierToken)).ValueText).ToArray();

         var snapshotProperties = new List<SnapshotProperty>();
         foreach (var property in properties)
         {
             var prop = (PropertyDeclarationSyntax)property;

             snapshotProperties.Add(new SnapshotProperty(
                 prop.ToString(),
                 prop.Type.ToString(),
                 prop.Identifier.ValueText,
                 prop.Identifier.ValueText.ToLower()));
         }
    }
}

private class SnapshotProperty
{
    public string FullProperty { get; }
    public string Type { get; }
    public string PropertyName { get; }
    public string ParameterName { get; }

    public SnapshotProperty(string fullProperty, string type, string propertyName, string parameterName)
    {
        FullProperty = fullProperty;
        Type = type;
        PropertyName = propertyName;
        ParameterName = parameterName;
    }
}
1

There are 1 answers

0
nalka On BEST ANSWER

You can use the GetTypeInfo extension method on a SemanticModel and from here you can get

  • The type's name with .Type.Name
  • The containing namespace's name with .Type.ContainingNamespace.Name (you may have to go through the ContainingNamesapce's ContainingNamespace if you have several namespaces like Namespace1.Namespace2)
  • The type's full name via .Type.ToDisplayString() (some of the types that are aliased will display with their alias instead, for example usage on System.Int32 will display int, see the SpecialType property for more)

If you don't already have one in the code that calls Execute, you can get a SemanticModel with item1 (your parameter of type Compilation) using GetSemanticModel : item1.GetSemanticModel(classDeclaration.GetLocation().SourceTree).

Assuming you want the type's full name, your execute method would then look like the following :

private static void Execute(Compilation item1, ImmutableArray<(ClassDeclarationSyntax classDeclaration, AttributeData attribute)> classes, SourceProductionContext context)
{
    foreach (var (classDeclaration, attribute) in classes)
    {
        var properties = classDeclaration.Members.AsEnumerable().Where(o => o.IsKind(SyntaxKind.PropertyDeclaration));
        var props = properties.Select(o => o.ChildTokens().Single(n => n.IsKind(SyntaxKind.IdentifierToken)).ValueText).ToArray();
        var semanticModel = item1.GetSemanticModel(classDeclaration.GetLocation().SourceTree);
        var snapshotProperties = new List<SnapshotProperty>();
        foreach (var property in properties)
        {
            var prop = (PropertyDeclarationSyntax)property;

            snapshotProperties.Add(new SnapshotProperty(
                prop.ToString(),
                semanticModel.GetTypeInfo(prop.Type).Type.ToDisplayString(),
                prop.Identifier.ValueText,
                prop.Identifier.ValueText.ToLower()));
        }
    }
}