2014-04-24 11 views
9

Versuch, die T4-Vorlagen für Immutable Object Graph gibt FehlerT4 Berichte Kompilieren Transformation: Ungültige Zeichen ‚this‘ in Klasse, Struktur

╔═══════╦═══╦══════════════════════════════════════════════════════════════════════════════════════════════════╦═════════════════════════════════════════════════════════╦═══╦════╦══════╗ 
║ Error ║ 5 ║ Compiling transformation: Invalid token 'this' in class, struct, or interface member declaration ║ c:\dev\ImmutableObjectGraph-master\2013\Demo\Message.tt ║ 1 ║ 1 ║ Demo ║ 
║ Error ║ 6 ║ Compiling transformation: Method must have a return type           ║ c:\dev\ImmutableObjectGraph-master\2013\Demo\Message.tt ║ 1 ║ 6 ║ Demo ║ 
║ Error ║ 7 ║ Compiling transformation: Type expected               ║ c:\dev\ImmutableObjectGraph-master\2013\Demo\Message.tt ║ 1 ║ 12 ║ Demo ║ 
╚═══════╩═══╩══════════════════════════════════════════════════════════════════════════════════════════════════╩═════════════════════════════════════════════════════════╩═══╩════╩══════╝ 

Die Linie berichtete zu laufen ist immer die Linie 1, und der volle Satz von T4-Vorlagen ist viele Hunderte von Zeilen. Wie kann ich dieses Problem beheben und beheben?

+0

Während unten Antwort ist richtig, wenn Sie GitHub verwenden, kann der folgende Artikel auch eine alternative Lösung erklären - https://www.teamdevelopmentforsitecore.com/Blog/t4-transform-file-problems-code-gen – woodyiii

+0

@ Woodyiii, können Sie feststellen, dass das Hinzufügen des richtigen EOL-Spezifizierer zu '.gitattributes' Ihr Problem dauerhaft lösen wird. Wenn Sie Teammitglieder auf anderen Plattformen haben, können Sie sie manuell ändern. – Mitch

Antwort

27

Sie können keine Literale in einer T4-Vorlage nach einem Scriptlet haben.

ändern

<#@ template debug="true" language="C#" #> 
<#+ 
// scriptlet 
#> 
               <-- empty line here 

Um

<#@ template debug="true" language="C#" #> 
<#+ 
// scriptlet 
#> 

Debuggen

können Sie die C# sehen von PreProcessTemplate mit einem benutzerdefinierten Templating Host Aufruf durch die T4-Motor erzeugt wird.

I modifiziert, um die für diesen Zweck Custom Template Host sample:

using Microsoft.VisualStudio.TextTemplating; 
using System; 
using System.CodeDom.Compiler; 
using System.Collections.Generic; 
using System.IO; 
using System.Text; 

namespace CustomHost 
{ 
    class CustomCmdLineHost : ITextTemplatingEngineHost 
    { 
     public string TemplateFile { get; private set; } 
     public string FileExtension { get; private set; } 
     public Encoding FileEncoding { get; private set; } 
     public CompilerErrorCollection Errors { get; private set; } 

     public IList<string> StandardAssemblyReferences { get { return new[] { typeof(System.Uri).Assembly.Location }; } } 
     public IList<string> StandardImports { get { return new string[] { "System" }; } } 

     public CustomCmdLineHost(string file) 
     { 
      this.TemplateFile = file; 
      this.FileEncoding = Encoding.UTF8; 
      this.FileExtension = ".txt"; 
     } 

     public bool LoadIncludeText(string requestFileName, out string content, out string location) 
     { 
      content = location = String.Empty; 

      if (File.Exists(requestFileName)) 
      { 
       content = File.ReadAllText(requestFileName); 
       return true; 
      } 

      return false; 
     } 

     public object GetHostOption(string optionName) 
     { 
      object returnObject; 
      switch (optionName) 
      { 
       case "CacheAssemblies": 
        returnObject = true; 
        break; 
       default: 
        returnObject = null; 
        break; 
      } 
      return returnObject; 
     } 

     public string ResolveAssemblyReference(string assemblyReference) 
     { 
      return ResolvePath(assemblyReference); 
     } 

     public Type ResolveDirectiveProcessor(string processorName) 
     { 
      throw new Exception("Directive Processor not found"); 
     } 

     public string ResolvePath(string fileName) 
     { 
      if (File.Exists(fileName)) 
      { 
       return fileName; 
      } 

      string candidate = Path.Combine(Path.GetDirectoryName(this.TemplateFile), fileName); 
      if (File.Exists(candidate)) 
      { 
       return candidate; 
      } 

      return fileName; 
     } 

     public string ResolveParameterValue(string directiveId, string processorName, string parameterName) 
     { 
      return String.Empty; 
     } 

     public void SetFileExtension(string extension) 
     { 
      FileExtension = extension; 
     } 

     public void SetOutputEncoding(System.Text.Encoding encoding, bool fromOutputDirective) 
     { 
      FileEncoding = encoding; 
     } 

     public void LogErrors(CompilerErrorCollection errors) 
     { 
      Errors = errors; 
     } 

     public AppDomain ProvideTemplatingAppDomain(string content) 
     { 
      return AppDomain.CreateDomain("Generation App Domain"); 
     } 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      var templateFileName = args[0]; 

      CustomCmdLineHost host = new CustomCmdLineHost(templateFileName); 
      Engine engine = new Engine(); 

      string language; 
      string[] refs; 
      var output = engine.PreprocessTemplate(
       // input file 
       File.ReadAllText(templateFileName), host, 
       "testClass", "testNamespace", out language, out refs); 

      string outputFileName = Path.Combine(
       Path.GetDirectoryName(templateFileName), 
       templateFileName + ".generator.cs"); 

      File.WriteAllText(outputFileName, output, host.FileEncoding); 

      foreach (CompilerError error in host.Errors) 
       Console.WriteLine(error.ToString()); 

      Console.ReadLine(); 
     } 
    } 
} 

den Transformator von der Schablone erzeugten Prüfungs Linien zeigten wie die folgende außerhalb des TransformText() Methode. Anscheinend wurden alle Literale in den Quellvorlagen, die nach einem scriptlet (<#+ #>) kamen, in die generierte Generatorklasse eingefügt.

 #line 1 "C:\dev\ImmutableObjectGraph-master\2013\Demo\Fruit.tt" 
this.Write("\n"); 

Durch Entfernen der Zeilenvorschubzeichen am Ende jeder Vorlagendatei wurde das Problem behoben.

+2

Ich denke, dass diese Information für 99% der Leser am wichtigsten ist: "Das Entfernen der Zeilenumbruchzeichen am Ende jeder Vorlagendatei löste das Problem." – Maxim

+0

Vielen Dank, ich habe mir eine Stunde lang die Haare ausgerissen und versucht zu verstehen, was los war – Atario

+0

Für mich war das Problem woanders. 1. Szymon Seliga der Probe Nehmen Code von oben 2. Einfügen in Console App 3. auf Ihre * .tt Datei installieren nuget "Microsoft.VisualStudio.TextTemplating.15.0" 4. hard Pfad (auf lien 111 sein sollte) 5. Dies erzeugt * .tt.generator.cs 6. Öffnen Sie diese Datei in Visual Studio 7. suchen Sie nach this.Write ("\ n"); das sind externe Methoden (visuelle Studio-Syntax intelissense wird es mit rot automatisch unterstreichen – ambidexterous

4

Für mich war die abschließende Zeilenumbruch am Ende der Datei kein Problem, aber mit Unix-Zeilenenden (\ n) anstelle von Windows-Zeilenenden (\ r \ n) brach die T4-Engine.

Sehr frustrierend zu debuggen, wenn Sie zwei Dateien haben, die identisch aussehen, aber einer von ihnen wird nicht kompilieren!

+0

In meinem Fall löste diese Antwort mein Problem und dieser Artikel erklärt, wie man das Problem im Detail beheben kann - https: //www.teamdevelopmentforsitecore.com/Blog/t4-transform-datei-probleme-code-gen Wann immer wir unsere Versionskontrolle in GitHub umgewandelt haben, gab es zufällige CR LF Probleme, die immer noch kommen, wie dieser. – woodyiii

+0

"Windows oder Büste!" Sie sagten. Was könnte schiefgehen? –