diff --git a/JSIL.Libraries/Sources/JSIL.Core.js b/JSIL.Libraries/Sources/JSIL.Core.js index 773d5ff9c..d4894c167 100644 --- a/JSIL.Libraries/Sources/JSIL.Core.js +++ b/JSIL.Libraries/Sources/JSIL.Core.js @@ -8492,7 +8492,7 @@ JSIL.InterfaceMethod.prototype.$MakeCallMethod = function () { var target = thisObject[key]; var targetFunctionArgs = Array.prototype.slice.call(arguments, 2); if (genericArgs) { - resolvedTarget = target.apply(thisObject, genericArgs); + var resolvedTarget = target.apply(thisObject, genericArgs); return resolvedTarget(targetFunctionArgs); } else { return target.apply(thisObject, targetFunctionArgs); diff --git a/JSIL/AssemblyTranslator.cs b/JSIL/AssemblyTranslator.cs index 9af9e54a5..b2c4877bd 100644 --- a/JSIL/AssemblyTranslator.cs +++ b/JSIL/AssemblyTranslator.cs @@ -284,12 +284,7 @@ protected ParallelOptions GetParallelOptions () { } protected bool IsIgnored (string assemblyName) { - foreach (var ia in Configuration.Assemblies.Ignored) { - if (Regex.IsMatch(assemblyName, ia, RegexOptions.IgnoreCase)) - return true; - } - - return false; + return Configuration.IsIgnoredAssembly(assemblyName); } protected string ResolveRedirectedName (string assemblyName) { @@ -841,20 +836,7 @@ private void GetMethodsToAnalyze (AssemblyDefinition assembly, ConcurrentBag assemblies) { if (assemblies != null) { foreach (var referenceOverride in assemblies) { - if (!Translator.IsIgnoredAssembly(referenceOverride.Value)) { + if (!Translator.Configuration.IsIgnoredAssembly(referenceOverride.Value)) { Formatter.WriteRaw(string.Format("import {{$private as {0}}} from \"./{1}\"", referenceOverride.Key.IDString, referenceOverride.Value)); Formatter.Semicolon(); } @@ -158,6 +158,13 @@ private void EmitClassInOutType (TypeDefinition typedef) { Formatter.WriteTypeReference(iface, typedef, JavascriptFormatterHelper.ReplaceMode.In, false); } + if (typedef.IsInterface) { + Formatter.Space(); + Formatter.WriteRaw("|"); + Formatter.Space(); + Formatter.WriteTypeReference(typedef.Module.TypeSystem.Object, typedef, JavascriptFormatterHelper.ReplaceMode.In, false); + } + Formatter.Semicolon(); /*Out*/ @@ -185,6 +192,14 @@ private void EmitClassInOutType (TypeDefinition typedef) { Formatter.WriteTypeReference(iface, typedef, JavascriptFormatterHelper.ReplaceMode.Out, false); } + if (typedef.IsInterface) + { + Formatter.Space(); + Formatter.WriteRaw("&"); + Formatter.Space(); + Formatter.WriteTypeReference(typedef.Module.TypeSystem.Object, typedef, JavascriptFormatterHelper.ReplaceMode.Out, false); + } + Formatter.Semicolon(); } @@ -230,7 +245,10 @@ private void EmitClassStatic (TypeDefinition typedef) { } if (typedef.IsInterface) { - var instanceMethods = typedef.Methods.Where(it => it.IsPublic && !Translator.ShouldSkipMember(it)).GroupBy(method => method.Name).OrderBy(group => group.Key); + var instanceMethods = typedef.Methods + .Where(it => it.IsPublic && !Translator.ShouldSkipMember(it)) + .GroupBy(method => method.Name + (method.HasGenericParameters ? "`" + method.GenericParameters.Count : string.Empty)) + .OrderBy(group => group.Key); foreach (var instanceMethodGroup in instanceMethods) { EmitInterfaceMethodGroup(instanceMethodGroup.Key, instanceMethodGroup); @@ -575,7 +593,10 @@ public static bool WriteTypeReference (this JavascriptFormatter formatter, TypeR } } else if (typeReference is GenericInstanceType) { var genericType = (GenericInstanceType) typeReference; - if (formatter.WriteTypeReference(genericType.ElementType, context, replaceMode)) /*TODO*/ { + if (genericType.Resolve().FullName == "System.Nullable`1") { + formatter.WriteTypeReference(genericType.GenericArguments[0], context, replaceMode); + } + else if (formatter.WriteTypeReference(genericType.ElementType, context, replaceMode)) /*TODO*/ { formatter.WriteRaw("<"); formatter.CommaSeparatedList(genericType.GenericArguments, genericArgument => { formatter.WriteTypeReference(genericArgument, context, ReplaceMode.Instance); @@ -604,6 +625,11 @@ public static bool WriteTypeReference (this JavascriptFormatter formatter, TypeR } else if (targetAssembly == formatter.Assembly.FullName) { assemblyRef = string.Empty; } else { + if (formatter.Configuration.IsIgnoredAssembly(targetAssembly)) { + formatter.WriteRaw("Object"); // TODO. Think what type use for ignored assemblies. + return false; + } + assemblyRef = formatter.Manifest.Entries.FirstOrDefault(item => item.Value == targetAssembly).Key; } if (definition != null && assemblyRef != null) { @@ -626,7 +652,7 @@ public static bool WriteTypeReference (this JavascriptFormatter formatter, TypeR * It could be improved, by we really need generic variance support or support of: type T = something & I (see Microsoft/TypeScript#6230) */ - var fixedMode = (replaceMode != ReplaceMode.Instance && context == definition) ? ReplaceMode.Instance : replaceMode; + var fixedMode = (replaceMode != ReplaceMode.Instance && IsCircularRef(definition, context, null)) ? ReplaceMode.Instance : replaceMode; formatter.TRSuffix(fixedMode); } else { @@ -639,6 +665,49 @@ public static bool WriteTypeReference (this JavascriptFormatter formatter, TypeR return true; } + public static bool IsCircularRef (TypeReference type, TypeDefinition context, List checkedList) { + if (type is GenericParameter || context == null || type == null) + { + return false; + } + + if (checkedList == null) { + checkedList = new List(); + } + if (type is ArrayType) { + return IsCircularRef(((ArrayType) type).ElementType, context, checkedList); + } + if (type is GenericInstanceType) { + var gt = (GenericInstanceType) type; + foreach (var genericArgument in gt.GenericArguments) { + if (IsCircularRef(genericArgument, context, checkedList)) { + return true; + } + } + } + + var resolvedType = type.Resolve(); + if (resolvedType != null) { + if (checkedList.Contains(resolvedType)) { + return false; + } + checkedList.Add(resolvedType); + + if (resolvedType == context) { + return true; + } + if (IsCircularRef(resolvedType.BaseType, context, checkedList)) { + return true; + } + foreach (var typeReference in resolvedType.Interfaces) { + if (IsCircularRef(typeReference, context, checkedList)) { + return true; + } + } + } + return false; + } + public static void CommaSeparatedList (this JavascriptFormatter formatter, IEnumerable list, Action process) { bool first = true; foreach (var item in list) { diff --git a/JSIL/JS Libraries/DefinitelyTyped/internals/JSIL.Core.d.ts b/JSIL/JS Libraries/DefinitelyTyped/internals/JSIL.Core.d.ts index ef22ac0cb..3bf87242f 100644 --- a/JSIL/JS Libraries/DefinitelyTyped/internals/JSIL.Core.d.ts +++ b/JSIL/JS Libraries/DefinitelyTyped/internals/JSIL.Core.d.ts @@ -48,7 +48,6 @@ export declare namespace $private{ type TIn = Instance; type TOut = Instance & number; interface Static extends Type { - new (arg: number): TOut; } type Factory = Static; } @@ -59,7 +58,6 @@ export declare namespace $private{ type TIn = Instance; type TOut = Instance & number; interface Static extends Type { - new (arg: number): TOut; } type Factory = Static; } @@ -70,7 +68,6 @@ export declare namespace $private{ type TIn = Instance; type TOut = Instance & number; interface Static extends Type { - new (arg: number): TOut; } type Factory = Static; } @@ -81,7 +78,6 @@ export declare namespace $private{ type TIn = Instance; type TOut = Instance & number; interface Static extends Type { - new (arg: number): TOut; } type Factory = Static; } @@ -92,7 +88,6 @@ export declare namespace $private{ type TIn = Instance; type TOut = Instance & number; interface Static extends Type { - new (arg: number): TOut; } type Factory = Static; } @@ -103,7 +98,6 @@ export declare namespace $private{ type TIn = Instance; type TOut = Instance & number; interface Static extends Type { - new (arg: number): TOut; } type Factory = Static; } @@ -112,7 +106,6 @@ export declare namespace $private{ type TIn = Instance; type TOut = Instance; interface Static extends Type { - new (arg: number): TOut; } type Factory = Static; } @@ -121,7 +114,6 @@ export declare namespace $private{ type TIn = Instance; type TOut = Instance; interface Static extends Type { - new(arg: number): TOut; } type Factory = Static; } @@ -130,7 +122,6 @@ export declare namespace $private{ type TIn = Instance; type TOut = Instance; interface Static extends Type { - new(arg: number): TOut; } type Factory = Static; } @@ -141,7 +132,6 @@ export declare namespace $private{ type TIn = Instance; type TOut = Instance & string; interface Static extends Type { - new (arg: number): TOut; } type Factory = Static; } diff --git a/JSIL/JS Libraries/DefinitelyTyped/module.JSIL.TypeScriptInterop.d.ts b/JSIL/JS Libraries/DefinitelyTyped/module.JSIL.TypeScriptInterop.d.ts new file mode 100644 index 000000000..b9a6173f2 --- /dev/null +++ b/JSIL/JS Libraries/DefinitelyTyped/module.JSIL.TypeScriptInterop.d.ts @@ -0,0 +1,9 @@ +import * as jsilCore from "./module.JSIL.Core"; + +export function AsNetString(input: string): typeof jsilCore.System.String.$Undefined; +export function AsInt32(input: number): typeof jsilCore.System.Int32.$Undefined; +export function AsUInt32(input: number): typeof jsilCore.System.UInt32.$Undefined; +export function AsInt16(input: number): typeof jsilCore.System.Int16.$Undefined; +export function AsUInt16(input: number): typeof jsilCore.System.UInt16.$Undefined; +export function AsByte(input: number): typeof jsilCore.System.Byte.$Undefined; +export function AsSByte(input: number): typeof jsilCore.System.SByte.$Undefined; \ No newline at end of file diff --git a/JSIL/JS Libraries/DefinitelyTyped/module.JSIL.TypeScriptInterop.js b/JSIL/JS Libraries/DefinitelyTyped/module.JSIL.TypeScriptInterop.js new file mode 100644 index 000000000..c28c73813 --- /dev/null +++ b/JSIL/JS Libraries/DefinitelyTyped/module.JSIL.TypeScriptInterop.js @@ -0,0 +1,29 @@ +JSIL.AsNetString = function (input) { + return input; +} + +JSIL.AsInt32 = function (input) { + return input | 0; +} + +JSIL.AsUInt32 = function (input) { + return input >>> 0; +} + +JSIL.AsInt16 = function (input) { + return (input | 0) && 0xFFFF; +} + +JSIL.AsUInt16 = function (input) { + return (input >>> 0) && 0xFFFF; +} + +JSIL.AsSByte = function (input) { + return (input | 0) && 0xFF; +} + +JSIL.AsByte = function (input) { + return (input >>> 0) && 0xFF; +} + +module.exports = JSIL; \ No newline at end of file diff --git a/JSIL/JSIL.csproj b/JSIL/JSIL.csproj index 0a1dea55b..cb794007a 100644 --- a/JSIL/JSIL.csproj +++ b/JSIL/JSIL.csproj @@ -168,6 +168,9 @@ + + PreserveNewest + @@ -183,5 +186,10 @@ PreserveNewest + + + PreserveNewest + + \ No newline at end of file