Introduction

In part one of reading the sourcefile with Roslyn I installed Roslyn, made a new console project and read the content of this file. Now lets go a bit further.

Property and class

So I adapted my sourcefile to contain a bit more posibilities.

Public Class Class1
    Public Property string1 As String
    Public Property string2 As String

    Private Class Class2
        Public Property string3 As String
        Public Property string4 As String
    End Class
End Class

Public Class Class3
    Public Property string5 As String
    Public Property string6 As String
End Class

Partial Public Class Class1
    Public Property string7 As String
    Public Property string8 As String
End Class

If I now run my previous example.

Imports System.IO
 
Module Module1
 
    Sub Main()
        Dim sourcetext As String
        Using streamReader = New StreamReader("F:MyDocumentsVisual Studio 2010ProjectsConsoleApplication5Class1.vb")
            sourcetext = streamReader.ReadToEnd
        End Using
 
        For Each prop In SyntaxTree.ParseCompilationUnit(sourcetext).Root.DescendentNodes.OfType(Of PropertyStatementSyntax)()
            Console.WriteLine(prop.GetText)
            Console.WriteLine(prop.Identifier.GetFullText)
        Next
        Console.ReadLine()
    End Sub
 
End Module```
I get the following result.

<div class="image_block">
  <a href="/wp-content/uploads/users/chrissie1/roslyn/roslyn3.png?mtime=1319311151"><img alt="" src="/wp-content/uploads/users/chrissie1/roslyn/roslyn3.png?mtime=1319311151" width="707" height="423" /></a>
</div>

That is not a very usefull result since I have no idea where the properties are coming from. But that is easliy fixed since each property also has a parent property.

```vbnet
Imports System.IO

Module Module1

    Sub Main()
        Dim sourcetext As String
        Using streamReader = New StreamReader("F:MyDocumentsVisual Studio 2010ProjectsConsoleApplication5Class1.vb")
            sourcetext = streamReader.ReadToEnd
        End Using

        For Each prop In SyntaxTree.ParseCompilationUnit(sourcetext).Root.DescendentNodes.OfType(Of PropertyStatementSyntax)()
            Console.WriteLine("Property: " & prop.Identifier.GetText)
            If TypeOf prop.Parent Is ClassBlockSyntax Then
                Console.WriteLine("Belongs to: " & CType(CType(prop.Parent, ClassBlockSyntax).ChildNodes(0), ClassStatementSyntax).Identifier.GetText)
            End If

        Next
        Console.ReadLine()
    End Sub

End Module

Which gives this result.

You have to watch out because the parent is not a ClassStatementSyntax but a ClassBlockSyntax. The ClassBlockSyntax does not contain the identifier but it does contain a childnode that is a ClassStatemetSyntax which does contain the identifier. You could just print the whole syntaxtree to find this out, or RTFM.

Of course you can also use a bit more LINQ and get this.

Option Strict Off

Imports System.IO

Module Module1

    Sub Main()
        Dim sourcetext As String
        Using streamReader = New StreamReader("F:MyDocumentsVisual Studio 2010ProjectsConsoleApplication5Class1.vb")
            sourcetext = streamReader.ReadToEnd
        End Using

        Dim propclasses = From e In SyntaxTree.ParseCompilationUnit(sourcetext).Root.DescendentNodes.OfType(Of PropertyStatementSyntax)() Select New With {.PropertyName = e.Identifier.GetText, .ClassName = CType(CType(e.Parent, ClassBlockSyntax).ChildNodes(0), ClassStatementSyntax).Identifier.GetText}

        For Each propclass In propclasses.OrderBy(Function(x) x.ClassName)
            Console.WriteLine("Property: " & propclass.PropertyName)
            Console.WriteLine("Belongs to: " & propclass.ClassName)
        Next
        Console.ReadLine()
    End Sub

End Module

With a slightly different result as before.

Conclusion

Once you got how the syntaxtree thing works it’s very easy to find what you need.