in src/Bicep.Core/PrettyPrint/DocumentBuildVisitor.cs [329:431]
public override void VisitTypedLocalVariableSyntax(TypedLocalVariableSyntax syntax) =>
this.BuildWithSpread(() => base.VisitTypedLocalVariableSyntax(syntax));
public override void VisitLambdaSyntax(LambdaSyntax syntax) =>
this.BuildWithSpread(() => base.VisitLambdaSyntax(syntax));
public override void VisitTypedLambdaSyntax(TypedLambdaSyntax syntax) =>
this.BuildWithSpread(() => base.VisitTypedLambdaSyntax(syntax));
private void VisitCommaAndNewLineSeparated(ImmutableArray<SyntaxBase> nodes, bool leadingAndTrailingSpace)
{
if (nodes.Length == 1 && nodes[0] is Token { Type: TokenType.NewLine })
{
this.Build(() => this.Visit(nodes[0]), children =>
{
if (children.Length == 1)
{
if (children[0] == Line || children[0] == SingleLine || children[0] == DoubleLine)
{
return Nil;
}
// Trailing comment.
return children[0];
}
return new NestDocument(1, [.. children]);
});
return;
}
SyntaxBase? leadingNewLine = null;
if (nodes.Length > 0 && nodes[0] is Token { Type: TokenType.NewLine })
{
leadingNewLine = nodes[0];
nodes = nodes.RemoveAt(0);
}
SyntaxBase? trailingNewLine = null;
if (nodes.Length > 0 && nodes[^1] is Token { Type: TokenType.NewLine })
{
trailingNewLine = nodes[^1];
nodes = nodes.RemoveAt(nodes.Length - 1);
}
this.Build(() =>
{
this.Visit(leadingNewLine);
if (leadingAndTrailingSpace && nodes.Any() && leadingNewLine is null)
{
this.PushDocument(Space);
}
for (var i = 0; i < nodes.Length; i++)
{
var visitingBrokenStatement = this.visitingBrokenStatement;
if (this.HasSyntaxError(nodes[i]))
{
this.visitingBrokenStatement = true;
}
this.Visit(nodes[i]);
if (!this.visitingBrokenStatement)
{
if (i < nodes.Length - 1 &&
nodes[i] is Token { Type: TokenType.Comma } &&
nodes[i + 1] is not Token { Type: TokenType.NewLine })
{
this.PushDocument(Space);
}
}
this.visitingBrokenStatement = visitingBrokenStatement;
}
if (leadingAndTrailingSpace && nodes.Any() && trailingNewLine is null)
{
this.PushDocument(Space);
}
this.Visit(trailingNewLine);
}, children =>
{
// This logic ensures that syntax with only a single child is not doubly-nested,
// and that the final newline does not cause the next piece of text to be indented
// e.g. 'bar' in the following is only indented once, and '})' is not indented:
// foo({
// bar: 123
// })
var hasTrailingNewline = trailingNewLine is not null;
var nestedChildren = Concat(hasTrailingNewline ? children[..^1] : children);
var newLine = hasTrailingNewline ? children[^1] : Nil;
// Do not call Nest() if we are inside a broken statement, otherwise it will keep on indenting further when the user formats document.
if (!this.visitingBrokenStatement && children.Length > 1)
{
nestedChildren = nestedChildren.Nest();
}
return Concat(nestedChildren, newLine);
});
}