2013-09-26 12 views
6

Próbowałem użyć ClearScript do załadowania kompilatora TypeScript, aby skompilować pewien podstawowy kod TypeScript.Ładowanie kompilatora TypeScript do ClearScript, "WScript jest niezdefiniowany", niemożliwe zadanie?

Niestety, podczas wykonywania źródło maszynopis kompilatora otrzymuję ten błąd:

'WScript' is undefined

jest to program LINQPad Użyłem, umieść ClearScript dll i TypeScript compiler file obok programu .linq:

void Main() 
{ 
    using (var js = new Microsoft.ClearScript.Windows.JScriptEngine(Microsoft.ClearScript.Windows.WindowsScriptEngineFlags.DisableSourceManagement)) 
    { 
     var typeScriptSource = File.ReadAllText(Path.Combine(Path.GetDirectoryName(Util.CurrentQueryPath), "tsc.js")); 
     js.Execute(typeScriptSource); 
     const string typeScriptCode = @" 
      class Greeter { 
       greeting: string; 
       constructor(message: string) { 
        this.greeting = message; 
       } 
       greet() { 
        return ""Hello, "" + this.greeting; 
       } 
      } 
      function test() 
      { 
       var greeter = Greeter(""world""); 
       return greeter.greet(); 
      } 
     "; 
     js.Script.TypeScript.Compile(typeScriptCode); 

     object result = js.Script.test(); 
     result.Dump(); 
    } 
} 

#region Copy ClearScript to correct location 

static UserQuery() 
{ 
    foreach (var filename in new[] { "ClearScriptV8-32.dll", "ClearScriptV8-64.dll", "v8-ia32.dll", "v8-x64.dll" }) 
    { 
     try 
     { 
      string sourcePath = Path.Combine(Path.GetDirectoryName(Util.CurrentQueryPath), filename); 
      string targetPath = Path.Combine(Path.GetDirectoryName(typeof(Util).Assembly.Location), filename); 

      File.Copy(sourcePath, targetPath, true); 
     } 
     catch (IOException ex) 
     { 
      unchecked 
      { 
       const int fileInUseHresult = (int)0x80070020; 
       if (ex.HResult != fileInUseHresult) 
        throw; 
      } 
     } 
    } 
} 

#endregion 

błąd występuje na tej linii:

js.Execute(typeScriptSource); 

Mam utworzony plik .zip ze wszystkim, potrzebujesz LINQPad do załadowania pliku .linq i eksperymentowania. Dll programu ClearScript są tworzone z niezmodyfikowanego źródła, ale jeśli nie masz do mnie zaufania, powinieneś móc je odtworzyć (jeśli ich nie masz).

Jest dostępna tutaj: Dropbox Link to SO19023498.zip.

Co próbowałem:

  1. Próbowałem wykonaniu tego kodu pierwszy:

    var WScript = new ActiveXObject("WSH.WScript"); 
    

    Ten produkowany tylko ten błąd: Automation server can't create object

    nie widzę WSH.WScript w rejestrze pod HKEY_CLASSES_ROOT, więc to może być to.

  2. Próbowałem dowiedzieć się, jak utworzyć obiekt z .NET i ustawienie go w kontekście skryptu, ale nie jestem patrząc we właściwe miejsce.

+0

Należy pamiętać, że nie wiem, czy wezwanie do kompilacji kodu maszynopis jest poprawna, może to zwraca wynikowy kodu javascript, ale program zawodzi przed tym krokiem. –

+0

Obiekt WScript nie jest możliwy do utworzenia, chociaż można go łatwo emulować przy użyciu klasy C#. Skrypt tsc.js wymaga również obiektu ActiveXObject, który jest JScript-ism, ale można go również wyłudzić, jeśli chcesz użyć V8 (co, jak zakładam, robisz, ponieważ przechodzisz przez bóle, aby zainstalować biblioteki DLL V8 ClearScript). Wszystko to jednak wymagałoby trochę pracy, więc polecam podejście Ela poniżej. – BitCortex

Odpowiedz

5

Po zabawy trochę z ClearScript, pomysł jest całkiem fajny rzeczywiście dostać go w ruchu.

Aby otrzymać kod przynajmniej trochę bardziej trwania: Zamiast używać tsc.js, wystarczy użyć typescript.js która pochodzi z SDK i powinny być w tym samym folderze.

var typeScriptSource = File.ReadAllText("typescript.js"); 

typescript.js jest zwykły javascript kompilator gdzie TSC korzysta WSH oraz inne obiekty COM ...

W ten sposób można również użyć silnik V8!

Ale w każdym razie oznacza to, że musiałbyś napisać kod JavaScript, aby faktycznie objąć funkcje TypeScript.TypeScriptCompiler.

Oznacza to, że musiałbyś zrobić to samo, jakbyś użył TypeScriptCompiler na niestandardowej stronie html (tak jak robi to plac zabaw). Nie znalazłem dotąd dokumentacji, jak korzystać z kompilatora ... Ale znalazłem jedną stronę, która również próbuje wdrożyć to http://10consulting.com/2012/10/12/introduction-to-typescript-presentation/ Jeśli spojrzysz na źródło prezentacji, znajdziesz klasę Compiler.

Compiler.prototype.compile = function (src) { 
    var outfile = { 
     source: "", 
     Write: function (s) { 
      this.source += s; 
     }, 
     WriteLine: function (s) { 
      this.source += s + "\n"; 
     }, 
     Close: function() { } 
    }; 

    var compiler = new TypeScript.TypeScriptCompiler(outfile); 

    try { 
     compiler.parser.errorRecovery = true; 
     compiler.setErrorCallback(function (start, len, message, block) { 
      console.log('Compilation error: ', message, '\n Code block: ', block, ' Start position: ', start, ' Length: ', len); 
     }); 
     compiler.addUnit(Compiler.libfile, 'lib.d.ts'); 
     compiler.addUnit(src, ''); 

     compiler.typeCheck(); 

     compiler.emit(false, function createFile(fileName) { 
      console.log(outfile); 
      return outfile; 
     }); 

     console.log('compiled: ' + outfile.source); 
     return outfile.source; 
    } catch (e) { 
     console.log('Fatal error: ', e); 
    } 
    return ''; 
}; 
return Compiler; 

To wygląda dość obiecująco, ale niestety, jeśli staram się go używać z ClearScript rzuca dziwne błędy, może robię coś źle ...

Przynajmniej jeśli debugować za pomocą kodu , js.Scripts.TypeScript jest zdefiniowany i zawiera wszystkie obiekty TypeScript!

W każdym razie, myślę, że powinno to przynieść ci kolejny krok;) daj mi znać, jeśli odniosłeś sukces!

Jako alternatywa, możesz użyć narzędzia wiersza poleceń, aby po prostu wywołać kompilator zamiast robić to bezpośrednio z C#. Wydaje mi się, że powinno to być łatwiejsze do wdrożenia ... Lub zagraj w pakiecie node.js, który zapewnia również wszystkie potrzebne usługi kompilatora.

+0

Dzięki za to, na pewno spróbuję tego później jeszcze dzisiaj, opublikuję komentarze lub inne niezbędne informacje odzwierciedlające to, co odkryję. –

+0

Ela jest tutaj na dobrej drodze. Skrypt typecript.js to podstawowy przenośny kod TypeScript i działa doskonale w wersji V8. Jednak powyższe opakowanie kompilatora jest nieaktualne; np. TypeScriptCompiler nie ma metody addUnit() w ostatnich kroplach. Powyższy kod również używa obiektu "konsoli", który musiałby być gdzieś zdefiniowany. – BitCortex

4

Oto próbka szkieletu przy użyciu aktualnej wersji typescript.js. Zauważ, że TypeScript API jest poddawany inżynierii wstecznej; o ile mogę powiedzieć, że jedynym oficjalnym interfejsem jest linia poleceń tsc. Należy także pamiętać, że jest to minimalna próbka że nie ma obsługi błędów lub raportowanie:

using System; 
using System.IO; 
using Microsoft.ClearScript; 
using Microsoft.ClearScript.V8; 

namespace Test 
{ 
    public class TypeScriptCompiler 
    { 
     private readonly dynamic _compiler; 
     private readonly dynamic _snapshot; 
     private readonly dynamic _ioHost; 

     public TypeScriptCompiler(ScriptEngine engine) 
     { 
      engine.Evaluate(File.ReadAllText("typescript.js")); 
      _compiler = engine.Evaluate("new TypeScript.TypeScriptCompiler"); 
      _snapshot = engine.Script.TypeScript.ScriptSnapshot; 
      _ioHost = engine.Evaluate(@"({ 
       writeFile: function (path, contents) { this.output = contents; } 
      })"); 
     } 

     public string Compile(string code) 
     { 
      _compiler.addSourceUnit("foo.ts", _snapshot.fromString(code)); 
      _compiler.pullTypeCheck(); 
      _compiler.emitUnit("foo.ts", _ioHost); 
      return _ioHost.output; 
     } 
    } 

    public static class TestApplication 
    { 
     public static void Main() 
     { 
      using (var engine = new V8ScriptEngine()) 
      { 
       var compiler = new TypeScriptCompiler(engine); 
       Console.WriteLine(compiler.Compile("class Foo<T> {}")); 
      } 
     } 
    } 
} 
1

Po 4 latach, stosując maszynopis 2,7 Usług na https://rawgit.com/Microsoft/TypeScript/master/lib/typescriptServices.js to rodzaj dwóch-liner teraz:

  • zainicjować swój ulubiony silnik JS z tego skryptu
  • załadować zawartość strunowe twoich * .TS zasobów
  • uzyskać odwołanie funkcją ts.transpile
  • paszy skrypt typu jako ciąg i wrócić ciąg z transpiled źródła

zastosowaniem np ClearScript engine w C# z TS źródłowego w ciągu src to byłoby:

dynamic transpile = engine.Evaluate("ts.transpile"); 
var js = transpile(src); 
// now feed the string js into a different JS engine