GeneratorAbortException for custom lpt template

Posts   
 
    
Conrad
User
Posts: 37
Joined: 11-Jan-2008
# Posted on: 24-Apr-2013 02:30:26   

I am trying to generate custom code using include templates. I have followed the example in "Generated code - Adding your own code to the generated classes" in v4 Framework Documentation. I have added a template binding Custom_EntityAdapterTemplate to a file named EntityInclude.lpt. In the lpt file, I have added the following code:

Public Function TestMyFunction() as String Return "Test" End Function

When I Generate source-code, I get the following exception:

Compilation of templates threw errors: Error BC30800, at line: 78, pos: 0: Method arguments must be enclosed in parentheses. Error BC30037, at line: 78, pos: 0: Character is not valid. Error BC30287, at line: 80, pos: 0: '.' expected. Error BC30035, at line: 82, pos: 0: Syntax error. Error BC30072, at line: 83, pos: 0: 'Case' can only appear inside a 'Select Case' statement. Error BC30037, at line: 84, pos: 0: Character is not valid. Error BC30037, at line: 85, pos: 0: Character is not valid. Error BC30072, at line: 86, pos: 0: 'Case' can only appear inside a 'Select Case' statement. Error BC30037, at line: 87, pos: 0: Character is not valid. . . . Error BC30041, at line: 0, pos: 0: Maximum number of errors has been exceeded.

Stack trace: LLBLGen Pro version 4.0. Build April 11th, 2013 -----[Core exception]-------------------- at SD.LLBLGen.Pro.LptParser.DotNetTemplateEngine.CompileForTDLIncludeTemplates(ITask taskDefinition) at SD.LLBLGen.Pro.TaskPerformers.CodeEmitter.Perform(IGenerator executingGenerator, ITask taskDefinition, Dictionary2 parameters) at SD.LLBLGen.Pro.ApplicationCore.CodeGenerationMetaData.Tasks.Task.PerformElement(IGenerator executingGenerator, LogNode parentNode) at SD.LLBLGen.Pro.ApplicationCore.CodeGenerationMetaData.Tasks.TaskGroupElement.Perform(IGenerator executingGenerator, LogNode parentNode) at SD.LLBLGen.Pro.ApplicationCore.CodeGenerationMetaData.Tasks.TaskGroup.PerformElement(IGenerator executingGenerator, LogNode parentNode) at SD.LLBLGen.Pro.ApplicationCore.CodeGenerationMetaData.Tasks.TaskGroupElement.Perform(IGenerator executingGenerator, LogNode parentNode) at SD.LLBLGen.Pro.ApplicationCore.CodeGenerationMetaData.Tasks.TaskGroup.PerformElement(IGenerator executingGenerator, LogNode parentNode) at SD.LLBLGen.Pro.ApplicationCore.CodeGenerationMetaData.Tasks.TaskGroupElement.Perform(IGenerator executingGenerator, LogNode parentNode) at SD.LLBLGen.Pro.GeneratorCore.Generator.RunTasks(String rootNameSpaceToUse, String destinationRootFolder, String groupName) at SD.LLBLGen.Pro.GeneratorCore.Generator.Start(ITaskGroup tasksToExecute, ApplicationConfiguration configurationSettings, Language languageToUse, Platform platformToUse, List1 templateBindingsToUse, String templateGroupToUse, String rootNameSpaceToUse, String destinationRootFolder, Project projectDefinition, CodeGenerationCycleOutputType outputType) at SD.LLBLGen.Pro.GeneratorCore.Generator.Start(ITaskGroup tasksToExecute, CodeGenerationCyclePreferences preferences, ApplicationConfiguration configurationSettings, Project projectDefinition) at SD.LLBLGen.Pro.Gui.Classes.GuiController.PerformRunCodeGenerationCycleAction(ITaskGroup toExecute, CodeGenerationCyclePreferences codeGenerationCyclePreferences, HashSet1 entitiesToUse, HashSet1 spCallsToUse, HashSet1 typedViewsToUse, HashSet1 typedListsToUse, HashSet1 valueTypesToUse, HashSet1 tvfCallsTouse, List`1 vsNetProjectsCreated, LogNode& tasksResultLog)

Any ideas as to what I may be doing wrong? When I use TDL type templates, I do not have a problem generating custom code.

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 24-Apr-2013 07:55:51   
  • How do the .templatebindings and .tasks/.preset files look like?
  • Do you have compileOnly=true on the task?

Take a look at the DotNetTemplateEngine docs, or take a similar template/task/preset built in LLBLGen to mimic the same setup.

David Elizondo | LLBLGen Support Team
Conrad
User
Posts: 37
Joined: 11-Jan-2008
# Posted on: 24-Apr-2013 19:40:49   

My template bindings file looks like this:

<?xml version="1.0"?> <templateBindings xmlns="http://sd/llblgen/pro/templateBindingsDefinition.xsd" name="MyApp.TemplateBindings" description ="Contains template bindings for custom templates" precedenceLevel="11"> <supportedFrameworks> <framework name="LLBLGen Pro Runtime Framework"/> </supportedFrameworks> <supportedPlatforms> <platform name=".NET 3.5"/> <platform name=".NET 4.0"/> </supportedPlatforms> <language name="VB.NET"> <templateBinding templateID="Custom_EntityAdapterTemplate" filename="EntityInclude.lpt" /> </language> </templateBindings>

I am using an unmodified SD.Presets.Adapter.General preset to generate the code. I assume that if I create a binding for Custom_EntityAdapterTemplate, it will be automatically included when I generate code using that preset.

Conrad
User
Posts: 37
Joined: 11-Jan-2008
# Posted on: 24-Apr-2013 20:56:16   

In case it matters, I am using a project that was converted from 2.6 to 4.0.

...Never mind. I just created a brand new project in 4.0, mapped a single table to an entity, added the template binding file and mapping through the GUI and had the same problem.

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 25-Apr-2013 07:34:44   

It's important to see your .task or .preset files for that task because the parameters of the task. It looks like the task performer is actually compiling your code where it should just emit that text, that's why I think you have something you shouldn't in the parameters.

David Elizondo | LLBLGen Support Team
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39760
Joined: 17-Aug-2003
# Posted on: 25-Apr-2013 10:37:22   

<templateBinding templateID="Custom_EntityAdapterTemplate" filename="EntityInclude.lpt" />

this binding misses an important attribute: includeOnly simple_smile . If includeOnly is present, it's compiled in a different class, as the include template isn't a full template, but will be included elsewhere.

Frans Bouma | Lead developer LLBLGen Pro
Conrad
User
Posts: 37
Joined: 11-Jan-2008
# Posted on: 26-Apr-2013 02:22:17   

I have tried to create a simple LLBLGen project that replicates the problem I am having. If you generate code, you should get the error include in the previous message.

Otis - I tried changing the includeOnly option with no success. The sample template I included has a simple method. I will be including much more complicated logic in my real project.

Thanks for your help with this.

Attachments
Filename File size Added on Approval
TestProject.zip 2,838 26-Apr-2013 02:22.29 Approved
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39760
Joined: 17-Aug-2003
# Posted on: 26-Apr-2013 13:06:25   

The code generator appears to inline the template using C# code, which is of course not going to work. We're looking into it.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39760
Joined: 17-Aug-2003
# Posted on: 26-Apr-2013 13:25:20   

It's unfortunate, but .lpt templates can only be written in C#. The problem is that the core framework also has lpt templates starting with v4, and they're all in C#. As all lpt templates are compiled into 1 assembly (and then executed which produces the output) they have to be in C#.

We didn't mention this in the SDK docs, which is an oversight, as we didn't realize this restriction till now. It might be a big restriction for people who migrate to v4 and have a lot of lpt templates in VB.NET. We'll look into whether this is solvable at all, but chances are slim.

I'm sorry to not have a better, easier, answer for you.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39760
Joined: 17-Aug-2003
# Posted on: 26-Apr-2013 13:43:10   

The only solution is to port all our .lpt templates to VB.NET for the sole purpose of customers being able to write lpt templates in VB.NET. (as the output language doesn't matter, you can write .lpt templates in C# which emit VB.NET, as ours do). This is a big maintenance burden so we won't go there, at least not for now.

The restriction is thus: lpt templates have to be written in C#. We can't compile both in separate assemblies (technically this is possible of course) because the templates can refer to each other, which will create a reference cycle, so this can't work in practice: lpt templates have to be in 1 language only, and as there are already lpt templates written in C#, you can't write .lpt templates in VB.NET

Remember, the output language can be anything, so you can write your lpt templates in C# which produce VB.NET. See for an example the lpt templates we use to emit VB.NET code for e.g. the persistenceInfoProvider: the code is in C# and the output is in VB.NET.

If you need help with this, please let us know.

Frans Bouma | Lead developer LLBLGen Pro