Skip to content
This repository was archived by the owner on Aug 24, 2022. It is now read-only.

TypeScript definitions improvements #1025

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
2 changes: 1 addition & 1 deletion JSIL.Libraries/Sources/JSIL.Core.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
22 changes: 2 additions & 20 deletions JSIL/AssemblyTranslator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -841,20 +836,7 @@ private void GetMethodsToAnalyze (AssemblyDefinition assembly, ConcurrentBag<Met
}

public bool IsIgnored (AssemblyDefinition assembly) {
return IsIgnoredAssembly(assembly.FullName);
}

public bool IsIgnoredAssembly(string assemblyName)
{
foreach (var sa in Configuration.Assemblies.Ignored)
{
if (Regex.IsMatch(assemblyName, sa, RegexOptions.IgnoreCase))
{
return true;
}
}

return false;
return IsIgnored(assembly.FullName);
}

public bool IsStubbed (AssemblyDefinition assembly) {
Expand Down
15 changes: 14 additions & 1 deletion JSIL/Configuration.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace JSIL.Translator {
[Serializable]
Expand Down Expand Up @@ -154,7 +155,7 @@ public virtual void MergeInto (Configuration result) {
if (UseThreads.HasValue)
result.UseThreads = UseThreads;
if (UseDefaultProxies.HasValue)
result.UseDefaultProxies = UseDefaultProxies;
result.UseDefaultProxies = UseDefaultProxies;

if (FrameworkVersion.HasValue)
result.FrameworkVersion = FrameworkVersion;
Expand Down Expand Up @@ -191,4 +192,16 @@ public virtual void MergeInto (Configuration result) {
CodeGenerator.MergeInto(result.CodeGenerator);
}
}

public static class ConfigurationHelper {
public static bool IsIgnoredAssembly (this Configuration configurain, string assemblyName) {
foreach (var sa in configurain.Assemblies.Ignored) {
if (Regex.IsMatch(assemblyName, sa, RegexOptions.IgnoreCase)) {
return true;
}
}

return false;
}
}
}
77 changes: 73 additions & 4 deletions JSIL/DefinitelyTypedAssemblyEmitter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public override void EmitHeader (bool stubbed, bool iife) {
public override void EmitAssemblyReferences (string assemblyDeclarationReplacement, Dictionary<AssemblyManifest.Token, string> 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();
}
Expand Down Expand Up @@ -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*/
Expand Down Expand Up @@ -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();
}

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand All @@ -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<T> (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 {
Expand All @@ -639,6 +665,49 @@ public static bool WriteTypeReference (this JavascriptFormatter formatter, TypeR
return true;
}

public static bool IsCircularRef (TypeReference type, TypeDefinition context, List<TypeDefinition> checkedList) {
if (type is GenericParameter || context == null || type == null)
{
return false;
}

if (checkedList == null) {
checkedList = new List<TypeDefinition>();
}
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<T> (this JavascriptFormatter formatter, IEnumerable<T> list, Action<T> process) {
bool first = true;
foreach (var item in list) {
Expand Down
10 changes: 0 additions & 10 deletions JSIL/JS Libraries/DefinitelyTyped/internals/JSIL.Core.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ export declare namespace $private{
type TIn = Instance;
type TOut = Instance & number;
interface Static extends Type<Instance, TIn, TOut> {
new (arg: number): TOut;
}
type Factory = Static;
}
Expand All @@ -59,7 +58,6 @@ export declare namespace $private{
type TIn = Instance;
type TOut = Instance & number;
interface Static extends Type<Instance, TIn, TOut> {
new (arg: number): TOut;
}
type Factory = Static;
}
Expand All @@ -70,7 +68,6 @@ export declare namespace $private{
type TIn = Instance;
type TOut = Instance & number;
interface Static extends Type<Instance, TIn, TOut> {
new (arg: number): TOut;
}
type Factory = Static;
}
Expand All @@ -81,7 +78,6 @@ export declare namespace $private{
type TIn = Instance;
type TOut = Instance & number;
interface Static extends Type<Instance, TIn, TOut> {
new (arg: number): TOut;
}
type Factory = Static;
}
Expand All @@ -92,7 +88,6 @@ export declare namespace $private{
type TIn = Instance;
type TOut = Instance & number;
interface Static extends Type<Instance, TIn, TOut> {
new (arg: number): TOut;
}
type Factory = Static;
}
Expand All @@ -103,7 +98,6 @@ export declare namespace $private{
type TIn = Instance;
type TOut = Instance & number;
interface Static extends Type<Instance, TIn, TOut> {
new (arg: number): TOut;
}
type Factory = Static;
}
Expand All @@ -112,7 +106,6 @@ export declare namespace $private{
type TIn = Instance;
type TOut = Instance;
interface Static extends Type<Instance, TIn, TOut> {
new (arg: number): TOut;
}
type Factory = Static;
}
Expand All @@ -121,7 +114,6 @@ export declare namespace $private{
type TIn = Instance;
type TOut = Instance;
interface Static extends Type<Instance, TIn, TOut> {
new(arg: number): TOut;
}
type Factory = Static;
}
Expand All @@ -130,7 +122,6 @@ export declare namespace $private{
type TIn = Instance;
type TOut = Instance;
interface Static extends Type<Instance, TIn, TOut> {
new(arg: number): TOut;
}
type Factory = Static;
}
Expand All @@ -141,7 +132,6 @@ export declare namespace $private{
type TIn = Instance;
type TOut = Instance & string;
interface Static extends Type<Instance, TIn, TOut> {
new (arg: number): TOut;
}
type Factory = Static;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
29 changes: 29 additions & 0 deletions JSIL/JS Libraries/DefinitelyTyped/module.JSIL.TypeScriptInterop.js
Original file line number Diff line number Diff line change
@@ -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;
8 changes: 8 additions & 0 deletions JSIL/JSIL.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,9 @@
</None>
</ItemGroup>
<ItemGroup>
<None Include="JS Libraries\DefinitelyTyped\module.JSIL.TypeScriptInterop.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<Content Include="jsil.ico" />
</ItemGroup>
<ItemGroup>
Expand All @@ -183,5 +186,10 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<None Include="JS Libraries\DefinitelyTyped\module.JSIL.TypeScriptInterop.d.ts">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>