编译单元使用解析的"For"/"Next"语句

本文关键字:quot For 语句 Next 单元 编译 | 更新日期: 2023-09-27 18:04:48

我面临一个问题,当我创建一个虚拟的命名空间,类和子,并为for/Next循环添加解析语句时,它在我的编译单元的NormalizeWhitespace方法上崩溃。

IndexOutOfRangeException
Index was outside the bounds of the array.
at System.Collections.Immutable.ImmutableArray`1.Builder.get_Item(Int32 index)
at Microsoft.CodeAnalysis.VisualBasic.Syntax.SyntaxNormalizer.GetIdentation(Int32 count)
at Microsoft.CodeAnalysis.VisualBasic.Syntax.SyntaxNormalizer.RewriteTrivia(SyntaxTriviaList triviaList, Int32 depth, Boolean isTrailing, Boolean mustBeIndented, Boolean mustHaveSeparator, Int32 lineBreaksAfter, Int32 lineBreaksBefore)
at Microsoft.CodeAnalysis.VisualBasic.Syntax.SyntaxNormalizer.VisitToken(SyntaxToken token)
at Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxRewriter.VisitEndBlockStatement(EndBlockStatementSyntax node)
at Microsoft.CodeAnalysis.VisualBasic.Syntax.SyntaxNormalizer.VisitEndBlockStatement(EndBlockStatementSyntax node)
at Microsoft.CodeAnalysis.VisualBasic.Syntax.EndBlockStatementSyntax.Accept[TResult](VisualBasicSyntaxVisitor`1 visitor)
at Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxRewriter.Visit(SyntaxNode node)
at Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxRewriter.VisitNamespaceBlock(NamespaceBlockSyntax node)
at Microsoft.CodeAnalysis.VisualBasic.Syntax.SyntaxNormalizer.VisitNamespaceBlock(NamespaceBlockSyntax node)
at Microsoft.CodeAnalysis.VisualBasic.Syntax.NamespaceBlockSyntax.Accept[TResult](VisualBasicSyntaxVisitor`1 visitor)
at Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxRewriter.Visit(SyntaxNode node)
at Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxRewriter.VisitListElement[TNode](TNode node)
at Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxRewriter.VisitList[TNode](SyntaxList`1 list)
at Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxRewriter.VisitCompilationUnit(CompilationUnitSyntax node)
at Microsoft.CodeAnalysis.VisualBasic.Syntax.SyntaxNormalizer.VisitCompilationUnit(CompilationUnitSyntax node)
at Microsoft.CodeAnalysis.VisualBasic.Syntax.CompilationUnitSyntax.Accept[TResult](VisualBasicSyntaxVisitor`1 visitor)
at Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxRewriter.Visit(SyntaxNode node)
at Microsoft.CodeAnalysis.VisualBasic.Syntax.SyntaxNormalizer.Normalize[TNode](TNode node, String indentWhitespace, String eolWhitespace, Boolean useElasticTrivia, Boolean useDefaultCasing)
at Microsoft.CodeAnalysis.VisualBasic.SyntaxExtensions.NormalizeWhitespace[TNode](TNode node, Boolean useDefaultCasing, String indentation, Boolean elasticTrivia)
at UserQuery.Main()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
下面是要复制的代码:
public void Main()
{
   var compilationUnit = SyntaxFactory.CompilationUnit();
   compilationUnit = compilationUnit.AddMembers(this.CreateNamespaceDeclaration());
   compilationUnit = compilationUnit.NormalizeWhitespace(true, "'r'n", false);
   compilationUnit.ToFullString().Dump();
}
public string[] StatementList = { "For i As Integer = 0 To 10", "Dim v = 0", "Next" };
// Define other methods and classes here
private NamespaceBlockSyntax CreateNamespaceDeclaration()
{
    return SyntaxFactory.NamespaceBlock(
        SyntaxFactory.NamespaceStatement(
        SyntaxFactory.IdentifierName("Test")))
        .WithMembers(
            SyntaxFactory.SingletonList<StatementSyntax>(
                SyntaxFactory.ClassBlock(
                SyntaxFactory.ClassStatement("VBCrash")
                .WithModifiers(
                    SyntaxFactory.TokenList(
                        SyntaxFactory.Token(SyntaxKind.PublicKeyword))))
        .WithImplements(SyntaxFactory.List<ImplementsStatementSyntax>())
        .WithMembers(SyntaxFactory.List<StatementSyntax>(
                SyntaxFactory.List<StatementSyntax>()
                .Add(SyntaxFactory.SubBlock(
                SyntaxFactory.SubStatement("Main"))
            .AddStatements(this.AddStatements()))))));
}

private StatementSyntax[] AddStatements()
{
    var result = default(SyntaxList<StatementSyntax>);
    foreach (var statement in StatementList)
    {
        result = result.Add(SyntaxFactory.ParseExecutableStatement(statement));
    }
    return result.ToArray();
}

我做错了什么吗?每当我为语句注释foreach循环时,它就会工作。

谢谢你的帮助

编译单元使用解析的"For"/"Next"语句

您的语法树形状不合法。解析块语句有结构;您不能像这样一次解析一行,然后将它们分组在一起,并期望从中得到一个有意义的树。(我想你在你的另一个问题中也做了同样的事情,这也会造成问题。)您应该一次解析所有这些语句,而不是一次解析一个。同样,如果需要顶级语句,请使用脚本解析模式。

不过,格式化程序不应该像这样崩溃。