2012-09-06 90 views
2

我试图使用Script#编译器将C#的小碎片编译成JavaScript。使用脚本#编译代码(独立)

但我没有得到任何回报,我的MemoryStreamSource中的GetStream()甚至没有被调用,所以我必须做错了什么。

这里是我的代码:

CodeScriptCompiler csc = new CodeScriptCompiler(); 

return csc.CompileCSharp("String.IsNullOrWhiteSpace(Model.MobilePhoneNumber)"); 

CodeScriptCompiler.cs

using System; 
using System.Collections.Generic; 
using ScriptSharp; 

namespace CodeToScriptCompiler 
{ 
    public class CodeScriptCompiler 
    { 
     ScriptCompiler sc = new ScriptCompiler(); 

     public string CompileCSharp(string csharpCode) 
     { 
      string errorMessages = String.Empty; 

      CompilerOptions options = new CompilerOptions(); 
      options.Defines = new List<string>(); 
      options.References = new List<string>(); 
      options.References.Add("System.dll"); 
      options.Resources = new List<IStreamSource>(); 
      options.Sources = new List<IStreamSource>(); 
      options.Sources.Add(new MemoryStreamSource(csharpCode)); 
      options.TemplateFile = new MemoryStreamSource(csharpCode); 

      MemoryStreamDestination output = new MemoryStreamDestination(); 
      options.ScriptFile = output; 

      if (!options.Validate(out errorMessages)) 
      { 
       return errorMessages; 
      } 

      return output.GetCompiledCode(); 
     } 
    } 
} 

MemoryStreamSource.cs

using System.IO; 
using System.Text; 
using ScriptSharp; 

namespace CodeToScriptCompiler 
{ 
    public class MemoryStreamSource : IStreamSource 
    { 
     private string _code; 

     private MemoryStream _memoryStream; 

     public MemoryStreamSource(string code) 
     { 
      this._code = code; 
     } 

     public string Name 
     { 
      get { return "InMemoryCode"; } 
     } 

     public string FullName 
     { 
      get { return "InMemoryCode"; } 
     } 

     public void CloseStream(Stream stream) 
     { 
      stream.Close(); 
     } 

     public Stream GetStream() 
     { 
      this._memoryStream = new MemoryStream(Encoding.ASCII.GetBytes(this._code)); 

      return this._memoryStream; 
     } 
    } 
} 

MemoryStreamDestination.cs

using System; 
using System.IO; 
using ScriptSharp; 

namespace CodeToScriptCompiler 
{ 
    public class MemoryStreamDestination : IStreamSource 
    { 
     private MemoryStream _memoryStream; 

     private string _compiledCode; 

     public string Name 
     { 
      get { return "MemoryStreamDestination"; } 
     } 

     public string FullName 
     { 
      get { return "MemoryStreamDestination"; } 
     } 

     public void CloseStream(Stream stream) 
     { 
      if (String.IsNullOrWhiteSpace(this._compiledCode)) 
      { 
       this._compiledCode = this.GetCompiledCode(); 
      } 

      stream.Close(); 
     } 

     public Stream GetStream() 
     { 
      this._memoryStream = new MemoryStream(); 

      return this._memoryStream; 
     } 

     public string GetCompiledCode() 
     { 
      if (!String.IsNullOrWhiteSpace(this._compiledCode)) 
      { 
       return this._compiledCode; 
      } 

      if (this._memoryStream != null) 
      { 
       using (StreamReader sr = new StreamReader(this._memoryStream)) 
       { 
        return sr.ReadToEnd(); 
       } 
      } 

      return String.Empty; 
     } 
    } 
} 

回答

2

有些事情,我看到潜在的问题。

  1. TemplateFile设置为c#码流。不要设置它,因为这不是有效的模板。
  2. 引用应该包含脚本#mscorlib,此外,只有完整路径才能生效有效的脚本#程序集。 System.dll不是一个脚本#程序集。
  3. 在您从MemoryStream中读取数据之前,您需要将流位置设置回到开始位置,否则在编译器写入它之后就会结束,并且没有其他可读的内容。
  4. 在您创建的编译器实例上没有看到对编译的调用,并传入选项实例。我的猜测是你做到了,只是不在堆栈溢出片段中。

你或许还应该实现IErrorHandler并传递到编译器来获得他们应该出现的错误信息,一旦你有基本的东西的工作。

仅供参考,你也可以看看https://github.com/nikhilk/scriptsharp/tree/master/tests/ScriptSharp/Core的单元测试,它做了类似的事情。

请注意,您需要一个有效的c#源文件,而不是一个独立的表达式。然而,你可以通过从结果脚本的开头和结尾处剥离东西来处理这个问题,以便为您关心的表达式获取脚本。

希望有所帮助。

我当然有兴趣/好奇地了解您如何使用这一点,在那里你编译C#动态脚本...

+0

'mscorlib'基准固定它,我搞砸了,以复制粘贴到关于缺少对“编译”调用的堆栈溢出。我试图将C#的Razor视图编译成代码,然后选择https://github.com/jchadwick/RazorClientTemplates停止的地方,这几乎是每个代码块,除了'foreach'和简单的'if'语句外。对String.IsNullOrWhiteSpace等的基本支持会改善事情。 – MartinHN

+0

但是 - 现在我得到语法错误:'EOF'的预期,因为我返回一个'MemoryStream',所以我试图欺骗它通过添加EOF到流。 – MartinHN

+0

IsNullOrWhitespace - 需要mscorlib中的更新,以及mscorlib.js中的相应添加。你会接受/提交拉请求吗? –