Skip to content

(Idea) Templates for code. ("active" parts considered by some as macros) #174

@AdamSpeight2008

Description

@AdamSpeight2008

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} )); }" );

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions