http://code.google.com/p/syntaxhighlighter/
Imports System Imports System.Collections.Generic Imports System.Text Imports ICSharpCode.NRefactory.Visitors Imports System.CodeDom Imports ICSharpCode.NRefactory.Ast Imports ICSharpCode.NRefactory Imports System.Collections Namespace IndexerLibrary Public Class CodeDomVisitor Inherits AbstractAstVisitor Private namespaceDeclarations As New Stack(Of CodeNamespace)() Private typeDeclarations As New Stack(Of CodeTypeDeclaration)() ' dummy collection used to swallow statements Private NullStmtCollection As New CodeStatementCollection() Public codeCompileUnit As New CodeCompileUnit() Private Function ConvType(ByVal type As TypeReference) As CodeTypeReference If type Is Nothing Then Throw New ArgumentNullException("type") End If If String.IsNullOrEmpty(type.SystemType) Then Throw New InvalidOperationException("empty type") End If Dim t As New CodeTypeReference(type.SystemType) For Each gt As TypeReference In type.GenericTypes t.TypeArguments.Add(ConvType(gt)) Next If type.IsArrayType Then t = New CodeTypeReference(t, type.RankSpecifier.Length) End If Return t End Function ' FIXME: map all modifiers correctly Private Shared Function ConvMemberAttributes(ByVal modifier As Modifiers) As MemberAttributes Dim attr As MemberAttributes = DirectCast(0, MemberAttributes) If (modifier And Modifiers.Abstract) <> 0 Then attr = attr Or MemberAttributes.Abstract End If If (modifier And Modifiers.[Const]) <> 0 Then attr = attr Or MemberAttributes.[Const] End If If (modifier And Modifiers.Sealed) <> 0 Then attr = attr Or MemberAttributes.Final End If If (modifier And Modifiers.[New]) <> 0 Then attr = attr Or MemberAttributes.[New] End If If (modifier And Modifiers.Virtual) <> 0 Then attr = attr Or MemberAttributes.Overloaded End If If (modifier And Modifiers.Override) <> 0 Then attr = attr Or MemberAttributes.Override End If If (modifier And Modifiers.[Static]) <> 0 Then attr = attr Or MemberAttributes.[Static] End If If (modifier And Modifiers.[Private]) <> 0 Then attr = attr Or MemberAttributes.[Private] ElseIf (modifier And Modifiers.[Public]) <> 0 Then attr = attr Or MemberAttributes.[Public] ElseIf (modifier And Modifiers.Internal) <> 0 AndAlso (modifier And Modifiers.[Protected]) <> 0 Then attr = attr Or MemberAttributes.FamilyOrAssembly ElseIf (modifier And Modifiers.Internal) <> 0 Then attr = attr Or MemberAttributes.Assembly ElseIf (modifier And Modifiers.[Protected]) <> 0 Then attr = attr Or MemberAttributes.Family End If Return attr End Function Public Overloads Overrides Function VisitCompilationUnit(ByVal compilationUnit As CompilationUnit, ByVal data As Object) As Object If compilationUnit Is Nothing Then Throw New ArgumentNullException("compilationUnit") End If Dim globalNamespace As New CodeNamespace("Global") 'namespaces.Add(globalNamespace); namespaceDeclarations.Push(globalNamespace) compilationUnit.AcceptChildren(Me, data) codeCompileUnit.Namespaces.Add(globalNamespace) Return globalNamespace End Function Public Overloads Overrides Function VisitNamespaceDeclaration(ByVal namespaceDeclaration As NamespaceDeclaration, ByVal data As Object) As Object Dim currentNamespace As New CodeNamespace(namespaceDeclaration.Name) 'namespaces.Add(currentNamespace); ' add imports from mother namespace For Each import As CodeNamespaceImport In DirectCast(namespaceDeclarations.Peek(), CodeNamespace).[Imports] currentNamespace.[Imports].Add(import) Next namespaceDeclarations.Push(currentNamespace) namespaceDeclaration.AcceptChildren(Me, data) namespaceDeclarations.Pop() codeCompileUnit.Namespaces.Add(currentNamespace) ' TODO : Nested namespaces allowed in CodeDOM ? Doesn't seem so :( Return Nothing End Function Public Overloads Overrides Function VisitUsingDeclaration(ByVal usingDeclaration As UsingDeclaration, ByVal data As Object) As Object For Each u As [Using] In usingDeclaration.Usings namespaceDeclarations.Peek().[Imports].Add(New CodeNamespaceImport(u.Name)) Next Return Nothing End Function Public Overloads Overrides Function VisitAttributeSection(ByVal attributeSection As AttributeSection, ByVal data As Object) As Object Return Nothing End Function Public Overloads Overrides Function VisitTypeDeclaration(ByVal typeDeclaration As TypeDeclaration, ByVal data As Object) As Object Dim oldTypeDeclaration As TypeDeclaration = currentTypeDeclaration Me.currentTypeDeclaration = typeDeclaration Dim codeTypeDeclaration As New CodeTypeDeclaration(typeDeclaration.Name) codeTypeDeclaration.IsClass = typeDeclaration.Type = ClassType.[Class] codeTypeDeclaration.IsEnum = typeDeclaration.Type = ClassType.[Enum] codeTypeDeclaration.IsInterface = typeDeclaration.Type = ClassType.[Interface] codeTypeDeclaration.IsStruct = typeDeclaration.Type = ClassType.Struct If typeDeclaration.BaseTypes IsNot Nothing Then For Each typeRef As TypeReference In typeDeclaration.BaseTypes codeTypeDeclaration.BaseTypes.Add(ConvType(typeRef)) Next End If typeDeclarations.Push(codeTypeDeclaration) typeDeclaration.AcceptChildren(Me, data) typeDeclarations.Pop() If typeDeclarations.Count > 0 Then typeDeclarations.Peek().Members.Add(codeTypeDeclaration) Else namespaceDeclarations.Peek().Types.Add(codeTypeDeclaration) End If currentTypeDeclaration = oldTypeDeclaration Return Nothing End Function Public Overloads Overrides Function VisitDelegateDeclaration(ByVal delegateDeclaration As DelegateDeclaration, ByVal data As Object) As Object ' CodeTypeDelegate codeTypeDelegate = new CodeTypeDelegate(delegateDeclaration.Name); ' codeTypeDelegate.Parameters ' ' ((CodeNamespace)namespaceDeclarations.Peek()).Types.Add(codeTypeDelegate); Return Nothing End Function Public Overloads Overrides Function VisitVariableDeclaration(ByVal variableDeclaration As VariableDeclaration, ByVal data As Object) As Object Return Nothing End Function Public Overloads Overrides Function VisitFieldDeclaration(ByVal fieldDeclaration As FieldDeclaration, ByVal data As Object) As Object For i As Integer = 0 To fieldDeclaration.Fields.Count - 1 Dim field As VariableDeclaration = DirectCast(fieldDeclaration.Fields(i), VariableDeclaration) 'this.withEventsFields.Add(field); If (fieldDeclaration.Modifier And Modifiers.[WithEvents]) <> 0 Then End If Dim fieldType As TypeReference = fieldDeclaration.GetTypeForField(i) If fieldType.IsNull Then fieldType = New TypeReference(typeDeclarations.Peek().Name) End If Dim memberField As New CodeMemberField(ConvType(fieldType), field.Name) memberField.UserData("StartLocation") = field.StartLocation.Line memberField.UserData("EndLocation") = field.EndLocation.Line memberField.Attributes = ConvMemberAttributes(fieldDeclaration.Modifier) If Not field.Initializer.IsNull Then memberField.InitExpression = DirectCast(field.Initializer.AcceptVisitor(Me, data), CodeExpression) End If typeDeclarations.Peek().Members.Add(memberField) Next Return Nothing End Function Public Overloads Overrides Function VisitMethodDeclaration(ByVal methodDeclaration As MethodDeclaration, ByVal data As Object) As Object Dim memberMethod As New CodeMemberMethod() memberMethod.Name = methodDeclaration.Name memberMethod.Attributes = ConvMemberAttributes(methodDeclaration.Modifier) memberMethod.UserData("StartLocation") = methodDeclaration.StartLocation.Line memberMethod.UserData("EndLocation") = methodDeclaration.EndLocation.Line If methodDeclaration.Body IsNot Nothing AndAlso Not (TypeOf methodDeclaration.Body Is NullBlockStatement) Then memberMethod.UserData("EndLocation") = methodDeclaration.Body.EndLocation.Line End If 'codeStack.Push(memberMethod.Statements); typeDeclarations.Peek().Members.Add(memberMethod) ' Add Method Parameters For Each parameter As ParameterDeclarationExpression In methodDeclaration.Parameters memberMethod.Parameters.Add(DirectCast(VisitParameterDeclarationExpression(parameter, data), CodeParameterDeclarationExpression)) Next 'variables.Clear(); 'methodDeclaration.Body.AcceptChildren(this, data); 'codeStack.Pop(); Return Nothing End Function Public Overloads Overrides Function VisitEventDeclaration(ByVal eventDeclaration As EventDeclaration, ByVal data As Object) As Object Dim memberMethod As New CodeMemberEvent() memberMethod.Name = eventDeclaration.Name memberMethod.Attributes = ConvMemberAttributes(eventDeclaration.Modifier) memberMethod.UserData("StartLocation") = eventDeclaration.StartLocation.Line memberMethod.UserData("EndLocation") = eventDeclaration.EndLocation.Line typeDeclarations.Peek().Members.Add(memberMethod) ' Add Method Parameters 'foreach (ParameterDeclarationExpression parameter in eventDeclaration.Parameters) '{ ' memberMethod.Parameters.Add((CodeParameterDeclarationExpression)VisitParameterDeclarationExpression(parameter, data)); '} Return Nothing End Function Public Overloads Overrides Function VisitPropertyDeclaration(ByVal propertyDeclaration As PropertyDeclaration, ByVal data As Object) As Object Dim memberMethod As New CodeMemberProperty() memberMethod.Name = propertyDeclaration.Name memberMethod.Attributes = ConvMemberAttributes(propertyDeclaration.Modifier) memberMethod.UserData("StartLocation") = propertyDeclaration.StartLocation.Line memberMethod.UserData("EndLocation") = propertyDeclaration.BodyEnd.Line typeDeclarations.Peek().Members.Add(memberMethod) ' Add Method Parameters For Each parameter As ParameterDeclarationExpression In propertyDeclaration.Parameters memberMethod.Parameters.Add(DirectCast(VisitParameterDeclarationExpression(parameter, data), CodeParameterDeclarationExpression)) Next Return Nothing End Function Public Overloads Overrides Function VisitConstructorDeclaration(ByVal constructorDeclaration As ConstructorDeclaration, ByVal data As Object) As Object Dim memberMethod As CodeMemberMethod = New CodeConstructor() 'codeStack.Push(memberMethod.Statements); typeDeclarations.Peek().Members.Add(memberMethod) 'constructorDeclaration.Body.AcceptChildren(this, data); 'codeStack.Pop(); For Each parameter As ParameterDeclarationExpression In constructorDeclaration.Parameters memberMethod.Parameters.Add(DirectCast(VisitParameterDeclarationExpression(parameter, data), CodeParameterDeclarationExpression)) Next Return Nothing End Function Public Overloads Overrides Function VisitParameterDeclarationExpression(ByVal parameterDeclarationExpression As ParameterDeclarationExpression, ByVal data As Object) As Object Return New CodeParameterDeclarationExpression(ConvType(parameterDeclarationExpression.TypeReference), parameterDeclarationExpression.ParameterName) End Function End Class End Namespace