diff --git a/package.json b/package.json
index e386169..0a2b08a 100644
--- a/package.json
+++ b/package.json
@@ -1,5 +1,5 @@
{
"name": "purview-sourcegeneratorframework",
- "version": "1.0.0-prerelease.31",
+ "version": "1.0.0-prerelease.32",
"private": true
}
diff --git a/src/src/SourceGeneratorShared/CodeWriter.cs b/src/src/SourceGeneratorShared/CodeWriter.cs
index 26e9252..691b2d1 100644
--- a/src/src/SourceGeneratorShared/CodeWriter.cs
+++ b/src/src/SourceGeneratorShared/CodeWriter.cs
@@ -632,7 +632,7 @@ public CodeWriter WritePartialMethod(MethodDeclarationOptions declaration)
}
///
- /// Writes a structured partial method declaration.
+ /// Writes an expression-bodied method.
///
/// writer.WriteMethodExpression(new MethodDeclarationOptions("Count", "int") { ExpressionBody = "items.Count" });
public CodeWriter WriteMethodExpression(MethodDeclarationOptions declaration)
@@ -645,8 +645,12 @@ public CodeWriter WriteMethodExpression(MethodDeclarationOptions declaration)
);
}
- // The method is not abstract, so we can use the WriteMethod overload that takes a body callback.
- return WriteMethod(declaration, _ => { });
+ using (WriteMethodScope(declaration))
+ {
+ //
+ }
+
+ return this;
}
///
@@ -3606,6 +3610,8 @@ static void ValidateMethodDeclaration(MethodDeclarationOptions declaration)
throw new ArgumentException("A readonly method cannot also be static.", nameof(declaration));
if (declaration.IsAbstract && declaration.ExpressionBody is not null)
throw new ArgumentException("An abstract method cannot have an expression body.", nameof(declaration));
+ if (declaration.IsPartial && declaration.ExpressionBody is not null)
+ throw new ArgumentException("A partial method cannot have an expression body.", nameof(declaration));
}
static void ValidateOperatorDeclaration(OperatorDeclarationOptions declaration)
diff --git a/src/tests/SourceGeneratorShared.UnitTests/CodeWriterTests.cs b/src/tests/SourceGeneratorShared.UnitTests/CodeWriterTests.cs
index 1d90a12..749b3ed 100644
--- a/src/tests/SourceGeneratorShared.UnitTests/CodeWriterTests.cs
+++ b/src/tests/SourceGeneratorShared.UnitTests/CodeWriterTests.cs
@@ -980,6 +980,146 @@ await Assert
);
}
+ [Test]
+ public async Task WriteMethodExpression_GivenExpressionBody_WritesExpressionBodiedMethod()
+ {
+ // Arrange
+ var writer = CodeWriterFactory.ForTests();
+ var declaration = new MethodDeclarationOptions("Count", Type("int")) { ExpressionBody = "items.Count" };
+
+ // Act
+ writer.WriteMethodExpression(declaration);
+
+ // Assert
+ await Assert.That(writer).Generates(GeneratedAttributes() + "int Count() => items.Count;\n");
+ }
+
+ [Test]
+ [Arguments(null)]
+ [Arguments("")]
+ [Arguments(" ")]
+ public async Task WriteMethodExpression_GivenWhitespaceExpressionBody_ThrowsWithoutWriting(string? expressionBody)
+ {
+ // Arrange
+ var writer = CodeWriterFactory.ForTests();
+ var declaration = new MethodDeclarationOptions("Count", Type("int")) { ExpressionBody = expressionBody };
+
+ // Act / Assert
+ await Assert.That(() => writer.WriteMethodExpression(declaration)).Throws();
+ await Assert.That(writer.ToString()).IsEmpty();
+ }
+
+ [Test]
+ public async Task WriteMethodExpression_GivenCallback_WritesExpressionBodiedMethod()
+ {
+ // Arrange
+ var writer = CodeWriterFactory.ForTests();
+ var declaration = new MethodDeclarationOptions("Count", Type("int"));
+
+ // Act
+ writer.WriteMethodExpression(declaration, expression => expression.Write("items.Count"));
+
+ // Assert
+ await Assert.That(writer).Generates(GeneratedAttributes() + "int Count() => items.Count;\n");
+ }
+
+ [Test]
+ public async Task WriteMethodExpression_GivenNullCallback_Throws()
+ {
+ // Arrange
+ var writer = CodeWriterFactory.ForTests();
+ var declaration = new MethodDeclarationOptions("Count", Type("int"));
+
+ // Act / Assert
+ await Assert.That(() => writer.WriteMethodExpression(declaration, null!)).Throws();
+ }
+
+ [Test]
+ public async Task WriteMethodExpression_GivenExpressionBodyAndCallback_ThrowsWithoutWriting()
+ {
+ // Arrange
+ var writer = CodeWriterFactory.ForTests();
+ var declaration = new MethodDeclarationOptions("Count", Type("int")) { ExpressionBody = "items.Count" };
+
+ // Act / Assert
+ await Assert
+ .That(() => writer.WriteMethodExpression(declaration, expression => expression.Write("items.Count")))
+ .Throws();
+ await Assert.That(writer.ToString()).IsEmpty();
+ }
+
+ [Test]
+ public async Task WriteMethodExpression_GivenPartialDeclaration_ThrowsWithoutWriting()
+ {
+ // Arrange
+ var writer = CodeWriterFactory.ForTests();
+ var declaration = new MethodDeclarationOptions("Count", Type("int"))
+ {
+ IsPartial = true,
+ ExpressionBody = "items.Count",
+ };
+
+ // Act / Assert
+ await Assert.That(() => writer.WriteMethodExpression(declaration)).Throws();
+ await Assert.That(writer.ToString()).IsEmpty();
+ }
+
+ [Test]
+ public async Task WriteMethodExpression_GivenPartialDeclarationAndCallback_ThrowsWithoutWriting()
+ {
+ // Arrange
+ var writer = CodeWriterFactory.ForTests();
+ var declaration = new MethodDeclarationOptions("Count", Type("int")) { IsPartial = true };
+
+ // Act / Assert
+ await Assert
+ .That(() => writer.WriteMethodExpression(declaration, expression => expression.Write("items.Count")))
+ .Throws();
+ await Assert.That(writer.ToString()).IsEmpty();
+ }
+
+ [Test]
+ public async Task WritePartialMethod_GivenExpressionBody_ThrowsWithoutWriting()
+ {
+ // Arrange
+ var writer = CodeWriterFactory.ForTests();
+ var declaration = new MethodDeclarationOptions("Count", Type("int")) { ExpressionBody = "items.Count" };
+
+ // Act / Assert
+ await Assert.That(() => writer.WritePartialMethod(declaration)).Throws();
+ await Assert.That(writer.ToString()).IsEmpty();
+ }
+
+ [Test]
+ public async Task WriteMethod_GivenExpressionBody_ThrowsWithoutWriting()
+ {
+ // Arrange
+ var writer = CodeWriterFactory.ForTests();
+ var declaration = new MethodDeclarationOptions("Count", Type("int")) { ExpressionBody = "items.Count" };
+
+ // Act / Assert
+ await Assert
+ .That(() => writer.WriteMethod(declaration, body => body.WriteLine("return items.Count;")))
+ .Throws();
+ await Assert.That(writer.ToString()).IsEmpty();
+ }
+
+ [Test]
+ public async Task WriteMethod_GivenBodyAndNoExpressionBody_WritesBlockBody()
+ {
+ // Arrange
+ var writer = CodeWriterFactory.ForTests();
+ var declaration = new MethodDeclarationOptions("Count", Type("int"));
+
+ // Act
+ writer.WriteMethod(declaration, body => body.WriteLine("return items.Count;"));
+
+ // Assert
+ await Assert
+ .That(writer)
+ .Generates(GeneratedAttributes() + "int Count()\n" + "{\n" + "\treturn items.Count;\n" + "}\n");
+ }
+
[Test]
public async Task WritePartialMethod_GivenPartialMethods_WritesDeclaration()
{