Search code examples
c#sqliteactiverecordt4sharpdevelop

T4 template generation error when trying to execute subsonic's activerecord in sharpdevelop


Hello,
I'm trying to get subsonic to work win SQLite in sharpdevelop (Active record approach).
I'm having some issues with generating the code from the T4 templates.

It throws this error: Blocks are not permitted after helpers - SQLiteTest.tt

If I remove the <#@ include file="SQLite.ttinclude" #> line it doesn't throw the error anymore, but of course it doesn't work.

The error must be somewhere in the SQLite.ttinclude or Settings.ttinclude I've looked through the ttinclude files but I have no idea what blocks or helpers are.

Do you have any idea about what might be the cause of the error? Apparently mono develop T4 generator throws the same error but not Visual Studio's one.


Solution

  • It's a bit hard to say what they mean with Helper/Block as Visual Studio T4 refers the different segments as as Statement, Expression, BoilerPlate and ClassFeature IIRC.

    While checking the source code for Mono T4 I would however guess that Block refers to Statements and Helpers refers to ClassFeatures.

    T4 example:

    <# // This is a Statement #>
    <#+ // This is a ClassFeature #>
    

    It's true that Statements can't appear below ClassFeatures in T4 but what I am thinking is happening here is that Visual Studio T4 does "smart" merging of ttinclude files. It's possible that Mono T4 doesn't.

    To see why consider these two T4 files.

    Example T4.ttinclude:

    <# // 1. This is a Statement #>
    <#+ // 1. This is a ClassFeature #>
    

    Example T4.tt

    <# // 2. This is a Statement #>
    <#+ // 2. This is a ClassFeature #>
    <#@ include file="T4.ttinclude" #>
    

    A straightforward implementation of include would just merge the file:

    <# // 2. This is a Statement #>
    <#+ // 2. This is a ClassFeature #>
    <# // 1. This is a Statement #>
    <#+ // 1. This is a ClassFeature #>
    

    But this is an illegal T4 template so what Visual Studio T4 does (to my knowledge) is merging the files into this which is legal:

    <# // 1. This is a Statement #>
    <# // 2. This is a Statement #>
    <#+ // 1. This is a ClassFeature #>
    <#+ // 2. This is a ClassFeature #>
    

    So if I am allowed to make a guess is that Mono T4 includes file using the straightforward approach but the SubSonic templates are design for Visual Studio T4 which uses a slightly more refined include strategy.

    If this is the reason you would need to

    1. Refactor SQLLite.ttinclude or Settings.ttinclude to only use ClassFeatures. That is probably a major refactoring as having Statements in a .ttinclude file is very convenient.
    2. Refactor Mono T4 to do something similar as Visual Studio T4

    Neither is good news I fear.

    PS. While reading the Mono code it seems the dev considered this:

    //TODO: are blocks permitted after helpers?  
    throw new ParserException ("Blocks are not permitted after helpers", seg.StartLocation);