-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Description
The 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} )); }" );