2014-04-24 13 views
9

Cố gắng để chạy các mẫu T4 cho Immutable Object Graph cho lỗi củabáo cáo T4 Biên dịch chuyển: thẻ không hợp lệ 'này' trong lớp, struct

╔═══════╦═══╦══════════════════════════════════════════════════════════════════════════════════════════════════╦═════════════════════════════════════════════════════════╦═══╦════╦══════╗ 
║ 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 ║ 
╚═══════╩═══╩══════════════════════════════════════════════════════════════════════════════════════════════════╩═════════════════════════════════════════════════════════╩═══╩════╩══════╝ 

Dòng thông báo luôn là dòng 1, và tập hợp đầy đủ các mẫu t4 là hàng trăm dòng. Làm cách nào để khắc phục sự cố và khắc phục vấn đề này?

+0

Trong khi câu trả lời dưới đây là chính xác, nếu bạn đang sử dụng GitHub, bài viết sau đây cũng có thể giải thích một giải pháp thay thế - https://www.teamdevelopmentforsitecore.com/Blog/t4-transform-file-problems-code-gen – woodyiii

+0

@ woodyiii, bạn có thể thấy rằng việc thêm đúng specifier eol vào '.gitattributes' sẽ vĩnh viễn giải quyết vấn đề của bạn. Thay đổi nó theo cách thủ công có thể nhanh chóng cũ nếu bạn có thành viên nhóm trên các nền tảng khác. – Mitch

Trả lời

27

Bạn không thể có các chữ trong mẫu T4 sau tập lệnh.

Thay đổi

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

Để

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

Debugging

Bạn có thể xem C# được tạo ra bởi các công cụ T4 bằng cách gọi PreProcessTemplate với một loạt tùy chỉnh khuôn mẫu.

Tôi đổi Custom Template Host sample cho mục đích này:

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

Kiểm tra máy biến áp được tạo ra từ các mẫu cho thấy dòng giống như sau bên ngoài phương pháp TransformText(). Dường như, bất kỳ chữ nào trong các mẫu nguồn xuất hiện sau một số scriptlet (<#+ #>) sẽ được đặt cố định vào lớp trình tạo được tạo ra.

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

Xóa ký tự dòng mới ở cuối mỗi tệp mẫu đã giải quyết được vấn đề.

+2

Tôi đoán thông tin này là quan trọng nhất đối với 99% người đọc: "Việc xóa các ký tự dòng mới ở cuối mỗi tệp mẫu đã giải quyết được sự cố." – Maxim

+0

Cảm ơn bạn rất nhiều, tôi đã rách tóc ra trong một giờ cố gắng để hiểu những gì đang xảy ra – Atario

+0

Đối với tôi vấn đề là ở một nơi khác. 1. Lấy mã mẫu của Szymon Seliga từ trên 2. Dán vào ứng dụng Console 3. Cài đặt nuget "Microsoft.VisualStudio.TextTemplating.15.0" 4. đường dẫn mã cứng vào tệp * .tt của bạn (phải nằm trong danh sách 111) 5. điều này sẽ tạo ra * .tt.generator.cs 6. mở tệp này trong Visual Studio 7. tìm kiếm this.Write ("\ n"); đó là các phương thức bên ngoài (cú pháp studio trực quan intelisense wil lactline gạch chân nó với màu đỏ – ambidexterous

4

Đối với tôi, dòng mới ở cuối tệp không phải là vấn đề, nhưng có dòng cuối Unix (\ n) thay vì kết thúc dòng Windows (\ r \ n) đã phá vỡ công cụ T4.

Rất bực bội khi gỡ lỗi khi bạn có hai tệp giống hệt nhau nhưng một trong số chúng sẽ không biên dịch!

+0

Trong trường hợp của tôi, câu trả lời này đã giải quyết được vấn đề của tôi và bài viết này giải thích cách khắc phục sự cố chi tiết - https: //www.teamdevelopmentforsitecore.com/Blog/t4-transform-file-problems-code-gen Bất cứ khi nào chúng tôi chuyển đổi quyền kiểm soát phiên bản của mình sang GitHub, đã có các sự cố CR LF ngẫu nhiên vẫn xuất hiện, như thế này. – woodyiii

+0

"Windows hoặc bức tượng bán thân!" họ nói rằng. Điều gì có thể xảy ra? –

Các vấn đề liên quan