Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 2 additions & 28 deletions src/MLIR.Generators/DialectSourceEmitter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -361,38 +361,12 @@ private static void AppendBodySyntaxFields(List<BodySyntaxField> fields, HashSet

private static string GenerateDelimitedNamedAttributeWriteTo(string fieldName)
{
return
" if (" + fieldName + ".OpenToken != null)\n" +
" {\n" +
" writer.WriteToken(" + fieldName + ".OpenToken.Value, \" \");\n" +
" for (var i = 0; i < " + fieldName + ".Count; i++)\n" +
" {\n" +
" if (i > 0)\n" +
" {\n" +
" writer.WriteToken(" + fieldName + ".SeparatorTokens[i - 1], string.Empty);\n" +
" }\n" +
" " + fieldName + "[i].WriteTo(writer, i > 0 ? \" \" : string.Empty);\n" +
" }\n" +
" writer.WriteToken(" + fieldName + ".CloseToken!.Value, string.Empty);\n" +
" }\n";
return " writer.WriteDelimitedList(" + fieldName + ", \" \");\n";
}

private static string GenerateDelimitedTokenWriteTo(string fieldName)
{
return
" if (" + fieldName + ".OpenToken != null)\n" +
" {\n" +
" writer.WriteToken(" + fieldName + ".OpenToken.Value, \" \");\n" +
" for (var i = 0; i < " + fieldName + ".Count; i++)\n" +
" {\n" +
" if (i > 0)\n" +
" {\n" +
" writer.WriteToken(" + fieldName + ".SeparatorTokens[i - 1], string.Empty);\n" +
" }\n" +
" writer.WriteToken(" + fieldName + "[i], i > 0 ? \" \" : string.Empty);\n" +
" }\n" +
" writer.WriteToken(" + fieldName + ".CloseToken!.Value, string.Empty);\n" +
" }\n";
return " writer.WriteDelimitedList(" + fieldName + ", \" \");\n";
}

private static string GetPunctuationFieldName(TokenKind tokenKind)
Expand Down
16 changes: 1 addition & 15 deletions src/MLIR/Syntax/BlockSyntax.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,21 +89,7 @@ public void WriteTo(
{
writer.WriteToken(LabelToken, "\n", blockIndentLevel);

if (Arguments.OpenToken != null)
{
writer.WriteToken(Arguments.OpenToken.Value, string.Empty);
for (var i = 0; i < Arguments.Count; i++)
{
if (i > 0)
{
writer.WriteToken(Arguments.SeparatorTokens[i - 1], string.Empty);
}

Arguments[i].WriteTo(writer, i > 0 ? " " : string.Empty);
}

writer.WriteToken(Arguments.CloseToken!.Value, string.Empty);
}
writer.WriteDelimitedList(Arguments, string.Empty);

writer.WriteToken(ColonToken, string.Empty);
}
Expand Down
38 changes: 38 additions & 0 deletions src/MLIR/Syntax/DelimitedSyntaxList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@
/// </summary>
public SyntaxToken? CloseToken { get; } = closeToken;

/// <summary>
/// Gets a value indicating whether this list is present in the source, i.e., has an opening delimiter token.
/// </summary>
public bool IsPresent => OpenToken.HasValue;

/// <summary>
/// Gets the number of items in the list.
/// </summary>
Expand All @@ -51,6 +56,39 @@
/// <param name="index">The item index.</param>
public T this[int index] => Items[index];

/// <summary>
/// Writes this list to the supplied syntax writer if an opening delimiter token is present.
/// Writes the opening delimiter, then each element (interleaved with separator tokens), then
/// the closing delimiter. When <see cref="IsPresent"/> is <see langword="false"/> this method
/// does nothing.
/// </summary>
/// <param name="writer">The syntax writer to write to.</param>
/// <param name="openLeadingTrivia">The fallback leading trivia to use for the opening delimiter token.</param>
/// <param name="writeElement">A delegate that writes a single element to the writer.</param>
public void WriteTo(
Text.SyntaxWriter writer,
string openLeadingTrivia,
System.Action<T, Text.SyntaxWriter, string> writeElement)
{
if (!IsPresent)
{
return;
}

writer.WriteToken(OpenToken.Value, openLeadingTrivia);

Check warning on line 78 in src/MLIR/Syntax/DelimitedSyntaxList.cs

View workflow job for this annotation

GitHub Actions / build-and-test

Nullable value type may be null.

Check warning on line 78 in src/MLIR/Syntax/DelimitedSyntaxList.cs

View workflow job for this annotation

GitHub Actions / build-and-test

Nullable value type may be null.
for (var i = 0; i < Count; i++)
{
if (i > 0)
{
writer.WriteToken(SeparatorTokens[i - 1], string.Empty);
}

writeElement(Items[i], writer, i > 0 ? " " : string.Empty);
}

writer.WriteToken(CloseToken!.Value, string.Empty);
}

/// <summary>
/// Returns an enumerator over the list items.
/// </summary>
Expand Down
45 changes: 3 additions & 42 deletions src/MLIR/Syntax/GenericOperationBodySyntax.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,55 +79,16 @@ public override bool TryGetGenericBody(out GenericOperationBodySyntax? genericBo
/// <inheritdoc/>
public override void WriteTo(Text.SyntaxWriter writer, int indentLevel)
{
writer.WriteToken(OperandList.OpenToken!.Value, string.Empty);
for (var i = 0; i < OperandList.Count; i++)
{
if (i > 0)
{
writer.WriteToken(OperandList.SeparatorTokens[i - 1], string.Empty);
}

writer.WriteToken(OperandList[i], i > 0 ? " " : string.Empty);
}

writer.WriteToken(OperandList.CloseToken!.Value, string.Empty);

if (SuccessorList.OpenToken != null)
{
writer.WriteToken(SuccessorList.OpenToken.Value, " ");
for (var i = 0; i < SuccessorList.Count; i++)
{
if (i > 0)
{
writer.WriteToken(SuccessorList.SeparatorTokens[i - 1], string.Empty);
}
writer.WriteDelimitedList(OperandList, string.Empty);

writer.WriteToken(SuccessorList[i], i > 0 ? " " : string.Empty);
}

writer.WriteToken(SuccessorList.CloseToken!.Value, string.Empty);
}
writer.WriteDelimitedList(SuccessorList, " ");

foreach (var region in Regions)
{
writer.WriteRegion(region, indentLevel);
}

if (Attributes.OpenToken != null)
{
writer.WriteToken(Attributes.OpenToken.Value, " ");
for (var i = 0; i < Attributes.Count; i++)
{
if (i > 0)
{
writer.WriteToken(Attributes.SeparatorTokens[i - 1], string.Empty);
}

Attributes[i].WriteTo(writer, i > 0 ? " " : string.Empty);
}

writer.WriteToken(Attributes.CloseToken!.Value, string.Empty);
}
writer.WriteDelimitedList(Attributes, " ");

if (TypeSignatureColonToken != null && TypeSignatureSyntax != null)
{
Expand Down
33 changes: 33 additions & 0 deletions src/MLIR/Text/SyntaxWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,39 @@ public void WriteBlock(BlockSyntax block, int regionIndentLevel)
block.WriteTo(this, regionIndentLevel);
}

/// <summary>
/// Writes a delimited list of syntax tokens.
/// Does nothing when <paramref name="list"/> has no opening delimiter token.
/// </summary>
/// <param name="list">The delimited token list to write.</param>
/// <param name="openLeadingTrivia">The fallback leading trivia for the opening delimiter token.</param>
public void WriteDelimitedList(DelimitedSyntaxList<SyntaxToken> list, string openLeadingTrivia)
{
list.WriteTo(this, openLeadingTrivia, static (token, writer, trivia) => writer.WriteToken(token, trivia));
}

/// <summary>
/// Writes a delimited list of named attribute syntax nodes.
/// Does nothing when <paramref name="list"/> has no opening delimiter token.
/// </summary>
/// <param name="list">The delimited attribute list to write.</param>
/// <param name="openLeadingTrivia">The fallback leading trivia for the opening delimiter token.</param>
public void WriteDelimitedList(DelimitedSyntaxList<NamedAttributeSyntax> list, string openLeadingTrivia)
{
list.WriteTo(this, openLeadingTrivia, static (attr, writer, trivia) => attr.WriteTo(writer, trivia));
}

/// <summary>
/// Writes a delimited list of block argument syntax nodes.
/// Does nothing when <paramref name="list"/> has no opening delimiter token.
/// </summary>
/// <param name="list">The delimited block argument list to write.</param>
/// <param name="openLeadingTrivia">The fallback leading trivia for the opening delimiter token.</param>
public void WriteDelimitedList(DelimitedSyntaxList<BlockArgumentSyntax> list, string openLeadingTrivia)
{
list.WriteTo(this, openLeadingTrivia, static (arg, writer, trivia) => arg.WriteTo(writer, trivia));
}

/// <summary>
/// Writes a token using its preserved trivia when present, or synthesized trivia otherwise.
/// </summary>
Expand Down
35 changes: 35 additions & 0 deletions tests/MLIR.Tests/ConstructionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -196,4 +196,39 @@ [new SyntaxToken("%0")],
Assert.True(module.Operations[0].HasCustomAssemblyBody);
Assert.Equal("0", module.Operations[0].Attributes[0].RawValue.Text);
}

[Fact]
public void DelimitedSyntaxListWriteToWritesAllTokensAndElements()
{
var list = new DelimitedSyntaxList<BlockArgumentSyntax>(
new SyntaxToken("("),
[
new BlockArgumentSyntax(new SyntaxToken("%arg0"), new SyntaxToken(":"), new RawTypeSyntax(new RawSyntaxText("i32"))),
new BlockArgumentSyntax(new SyntaxToken("%arg1"), new SyntaxToken(":"), new RawTypeSyntax(new RawSyntaxText("i64"))),
],
[new SyntaxToken(",")],
new SyntaxToken(")"));

var writer = new SyntaxWriter();
writer.WriteDelimitedList(list, string.Empty);

Assert.Equal("(%arg0: i32, %arg1: i64)", writer.ToString());
}

[Fact]
public void DelimitedSyntaxListWriteToDoesNothingWhenNotPresent()
{
var list = new DelimitedSyntaxList<BlockArgumentSyntax>(
null,
[],
[],
null);

Assert.False(list.IsPresent);

var writer = new SyntaxWriter();
writer.WriteDelimitedList(list, string.Empty);

Assert.Equal(string.Empty, writer.ToString());
}
}
Loading