@@ -185,6 +185,10 @@ private void GenerateStmt(BindingContext ctx)
185185 managedCodeGen . GenerateDeclarations ( ) ;
186186 WriteFile ( managedCodeGen , Path . Combine ( "AST" , "Stmt.cs" ) ) ;
187187
188+ managedCodeGen = new ManagedVisitorCodeGenerator ( ctx , decls . Union ( ExprClasses ) ) ;
189+ managedCodeGen . Process ( ) ;
190+ WriteFile ( managedCodeGen , Path . Combine ( "AST" , "StmtVisitor.cs" ) ) ;
191+
188192 managedCodeGen = new StmtASTConverterCodeGenerator ( ctx , decls , stmtClassEnum ) ;
189193 managedCodeGen . Process ( ) ;
190194 WriteFile ( managedCodeGen , Path . Combine ( "Parser" , "ASTConverter.Stmt.cs" ) ) ;
@@ -267,6 +271,9 @@ public override bool VisitClassDecl(Class @class)
267271 // Statements
268272 //
269273
274+ if ( CodeGeneratorHelpers . IsAbstractStmt ( @class ) )
275+ @class . IsAbstract = true ;
276+
270277 if ( @class . Name . EndsWith ( "Bitfields" ) )
271278 @class . ExplicitlyIgnore ( ) ;
272279
@@ -529,11 +536,32 @@ public override bool VisitClassDecl(Class @class)
529536 WriteLine ( $ "public { typeName } { propertyName } {{ get; set; }}") ;
530537 }
531538
539+ var rootBase = @class . GetNonIgnoredRootBase ( ) ;
540+ var isStmt = rootBase != null && rootBase . Name == "Stmt" ;
541+
542+ if ( isStmt && ! ( @class . IsAbstract && @class . Name != "Stmt" ) )
543+ {
544+ NewLine ( ) ;
545+ GenerateVisitMethod ( @class ) ;
546+ }
547+
532548 UnindentAndWriteCloseBrace ( ) ;
533549
534550 return true ;
535551 }
536552
553+ private void GenerateVisitMethod ( Class @class )
554+ {
555+ if ( @class . IsAbstract )
556+ {
557+ WriteLine ( "public abstract T Visit<T>(IStmtVisitor<T> visitor);" ) ;
558+ return ;
559+ }
560+
561+ WriteLine ( "public override T Visit<T>(IStmtVisitor<T> visitor) =>" ) ;
562+ WriteLineIndent ( "visitor.Visit{0}(this);" , @class . Name ) ;
563+ }
564+
537565 public override string GetBaseClassTypeName ( BaseClassSpecifier @base )
538566 {
539567 var type = base . GetBaseClassTypeName ( @base ) ;
@@ -563,6 +591,77 @@ public override void GenerateNamespaceFunctionsAndVariables(
563591 }
564592 }
565593
594+ class ManagedVisitorCodeGenerator : ManagedParserCodeGenerator
595+ {
596+ public ManagedVisitorCodeGenerator ( BindingContext context ,
597+ IEnumerable < Declaration > declarations )
598+ : base ( context , declarations )
599+ {
600+ }
601+
602+ public override void Process ( )
603+ {
604+ GenerateFilePreamble ( CommentKind . BCPL ) ;
605+ NewLine ( ) ;
606+
607+ WriteLine ( "namespace CppSharp.AST" ) ;
608+ WriteOpenBraceAndIndent ( ) ;
609+
610+ GenerateVisitor ( ) ;
611+ NewLine ( ) ;
612+
613+ GenerateVisitorInterface ( ) ;
614+
615+ UnindentAndWriteCloseBrace ( ) ;
616+ }
617+
618+ private void GenerateVisitor ( )
619+ {
620+ WriteLine ( $ "public abstract partial class AstVisitor") ;
621+ WriteOpenBraceAndIndent ( ) ;
622+
623+ foreach ( var @class in Declarations . OfType < Class > ( ) )
624+ {
625+ if ( @class . Name == "Stmt" ) continue ;
626+
627+ PushBlock ( ) ;
628+ var paramName = "stmt" ;
629+ WriteLine ( "public virtual bool Visit{0}({0} {1})" ,
630+ @class . Name , paramName ) ;
631+ WriteOpenBraceAndIndent ( ) ;
632+
633+ var visitName = @class . BaseClass != null ?
634+ @class . BaseClass . Name : "Stmt" ;
635+
636+ WriteLine ( $ "if (!Visit{ @class . BaseClass . Name } ({ paramName } ))") ;
637+ WriteLineIndent ( "return false;" ) ;
638+ NewLine ( ) ;
639+
640+ WriteLine ( "return true;" ) ;
641+
642+ UnindentAndWriteCloseBrace ( ) ;
643+ PopBlock ( NewLineKind . BeforeNextBlock ) ;
644+ }
645+
646+ UnindentAndWriteCloseBrace ( ) ;
647+ }
648+
649+ private void GenerateVisitorInterface ( )
650+ {
651+ WriteLine ( $ "public interface IStmtVisitor<out T>") ;
652+ WriteOpenBraceAndIndent ( ) ;
653+
654+ foreach ( var @class in Declarations . OfType < Class > ( ) )
655+ {
656+ var paramName = "stmt" ;
657+ WriteLine ( "T Visit{0}({0} {1});" ,
658+ @class . Name , paramName ) ;
659+ }
660+
661+ UnindentAndWriteCloseBrace ( ) ;
662+ }
663+ }
664+
566665 class ASTConverterCodeGenerator : ManagedParserCodeGenerator
567666 {
568667 readonly Enumeration StmtClassEnum ;
0 commit comments