Start a new topic

using TypeScript definition files to generate C# bindings/wrappers for javascript libraries

It's great that now we can use our C# classes in typescript, as version 1.0 made it availablefor us.

I'm wondering that could we use the typescript definition files to generate C# bindings/wrappers?  It would made many javascript libraries and frameworks (aurelia, angular, ...) available/accessible in our C# code. 


What dou you think about this? 


Can i PLEASE get a copy of this tool.


I am trying to convert (BY HAND) webix.d.ts (Almost 8000 lines of code).


This tool would be a great help... no matter if i gotta go fixup the converted code after...


Beter than HAND writting 8000 lines code.


1 person likes this

This is very good idea and actually here we have an internal tool that does exactly what you mentioned. Currently this tool is very basic and have limitations which requires manual tuning after TS -> C# converted. With this tool we actually ported lib.d.ts automatically.

Thanks

Good to read! I hope you will be able to complete and publish this internal tool for us to make development almost totally transparent between C# and typescript.

Thanks for your hard work!  

Here it is converted to Bridge.

7z
(132 KB)

Simple delegates work in my version it's just that the multiple generics on JQueryPromiseOperator out of memory it.

Just commited complex generic fix to master (not NewChanges). (I'm not using your code because I need your changes to the ReadTypeScriptFile as it doesn't currently use SkippedWord.

I am back at a place where I can get internet freely.

It memory out because of the while loop in GenericRead goes on forever... I have a version (modified from yours of course)... But take a look at my SkipToEndOfWord implementation:


First i let the 1 read of SkipToEndOfWordget BOTH the word and wheres:


  

		internal static SkippedWord SkipToEndOfWord(string tsFile, ref int index)
		{
			var result = new SkippedWord();
			if (!char.IsLetter(tsFile, index))
				SkipEmpty(tsFile, ref index);
			if (tsFile[index] == '[')
				return result;
			for (; index < tsFile.Length; index++) {
				var item = tsFile[index];
				if (char.IsLetterOrDigit(item) || item == '[' || item == ']' || item == '<' || item == '>' || item == '_' || item == '.' || item == '$')
					result.Word += item;
				else {
					if (result.Word.EndsWith("]") && !result.Word.EndsWith("[]")) {
						index--;
						result.Word = result.Word.Substring(0, result.Word.Length - 1);
					}
					result.Wheres = ReadGeneric(tsFile, ref index, ref result.Word);
					return result;
				}
			}
			result.Wheres = ReadGeneric(tsFile, ref index, ref result.Word);
			return result;
		}

		internal static Dictionary<string, string> ReadGeneric(string tsFile, ref int index, ref string word)
		{
			SkipEmpty(tsFile, ref index);
			Dictionary<string, string> whereTypesExt = new Dictionary<string, string>();
			if (word.Contains('<') && !word.Contains('>')) {
				index -= word.Length - word.IndexOf('<');
				word = word.Substring(0, word.IndexOf('<'));
				int marker = CloseGeneric(tsFile, index);
				if (marker > index) {
					string insides = tsFile.Substring(index + 1, (marker - index) - 1);
					word += "<";
					string[] targs = insides.Split(',');
					foreach (string targ in targs) {
						if (targ.IndexOf("extends", StringComparison.Ordinal) >= 0 || targ.IndexOf("implements", StringComparison.Ordinal) >= 0) {
							string buffer = targ.Replace("extends", "|").Replace("implements", "|");
							string[] items = buffer.Split('|');
							string types = items[0].Trim();
							string wheres = items[1].Trim();
							whereTypesExt.Add(types, wheres);
							word += (types.Trim() + ", ");
						} else {
							word += (targ.Trim() + ", ");
						}
					}
					word = word.TrimEnd(',', ' ');
					word += ">";
					index = (marker + 1);
					SkipEmpty(tsFile, ref index);
					// Support Arrays
					char array1 = tsFile[index];
					char array2 = tsFile[index + 1];
					if (array1.Equals('[') && array2.Equals(']')) {
						word += "[]";
						index += 2;
						SkipEmpty(tsFile, ref index);
					}
				} else {
					throw new Exception("Invalid Generic Type Syntax Detected For Word: " + word);
				}
			}
			return whereTypesExt;
		}

		internal static int CloseGeneric(string tsFile, int index)
		{
			int marker = -1;
			for (; index < tsFile.Length; index++) {
				char check = tsFile[index];
				if (check.Equals('>')) {
					marker = index;
					break;
				}
			}
			return marker;
		} 

  

Then used like:


 

							SkippedWord skipName = SkipToEndOfWord(tsFile, ref index); // Mackey Kinard
							string name = skipName.Word;
                            if (string.IsNullOrEmpty(name))
                                goto default;
							var wheres = skipName.Wheres; //GenericRead(tsFile, ref index, ref name);

 

Works pretty good... I made several other small changes and fixes to get working:


Attaches is the entire JQuery API mapped (For DuoCode) with Complex Generics And Everything




cs

You Almost got it... You just need the comma in between generic types:


AnotherWorker<TU> SHOULD BE AnotherWorker<T, U>


Take a look of at this TypeScript:


 

declare namespace Tester { 
	interface TestFx {
	    fx: {
	        tick: () => void;
	        /**
	         * The rate (in milliseconds) at which animations fire.
	         */
	        interval: number;
	        stop: () => void;
	        speeds: { slow: number; fast: number; };
	        /**
	         * Globally disable all animations.
	         */
	        off: boolean;
	        step: any;
	    };
	}
	interface TestWorker {
		test(): string|boolean;
	}
	interface TestWorker<T> {
		test(): T|Object;
	}
	interface AnotherWorker<T, U> {
		another(): U|TestWorker<T>;
	}
}



And this is from your latest Master:


 

using System;
using Bridge;
using Bridge.Html5;
using Bridge.WebGL;
using any = System.Object;
using boolean = System.Boolean;
using Function = System.Delegate;
using RegExp = Bridge.Text.RegularExpressions.Regex;
using number = System.Double;
using Number = System.Double;


namespace Tester
{
	[External]
	public delegate void tickDelegate ();
	[External]
	public delegate void stopDelegate ();
	[ObjectLiteral]
	public class JSONSpeedsInterface : SpeedsInterface
	{
		public extern number Slow { get; set; }
		public extern number Fast { get; set; }
	}
	[External]
	public interface SpeedsInterface
	{
		[FieldProperty]
		number Slow { get; set; }
		[FieldProperty]
		number Fast { get; set; }
	}
	[ObjectLiteral]
	public class JSONFxInterface : FxInterface
	{
		public extern tickDelegate Tick { get; set; }
		public extern number Interval { get; set; }
		public extern stopDelegate Stop { get; set; }
		public extern SpeedsInterface Speeds { get; set; }
		public extern boolean Off { get; set; }
		public extern any Step { get; set; }
	}
	[External]
	public interface FxInterface
	{
		[FieldProperty]
		tickDelegate Tick { get; set; }
		[FieldProperty]
		number Interval { get; set; }
		[FieldProperty]
		stopDelegate Stop { get; set; }
		[FieldProperty]
		SpeedsInterface Speeds { get; set; }
		[FieldProperty]
		boolean Off { get; set; }
		[FieldProperty]
		any Step { get; set; }
	}
	[ObjectLiteral]
	public class JSONTestFx : TestFx
	{
		public extern FxInterface Fx { get; set; }
	}
	[External]
	public interface TestFx
	{
		[FieldProperty]
		FxInterface Fx { get; set; }
	}
	[ObjectLiteral]
	public class JSONTestWorker : TestWorker
	{
	[External]
	public delegate Any<string, boolean> testDelegate ();

		public extern Any<string, boolean> Test ();
		public extern testDelegate test { get; set; }
	}
	[External]
	public interface TestWorker
	{
		Any<string, boolean> Test ();
	}
	[ObjectLiteral]
	public class JSONTestWorker<T> : TestWorker<T>
	{
	[External]
	public delegate Any<T, Object> testDelegate ();

		public extern Any<T, Object> Test ();
		public extern testDelegate test { get; set; }
	}
	[External]
	public interface TestWorker<T>
	{
		Any<T, Object> Test ();
	}
	[ObjectLiteral]
	public class JSONAnotherWorker<TU> : AnotherWorker<TU>
	{
	[External]
	public delegate Any<U, TestWorker<T>> anotherDelegate ();

		public extern Any<U, TestWorker<T>> Another ();
		public extern anotherDelegate another { get; set; }
	}
	[External]
	public interface AnotherWorker<TU>
	{
		Any<U, TestWorker<T>> Another ();
	}

} 

  


Since you ALMOST got Complex Generics working without my code... I will download your latest master (once you fix the comma thing) and apply some of the other fixes to the DuoCode Version and Either Pull request or just send you the whole project and you can do whatever you want with it.

Note: Im still a little worried about that ENDLESS while loop in the GenericRead.


Its just 'while(true)' always scares me a bit when i see that in code;

The [Js(Name="name")] should only be used when there are capitals in the original, I'll look into it.

It should only do it when the first letter of the identifier is a capital. I'm sorry I haven't been around I have gone somewhere with no internet and am now at an internet café.

For me, that doesn't happen (maybe it's one of the changes you made)


#pragma warning disable CS0626

        [FieldProperty]

        public extern static boolean Enabled { get; set; }

#pragma warning restore CS0626


in Cache in three.d.cs.

Login or Signup to post a comment