(Idea) Templates for code. ("active" parts considered by some as macros)
See original GitHub issueThe use of this is a little specialised, mainly aimed at code that manipulates and analyses sourcecode. Basic concept is to allow the coder to write the code they what to make as a Code Template and the compiler generates to code Roslyn’s AST needed to make it.
How these would be expressed in code is up for discussion, as a base to start from I’m use the following. The type Expr<T>
denotes an expression that evaluates to a T
, a statement would be an Expr<Void>
…
Codeplex Thread: Template Functions & Template Masks
Template Function
template IFExpression _IF_ ( Expr<Bool> cond, Expr truecode, Expr falsecode )
{
if( /{ cond : Expr<Bool> }/ )
{
/{ truecode }/
}
else
{
/{ falsecode }/
}
}
Template Mask
This example will use template functions and template mask to replace If - Else structure to Inline if structure.
This template mask matches against assignments.
template mask simple_assignment() : template_mask
{
|{ /{ target }/ = /{ source }/ ; |}
}
This template generates an assignment that utilises and inline if expression. cond ? true : false
template assignment_viaCondition_ <T>( target : __ , cond : Expr<Bool> ,
valueA : Expr<T> , valueB : Expr<T> ) : CS.Expr
{
|{ var /{ target }/ = (/{ cond }/ ) ? ( /{ valueA }/ ) : ( /{ valueB }/ ) ; |}
}
The following template mask matches against the if else construct.
template mask _IfElse_() : template_mask
{
|{ if( /{ cond }/
{
/{ on_true }/
}
else
{
/{ on_false }/
}
}|
}
So let’s utilise the previously construct templates and template masks.
AnalyseNode ( node : SyntaxNode )
{
var mn = template.Match( node , _IfElse_ )
if( !mn.Valid ) return
var part_0 = template.Match( mn["on_true"], simple_assignment )
var part_1 = template.Match( mn["on_false"], simple_assignment )
if( part_0.Valid && part_1.Valid )
{
if( part_0["target"] == part_1["target"] )
{
node.ReplaceWith( assignment_viaCondition_( part_0["target"] , mn["cond"] , part_0["source"], part_1["source"] );
}
}
}
Some of the functionality of Template Function can be implemented with the use of String Interpolation. Eg
SyntaxFactory.ParseExpression(
$"if( \{parameter.Identifier} == null ) { throw newArgumentNullException( nameof( \{parameter.IdentifieIdentifier.Text} )); }" );
Issue Analytics
- State:
- Created 9 years ago
- Reactions:1
- Comments:7 (4 by maintainers)
Top GitHub Comments
Closing, as we do not want to add a macro system to C# of VB.net.
@gafter It not entirely about macros. It’s also about design-time code template (akin to VS snippets). It would allow “snippets” to be within a specific namespace, and not global. (In fact the current snippets ain’t local, they are Visual Studio local. They are not tied to a specific project type, or even aware of the context they are to be pasted in (eg. #7858)
Yeah you could implement them as a code fix, but to that seem like a lot of code. Just to paste in section of code. In principle the ide and compiler can conspire together and automatically do the work for you.
We could also have usage attributes associated with the template, so that the IDE would be informed to when to suggest the snippet.