You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
An expression body that writes only a comment or directives still renders int P => ;// TODO (CS1525): the #175 guard checks only for blank lines #184
#178 (for #175) refuses an expression body whose callback writes nothing. A callback that writes only a comment, or only preprocessor directives, gets through and produces the same => ;:
Input
Output
ExpressionBodyFactory = b => b.WriteLine("// TODO")
ExpressionBodyFactory = b => { b.WriteLine("#if DEBUG"); b.WriteLine("#endif"); }
int P => #if DEBUG #endif ;
All three fail with CS1525 (invalid expression term ;). Reproduced against main @ aa7ca53, and the generated code was compiled to confirm the errors.
Why
RenderExpression (CodeBlocker/Templates/TemplateRendering.cs:341) throws only when every line is whitespace (lines.All(string.IsNullOrWhiteSpace)). When no line holds code, FindTerminatedLine (:429-446) stops at the first line, and Terminate (:527-537) puts the semicolon in front of the comment.
A placeholder like // TODO as the whole body is a common pattern while scaffolding generated code, so this is easy to hit.
Suggested fix
In RenderExpression, also throw when !HasCode(lines), using the existing HasCode / FindCodeEnds helpers. That gives a body made only of comments or directives the same InvalidOperationException and message as an empty one.
Priority: Medium. The output does not compile (CS1525), so the failure shows up at build time rather than going unnoticed. A // TODO placeholder is a common scaffolding pattern, so it is easy to hit.
Activity
matt-edmondson commentedon Nov 5, 2026
Triage
// TODOplaceholder is a common scaffolding pattern, so it is easy to hit.TemplateRendering.RenderExpression,HasCode/FindCodeEnds!HasCode(lines)). Do it together with A class with an empty expression-bodied property is still written with its closing brace, minus that member and everything after it (#164 again, since #178) #183 so the check runs fromValidate().int P => ;/get => ;(CS1525), the output Validate says it prevents #175/Refuse an expression body that writes no expression, before writing [patch] #178 and is the companion of A class with an empty expression-bodied property is still written with its closing brace, minus that member and everything after it (#164 again, since #178) #183. A method body made only of a/* block comment */is written as no body:void M() /* nothing to do */(CS1002), unlike the//form fixed in #157 #185 handles the/* */variant through the sameHasCodepath. No open PR covers it.Generated by Claude Code