2012-12-26 37 views
14

Tôi đang cố gắng viết một hàm trong C# để lấy một chuỗi chứa mã phân loại và trả về một chuỗi chứa mã JavaScript. Có chức năng thư viện nào cho điều này không?Lập trình biên dịch các bản ghi trong C#?

+0

Bạn có thể tự động hóa lệnh l ine compiler ... – SWeko

+0

Có thể xem: [câu trả lời này] (http://stackoverflow.com/a/3182411/1344760) – RichardTowers

+0

@SWeko: Tôi đang xem 'tsc' nhưng tôi không thấy gì cả sẽ lấy TS và JS đầu ra. Nó chỉ hoạt động với các tập tin như xa như tôi có thể nhìn thấy. – mpen

Trả lời

5

Có lẽ bạn có thể sử dụng trình thông dịch JavaScript như JavaScriptDotNet để chạy trình biên dịch mã số tsc.js từ C#.

Cái gì như:

string tscJs = File.ReadAllText("tsc.js"); 

using (var context = new JavascriptContext()) 
{ 
    // Some trivial typescript: 
    var typescriptSource = "window.alert('hello world!');"; 
    context.SetParameter("typescriptSource", typescriptSource); 
    context.SetParameter("result", ""); 

    // Build some js to execute: 
    string script = tscJs + @" 
result = TypeScript.compile(""typescriptSource"")"; 

    // Execute the js 
    context.Run(script); 

    // Retrieve the result (which should be the compiled JS) 
    var js = context.GetParameter("result"); 
    Assert.AreEqual(typescriptSource, js); 
} 

Rõ ràng mã mà sẽ cần một số công việc nghiêm túc. Nếu điều này đã làm hóa ra là khả thi, tôi chắc chắn sẽ quan tâm đến kết quả.

Bạn cũng có thể muốn sửa đổi tsc để nó có thể hoạt động trên chuỗi trong bộ nhớ thay vì yêu cầu tệp IO.

+0

Oh ..bạn có nghĩa là chạy trình biên dịch 'tsc' thông qua JavaScriptDotNet, chứ không phải đầu ra. Vẫn còn khá một cách xoay vòng để làm điều đó, nhưng về lý thuyết tôi đoán nó sẽ làm việc ... – mpen

+2

Vâng, xin lỗi vì không rõ ràng hơn. Thật khó nói về ba ngôn ngữ cùng một lúc! – RichardTowers

2

Tệp trình biên dịch TypeScript chính thức chạy trên một trong hai node.js hoặc Windows Script Host - nó được viết bằng chính TypeScript (và được chuyển thành JavaScript). Nó yêu cầu một máy chủ tập lệnh có thể truy cập vào hệ thống tệp.

Vì vậy, về cơ bản, bạn có thể chạy TypeScript từ bất kỳ ngôn ngữ nào miễn là bạn có thể bọc nó trong một công cụ tập lệnh hỗ trợ các thao tác hệ thống tệp yêu cầu.

Nếu bạn muốn biên dịch TypeScript thành JavaScript hoàn toàn bằng C#, bạn sẽ kết thúc viết một bản sao C# của trình biên dịch.

11

Bạn có thể sử dụng Process để gọi trình biên dịch, chỉ định vào một thư mục tạm thời và đọc nội dung của tệp được biên dịch.

tôi đã thực hiện một ứng dụng nhỏ để làm điều đó:

Cách sử dụng

TypeScriptCompiler.Compile(@"C:\tmp\test.ts"); 

Để có được JS string

string javascriptSource = File.ReadAllText(@"C:\tmp\test.js"); 

nguồn đầy đủ với ví dụ và nhận xét:

using System; 
using System.Collections.Generic; 
using System.Diagnostics; 
using System.IO; 
using System.Linq; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      try 
      { 
       // compiles a TS file 
       TypeScriptCompiler.Compile(@"C:\tmp\test.ts"); 

       // if no errors were found, read the contents of the compile file 
       string javascriptSource = File.ReadAllText(@"C:\tmp\test.js"); 
      } 
      catch (InvalidTypeScriptFileException ex) 
      { 
       // there was a compiler error, show the compiler output 
       Console.WriteLine(ex.Message); 
      } 

      Console.ReadKey(); 
     } 
    } 

    public static class TypeScriptCompiler 
    { 
     // helper class to add parameters to the compiler 
     public class Options 
     { 
      private static Options @default; 
      public static Options Default 
      { 
       get 
       { 
        if (@default == null) 
         @default = new Options(); 

        return @default; 
       } 
      } 

      public enum Version 
      { 
       ES5, 
       ES3, 
      } 

      public bool EmitComments { get; set; } 
      public bool GenerateDeclaration { get; set; } 
      public bool GenerateSourceMaps { get; set; } 
      public string OutPath { get; set; } 
      public Version TargetVersion { get; set; } 

      public Options() { } 

      public Options(bool emitComments = false 
       , bool generateDeclaration = false 
       , bool generateSourceMaps = false 
       , string outPath = null 
       , Version targetVersion = Version.ES5) 
      { 
       EmitComments = emitComments; 
       GenerateDeclaration = generateDeclaration; 
       GenerateSourceMaps = generateSourceMaps; 
       OutPath = outPath; 
       TargetVersion = targetVersion; 
      } 
     } 

     public static void Compile(string tsPath, Options options = null) 
     { 
      if (options == null) 
       options = Options.Default; 

      var d = new Dictionary<string,string>(); 

      if (options.EmitComments) 
       d.Add("-c", null); 

      if (options.GenerateDeclaration) 
       d.Add("-d", null); 

      if (options.GenerateSourceMaps) 
       d.Add("--sourcemap", null); 

      if (!String.IsNullOrEmpty(options.OutPath)) 
       d.Add("--out", options.OutPath); 

      d.Add("--target", options.TargetVersion.ToString()); 

      // this will invoke `tsc` passing the TS path and other 
      // parameters defined in Options parameter 
      Process p = new Process(); 

      ProcessStartInfo psi = new ProcessStartInfo("tsc", tsPath + " " + String.Join(" ", d.Select(o => o.Key + " " + o.Value))); 

      // run without showing console windows 
      psi.CreateNoWindow = true; 
      psi.UseShellExecute = false; 

      // redirects the compiler error output, so we can read 
      // and display errors if any 
      psi.RedirectStandardError = true; 

      p.StartInfo = psi; 

      p.Start(); 

      // reads the error output 
      var msg = p.StandardError.ReadToEnd(); 

      // make sure it finished executing before proceeding 
      p.WaitForExit(); 

      // if there were errors, throw an exception 
      if (!String.IsNullOrEmpty(msg)) 
       throw new InvalidTypeScriptFileException(msg); 
     } 
    } 

    public class InvalidTypeScriptFileException : Exception 
    { 
     public InvalidTypeScriptFileException() : base() 
     { 

     } 
     public InvalidTypeScriptFileException(string message) : base(message) 
     { 

     } 
    } 
} 
+0

Đây có lẽ là giải pháp tốt nhất, mặc dù tôi thực sự muốn tôi có thể giữ tất cả trong bộ nhớ (đầu vào và đầu ra). – mpen

+0

Câu trả lời tuyệt vời Tôi ước tôi có thể tăng gấp đôi upvote! – Glenn

+0

Tôi phải đối mặt với một 'Tập tin không tìm thấy' với một Win32Exception, nhưng đường dẫn của tôi cho tập tin TS của tôi là chính xác. Tôi nghĩ rằng đó là tha đường dẫn đến trình biên dịch TSC mà không phải là chính xác. Bạn đã gặp phải vấn đề này một lần chưa? EDIT: Tôi chỉ định trực tiếp đường dẫn cho trình biên dịch TSC của tôi, bây giờ tôi có thông báo này: "Tệp thực thi được chỉ định không phải là ứng dụng hợp lệ cho nền tảng hệ điều hành này". –

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