Walkthrough: Debugging a Text Template

Before you can debug a text template, you should understand the two steps of the text template transformation process. This is necessary because different classes of errors can occur within each step.

In the first step, the text template transformation engine creates a class called the generated transformation class. In order to create the generated transformation class, the text template transformation engine must be able to parse the text template. In this step, errors in the text template, such as incorrect tags, might prevent it from being parsed.

In the second step, the engine compiles and executes the generated transformation class to produce the output. In this step, errors might prevent the generated transformation class from compiling. For example, you might have written incorrect statement or expression code.

To debug a text template, you must first correct any errors that occur in the first step, in the text template. Then you must correct any errors that occur in the second step, in the generated transformation class.

注意

When you transform a text template, you can get errors from any of three sources: the text template, the generated transformation class, and any directives that you call from within the text template. In this walkthrough you will debug errors in the text template and the generated transformation class, but you can also use these procedures to debug custom directives.

Tasks illustrated in this walkthrough include the following:

  • Creating a domain-specific language solution

  • Creating a text template

  • Debugging an incorrect text template tag

  • Debugging directive calls that access a model from a text template

  • Debugging with the just-in-time debugger

Prerequisites

To complete this walkthrough, you will need:

Creating a Domain-Specific Language Solution

In this procedure, you create a domain-specific language solution. You base your solution on the Minimal Language solution template. However, the procedures demonstrated in this walkthrough apply to all the solution templates.

To create a domain-specific language solution

  1. On the File menu, point to New, and then click Project.

    The New Project dialog box appears.

  2. Under Project types, expand the Other Project Types node, and click Extensibility.

  3. Under Templates, click the Domain-Specific Language Designer template.

  4. In Name, type DebuggingTestLanguage, and click OK.

    The Select Domain-Specific Language Options page opens.

  5. Click Minimal Language, and click Next.

    The Define New Model File Type page opens.

  6. In What extension should model file use?, type ddd, and click Next.

    The Specify product details page opens.

  7. Change the name of the company to Fabrikam, and click Finish.

    The wizard closes, Domain-Specific Language Tools creates your solution, and the solution opens.

    注意

    When you create a project, the system automatically generates the default text templates. When you generate a text template, you will see a message that warns you not to run text templates from untrusted sources. If you do not want this message to appear again, select the Do not show this message again check box, and click OK. Otherwise, click OK.

  8. On the Build menu, click Build Solution.

  9. On the Debug menu, click Start Without Debugging.

    注意

    You must click Start Without Debugging instead of Start Debugging for later steps in this walkthrough to work correctly. By clicking Start Without Debugging, you can debug in a new instance of Visual Studio instead of in your domain-specific language solution. This is important for the later steps.

    A new instance of the Visual Studio experimental build starts and opens the debugging solution. For more information, see Experimental Build.

    注意

    You complete the remainder of this walkthrough in the experimental build.

Creating a Text Template

Next you add a text template to your solution. You will debug this text template in later steps.

To create a text template

  1. On the Project menu, click Add New Item.

    The Add New Item dialog box appears.

  2. Under Visual Studio installed templates, click Text File.

  3. In Name, type DebugTest.tt, and click Add.

    The system adds the file to the project.

  4. In Solution Explorer, click DebugTest.tt.

    警告

    When you add DebugTest.tt to the project, the file is highlighted in Solution Explorer, but it is not selected. If you do not select DebugTest.tt, the following step will not work.

  5. In the Properties window, in the Custom Tool property, type TextTemplatingFileGenerator.

  6. In Solution Explorer, right-click DebugTest.tt, and then click Run Custom Tool.

    The system transforms the text template and generates the corresponding output file. The new file appears in Solution Explorer under the text template file.

Debugging an Incorrect Text Template Tag

A common syntax error when you write text templates is to use an incorrect start or end tag. In this procedure, you will debug an incorrect tag.

To debug an incorrect text template tag

  1. In Solution Explorer, double-click DebugTest.tt to open it in the editor.

  2. Add the following code to DebugTest.tt:

    注意

    The code contains an error. You are introducing the error on purpose to debug it.

    <#@ template language="C#" #>
    <#@ output extension=".txt" #>
    
    <# for (int i = 0; i < 3; i++) { >
    
    Hello, World!
    
    <# } #>
    
    <#@ template language="VB" #>
    <#@ output extension=".txt" #>
    
    <# For i as integer = 1 to 3 >
    
    Hello, World!
    
    <# Next #>
    
  3. In Solution Explorer, right-click DebugTest.tt, and then click Run Custom Tool.

    The Error List window appears and displays this error:

    An unexpected start or end tag was found within a block. Make sure that you did not mis-type a start or end tag, and that you do not have any nested blocks in the template.

    In this case, the error in the code is an incorrect end tag. The # in the end tag is missing.

  4. In Solution Explorer, double-click DebugTest.tt to open it in the editor.

    注意

    You can also double-click the error in the Error List window to jump to the code.

  5. To correct the code, add the # to end tag. The change is highlighted.

    <# for (int i = 0; i < 3; i++) { #>
    
    <# For i as integer = 1 to 3 #>
    
  6. In Solution Explorer, right-click DebugTest.tt, and then click Run Custom Tool.

    Now the system transforms the text template and generates the corresponding output file. You will not see any errors in the Error List window.

Debugging Directive Calls that Access a Model from a Text Template

Before you can access a model from the statements and expressions in a text template, you must first call a generated directive processor. Calling the generated directive processor makes the classes in your model available to the text template code as properties. For more information, see Accessing Models from Text Templates.

In the following procedures, you will debug an incorrect directive name and an incorrect property name.

To debug an incorrect directive name

  1. In Solution Explorer, double-click DebugTest.tt to open it in the editor.

  2. Replace the code in DebugTest.tt with the following code:

    注意

    The code contains an error. You are introducing the error on purpose to debug it.

    <#@ template language="C#" inherits="Microsoft.VisualStudio.TextTemplating.VSHost.ModelingTextTransformation"#>
    <#@ output extension=".txt" #>
    <#@ modelRoot processor="DebuggingTestLanguageDirectiveProcessor" requires="fileName='Sample.ddd'" provides="ExampleModel=ExampleModel" #>
    
    Model: <#= this.ExampleModel #>
    <#
    foreach (ExampleElement element in this.ExampleModel.Elements) 
    { 
    #> 
        Element: <#= element.Name #>
    <# 
    }
    #>
    
    <#@ template language="VB" inherits="Microsoft.VisualStudio.TextTemplating.VSHost.ModelingTextTransformation"#>
    <#@ output extension=".txt" #>
    <#@ modelRoot processor="DebuggingTestLanguageDirectiveProcessor" requires="fileName='Sample.ddd'" provides="ExampleModel=ExampleModel" #>
    
    Model: <#= Me.ExampleModel #>
    <#
    For Each element as ExampleElement in Me.ExampleModel.Elements
    #> 
        Element: <#= element.Name #>
    <# 
    Next
    #>
    
  3. In Solution Explorer, right-click DebugTest.tt, and then click Run Custom Tool.

    The Error List window displays this error:

    The processor named 'DebuggingTestLanguageDirectiveProcessor' does not support the directive named 'modelRoot'. The transformation will not be run.

    In this case, the directive call contains an incorrect directive name. You have specified modelRoot as the directive name, but the correct directive name is DebuggingTestLanguage.

  4. In Solution Explorer, double-click DebugTest.tt to open it in the editor.

    注意

    You can also double-click the error in the Error List window to jump to the code.

  5. To correct the code, change the directive name to DebuggingTestLanguage.

    The change is highlighted.

    <#@ DebuggingTestLanguage processor="DebuggingTestLanguageDirectiveProcessor" requires="fileName='Sample.ddd'" provides="ExampleModel=ExampleModel" #>
    
    <#@ DebuggingTestLanguage processor="DebuggingTestLanguageDirectiveProcessor" requires="fileName='Sample.ddd'" provides="ExampleModel=ExampleModel" #>
    
  6. In Solution Explorer, right-click DebugTest.tt, and then click Run Custom Tool.

    Now the system transforms the text template and generates the corresponding output file. You will not see any errors in the Error List window.

To debug an incorrect property name

  1. In Solution Explorer, double-click DebugTest.tt to open it in the editor.

  2. Replace the code in DebugTest.tt with the following code:

    注意

    The code contains an error. You are introducing the error on purpose to debug it.

    <#@ template language="C#" inherits="Microsoft.VisualStudio.TextTemplating.VSHost.ModelingTextTransformation"#>
    <#@ output extension=".txt" #>
    <#@ DebuggingTestLanguage processor="DebuggingTestLanguageDirectiveProcessor" requires="fileName='Sample.ddd'" provides="ExampleModel=LibraryModel" #>
    
    Model: <#= this.ExampleModel #>
    <#
    foreach (ExampleElement element in this.ExampleModel.Elements) 
    { 
    #> 
        Element: <#= element.Name #>
    <# 
    }
    #>
    
    <#@ template language="VB" inherits="Microsoft.VisualStudio.TextTemplating.VSHost.ModelingTextTransformation"#>
    <#@ output extension=".txt" #>
    <#@ DebuggingTestLanguage processor="DebuggingTestLanguageDirectiveProcessor" requires="fileName='Sample.ddd'" provides="ExampleModel=LibraryModel" #>
    
    Model: <#= Me.ExampleModel #>
    <#
    For Each element as ExampleElement in Me.ExampleModel.Elements
    #> 
        Element: <#= element.Name #>
    <# 
    Next
    #>
    
  3. In Solution Explorer, right-click DebugTest.tt, and then click Run Custom Tool.

    The Error List window appears and displays one of these errors:

    (C#)

    Compiling transformation: Microsoft.VisualStudio.TextTemplating<GUID>. GeneratedTextTransformation' does not contain a definition for 'ExampleModel'

    (Visual Basic)

    Compiling transformation: 'ExampleModel' is not a member of 'Microsoft.VisualStudio.TextTemplating<GUID>.GeneratedTextTransformation'.

    In this case, the text template does not have a syntax error, but the generated transformation class cannot compile. The text template code contains an incorrect property name. You have specified ExampleModel as the property name, but the correct property name is LibraryModel. You can find the correct property name in the provides parameter, as shown in the following code:

    <#@ DebuggingTestLanguage processor="DebuggingTestLanguageDirectiveProcessor" requires="fileName='Sample.ddd'" provides="ExampleModel=LibraryModel" #>
    
  4. In Solution Explorer, double-click DebugTest.tt to open it in the editor.

    注意

    You can also double-click the error in the Error List window to jump to the code.

  5. To correct the code, change the property name to LibraryModel in the text template code.

    The changes are highlighted.

    <#@ template language="C#" inherits="Microsoft.VisualStudio.TextTemplating.VSHost.ModelingTextTransformation"#>
    <#@ output extension=".txt" #>
    <#@ DebuggingTestLanguage processor="DebuggingTestLanguageDirectiveProcessor" requires="fileName='Sample.ddd'" provides="ExampleModel=LibraryModel" #>
    
    Model: <#= this.LibraryModel #>
    <#
    foreach (ExampleElement element in this.LibraryModel.Elements) 
    { 
    #> 
        Element: <#= element.Name #>
    <# 
    }
    #>
    
    <#@ template language="VB" inherits="Microsoft.VisualStudio.TextTemplating.VSHost.ModelingTextTransformation"#>
    <#@ output extension=".txt" #>
    <#@ DebuggingTestLanguage processor="DebuggingTestLanguageDirectiveProcessor" requires="fileName='Sample.ddd'" provides="ExampleModel=LibraryModel" #>
    
    Model: <#= Me.LibraryModel #>
    <#
    For Each element as ExampleElements in Me.LibraryModel.Elements
    #> 
        Element: <#= element.Name #>
    <# 
    Next
    #>
    
  6. In Solution Explorer, right-click DebugTest.tt, and then click Run Custom Tool.

    Now the system transforms the text template and generates the corresponding output file. You will not see any errors in the Error List window.

Debugging with the Just-In-Time Debugger

In the following procedure, you will debug an element index that does not exist. This error is similar to errors from the previous procedures, but this time you will debug it by using the Visual Studio Just-In-Time Debugger.

注意

You can also use the following procedure to debug a custom directive.

To debug with the Just-In-Time Debugger

  1. In Solution Explorer, double-click DebugTest.tt to open it in the editor.

  2. Replace the code in DebugTest.tt with the following code:

    注意

    The code contains an error. You are introducing the error on purpose to debug it.

    <#@ template language="C#" inherits="Microsoft.VisualStudio.TextTemplating.VSHost.ModelingTextTransformation"#>
    <#@ output extension=".txt" #>
    <#@ DebuggingTestLanguage processor="DebuggingTestLanguageDirectiveProcessor" requires="fileName='Sample.ddd'" #>
    
    <# int counter = this.ExampleModel.Elements.Count; 
       counter = counter+1; 
       ExampleElement someElement = this.ExampleModel.Elements[counter];
    #>
    
    Element Number: <#= someElement.Name #>
    
  3. In Solution Explorer, right-click DebugTest.tt, and then click Run Custom Tool.

    The Error List window appears and displays some errors.

  4. In Solution Explorer, double-click DebugTest.tt to open it in the editor.

  5. Add a debug parameter to the template directive, and add a Break statement to the text template code. You must also comment out the code that is causing the errors.

    The code will look like the following:

    <#@ template debug="true" language="C#" inherits="Microsoft.VisualStudio.TextTemplating.VSHost.ModelingTextTransformation"#>
    <#@ output extension=".txt" #>
    <#@ DebuggingTestLanguage processor="DebuggingTestLanguageDirectiveProcessor" requires="fileName='Sample.ddd'" #>
    
    <# System.Diagnostics.Debugger.Break(); #>
    
    <# int counter = this.ExampleModel.Elements.Count; 
       counter = counter+1; 
       ExampleElement someElement = this.ExampleModel.Elements[counter];
    #>
    
    Element Number: <#= someElement.Name #>
    
  6. On the File menu, click Save DebugTest.tt.

    注意

    By saving the file, you run the text template transformation process automatically.

    A Visual Studio 2008 message appears.

  7. Click Debug.

    The Visual Studio Just-In-Time Debugger dialog box appears.

  8. In the Possible Debuggers list, click New instance of Visual Studio 2008, and then click Yes.

    DebugTest.tt opens in a new instance of Visual Studio. By default, this line is highlighted:

    <# System.Diagnostics.Debugger.Break(); #>

  9. On the Debug menu, click Continue.

    DebugTest.tt opens in a new instance of Visual Studio.

  10. Scroll through DebugTest.tt, and notice that the counter is set to a value that is larger than the number of elements in the model.

    counter = counter+1;

  11. Change this value so that it falls within the range of elements.

    counter = counter-1;
    
  12. Save DebugTest.tt.

    The current instance of Visual Studio closes, and a Visual Studio dialog box opens.

  13. Click Yes.

  14. On the Debug menu, click Stop Debugging.

  15. On the File menu, click Exit.

  16. When you are prompted to save changes, click No.

    The current instance of Visual Studio closes. This system returns you to your debugging solution in the experimental build.

  17. In Solution Explorer, double-click DebugTest.tt to open it in the editor.

  18. Remove the debugparameter from the first line so that it looks like this example:

    <#@ template language="C#" inherits="Microsoft.VisualStudio.TextTemplating.VSHost.ModelingTextTransformation"#>
    
  19. Remove the following line:

    <# System.Diagnostics.Debugger.Break(); #>

  20. Verify that DebugTest.tt looks like the following:

    <#@ template language="C#" inherits="Microsoft.VisualStudio.TextTemplating.VSHost.ModelingTextTransformation"#>
    <#@ output extension=".txt" #>
    <#@ DebuggingTestLanguage processor="DebuggingTestLanguageDirectiveProcessor" requires="fileName='Sample.ddd'" #>
    
    <# int counter = this.ExampleModel.Elements.Count; 
       counter = counter-1; 
       ExampleElement someElement = this.ExampleModel.Elements[counter];
    #>
    
    Element Number: <#= someElement.Name #>
    
  21. In Solution Explorer, right-click DebugTest.tt, and then click Run Custom Tool.

    Now the system transforms the text template and generates the corresponding output file. You will not see any errors in the Error List window.

See Also

Concepts

Common Validation Errors and Warnings in Text Templates

Troubleshooting Text Templates

Generating Artifacts Using Text Templates

Domain-Specific Language Tools Glossary