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

Dynamic on JS side #925

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 26 additions & 12 deletions JSIL.Libraries/Includes/Bootstrap/Core/Main.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,19 +120,33 @@ JSIL.MakeClass("System.ComponentModel.TypeConverter", "System.ComponentModel.Exp

JSIL.MakeDelegate("System.Action", true, [], JSIL.MethodSignature.Void);
JSIL.MakeDelegate("System.Action`1", true, ["T"], new JSIL.MethodSignature(null, [new JSIL.GenericParameter("T", "System.Action`1").in()]));
JSIL.MakeDelegate("System.Action`2", true, ["T1", "T2"], new JSIL.MethodSignature(null, [new JSIL.GenericParameter("T1", "System.Action`2").in(), new JSIL.GenericParameter("T2", "System.Action`2").in()]));
JSIL.MakeDelegate("System.Action`3", true, ["T1", "T2", "T3"], new JSIL.MethodSignature(null, [
new JSIL.GenericParameter("T1", "System.Action`3").in(), new JSIL.GenericParameter("T2", "System.Action`3").in(),
new JSIL.GenericParameter("T3", "System.Action`3").in()
]));

JSIL.MakeDelegate("System.Func`1", true, ["TResult"], new JSIL.MethodSignature(new JSIL.GenericParameter("TResult", "System.Func`1").out(), null));
JSIL.MakeDelegate("System.Func`2", true, ["T", "TResult"], new JSIL.MethodSignature(new JSIL.GenericParameter("TResult", "System.Func`2").out(), [new JSIL.GenericParameter("T", "System.Func`2").in()]));
JSIL.MakeDelegate("System.Func`3", true, ["T1", "T2", "TResult"], new JSIL.MethodSignature(new JSIL.GenericParameter("TResult", "System.Func`3").out(), [new JSIL.GenericParameter("T1", "System.Func`3").in(), new JSIL.GenericParameter("T2", "System.Func`3").in()]));
JSIL.MakeDelegate("System.Func`4", true, ["T1", "T2", "T3", "TResult"], new JSIL.MethodSignature(new JSIL.GenericParameter("TResult", "System.Func`4").out(), [
new JSIL.GenericParameter("T1", "System.Func`4").in(), new JSIL.GenericParameter("T2", "System.Func`4").in(),
new JSIL.GenericParameter("T3", "System.Func`4").in()
]));

(function() {
for (var i = 2; i <= 16; i++) {
var actionName = "System.Action`" + i;
var funcName = "System.Func`" + (i + 1);
var genericArgsForActions = [];
var genericArgsForFunctions = [];

var inputForActions = [];
var inputForFunctions = [];
for (var j = 0; j < i; j++) {
var name = "T" + (j + 1);
genericArgsForActions.push(name);
genericArgsForFunctions.push(name);

inputForActions.push(new JSIL.GenericParameter(name, actionName).in());
inputForFunctions.push(new JSIL.GenericParameter(name, funcName).in());
}

genericArgsForFunctions.push("TResult");

JSIL.MakeDelegate(actionName, true, genericArgsForActions, new JSIL.MethodSignature(null, inputForActions));
JSIL.MakeDelegate(funcName, true, genericArgsForFunctions, new JSIL.MethodSignature(new JSIL.GenericParameter("TResult", funcName).out(), inputForFunctions));
}
})();

JSIL.MakeDelegate("System.Predicate`1", true, ["in T"], new JSIL.MethodSignature($jsilcore.TypeRef("System.Boolean"), [new JSIL.GenericParameter("T", "System.Predicate`1").in()]));

Expand Down Expand Up @@ -331,4 +345,4 @@ JSIL.MakeInterface(
$.Method({}, "CleanUpManagedData", JSIL.MethodSignature.Action($.Object));
$.Method({}, "GetNativeDataSize", JSIL.MethodSignature.Return($.Int32));
}, []);
//? }
//? }
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
JSIL.MakeStaticClass("Microsoft.CSharp.RuntimeBinder.Binder", true, [], function($) {
$.RawMethod(true, "BinaryOperation",
function(flags, operation, context, argumentInfo) {
var binder = new $jsilcore.System.Runtime.CompilerServices.CallSiteBinder();
if (operation === $jsilcore.System.Linq.Expressions.ExpressionType.Add || operation === $jsilcore.System.Linq.Expressions.ExpressionType.AddChecked) {
binder.Method = function (callSite, left, right) {
return left+right;
};
} else if (operation === $jsilcore.System.Linq.Expressions.ExpressionType.And) {
binder.Method = function (callSite, left, right) {
return left & right;
};
} else if (operation === $jsilcore.System.Linq.Expressions.ExpressionType.AndAlso) {
binder.Method = function (callSite, left, right) {
return left && right;
};
} else if (operation === $jsilcore.System.Linq.Expressions.ExpressionType.Divide) {
binder.Method = function (callSite, left, right) {
return left / right;
};
} else if (operation === $jsilcore.System.Linq.Expressions.ExpressionType.Equal) {
binder.Method = function (callSite, left, right) {
return left == right;
};
} else if (operation === $jsilcore.System.Linq.Expressions.ExpressionType.ExclusiveOr) {
binder.Method = function (callSite, left, right) {
return left ^ right;
};
} else if (operation === $jsilcore.System.Linq.Expressions.ExpressionType.GreaterThan) {
binder.Method = function (callSite, left, right) {
return left > right;
};
} else if (operation === $jsilcore.System.Linq.Expressions.ExpressionType.GreaterThanOrEqual) {
binder.Method = function (callSite, left, right) {
return left >= right;
};
} else if (operation === $jsilcore.System.Linq.Expressions.ExpressionType.LeftShift) {
binder.Method = function (callSite, left, right) {
return left << right;
};
} else if (operation === $jsilcore.System.Linq.Expressions.ExpressionType.LessThan) {
binder.Method = function (callSite, left, right) {
return left < right;
};
} else if (operation === $jsilcore.System.Linq.Expressions.ExpressionType.LessThanOrEqual) {
binder.Method = function (callSite, left, right) {
return left <= right;
};
} else if (operation === $jsilcore.System.Linq.Expressions.ExpressionType.Modulo) {
binder.Method = function (callSite, left, right) {
return left % right;
};
} else if (operation === $jsilcore.System.Linq.Expressions.ExpressionType.Multiply || operation === $jsilcore.System.Linq.Expressions.ExpressionType.MultiplyChecked) {
binder.Method = function (callSite, left, right) {
return left * right;
};
} else if (operation === $jsilcore.System.Linq.Expressions.ExpressionType.NotEqual) {
binder.Method = function (callSite, left, right) {
return left != right;
};
} else if (operation === $jsilcore.System.Linq.Expressions.ExpressionType.Or) {
binder.Method = function (callSite, left, right) {
return left | right;
};
} else if (operation === $jsilcore.System.Linq.Expressions.ExpressionType.OrElse) {
binder.Method = function (callSite, left, right) {
return left || right;
};
} else if (operation === $jsilcore.System.Linq.Expressions.ExpressionType.RightShift) {
binder.Method = function (callSite, left, right) {
return left >> right;
};
} else if (operation === $jsilcore.System.Linq.Expressions.ExpressionType.Subtract || operation === $jsilcore.System.Linq.Expressions.ExpressionType.SubtractChecked) {
binder.Method = function (callSite, left, right) {
return left - right;
};
} else {
throw new Error("Binary operator is not supported.");
}
return binder;
});

$.RawMethod(true, "Convert",
function(flags, type, context) {
var binder = new $jsilcore.System.Runtime.CompilerServices.CallSiteBinder();
binder.Method = function (callSite, target) {
return type.__PublicInterface__.$Cast(target);
};
return binder;
});

$.RawMethod(true, "GetIndex",
function(flags, context, argumentInfo) {
var binder = new $jsilcore.System.Runtime.CompilerServices.CallSiteBinder();
var isStaticCall = (argumentInfo[0].Flags & $jsilcore.Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags.IsStaticType) > 0;
binder.Method = function (callSite, target) {
var realTarget = (isStaticCall ? target.__PublicInterface__ : target);
if ("get_Item" in realTarget) {
return realTarget["get_Item"].apply(realTarget, Array.prototype.slice.call(arguments, 2));
} else {
// TODO: Jagged arrays support
if (arguments.length === 3) {
return realTarget[arguments[2]];
} else {
throw new Error("Cannot use multi-dimensional indexer for object without indexed property.");
}
}
};
return binder;
});

$.RawMethod(true, "GetMember",
function (flags, name, context, argumentInfo) {
var binder = new $jsilcore.System.Runtime.CompilerServices.CallSiteBinder();
var isStaticCall = (argumentInfo[0].Flags & $jsilcore.Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags.IsStaticType) > 0;
binder.Method = function (callSite, target) {
var realTarget = (isStaticCall ? target.__PublicInterface__ : target);
if (("get_" + name) in realTarget) {
return realTarget["get_" + name]();
} else {
return realTarget[name];
}
};
return binder;
});

$.RawMethod(true, "Invoke",
function (flags, context, argumentInfo) {
var binder = new $jsilcore.System.Runtime.CompilerServices.CallSiteBinder();
binder.Method = function (callSite, target) {
return target.apply(null, Array.prototype.slice.call(arguments, 2));
};
return binder;
});

$.RawMethod(true, "InvokeConstructor",
function(flags, context, argumentInfo) {
throw new Error("Not implemented");
});

$.RawMethod(true, "InvokeMember",
function (flags, name, typeArguments, context, argumentInfo) {
var binder = new $jsilcore.System.Runtime.CompilerServices.CallSiteBinder();
var isStaticCall = (argumentInfo[0].Flags & $jsilcore.Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags.IsStaticType) > 0;
if (typeArguments !== null) {
var useMemberName = name + "$b" + typeArguments.length;
binder.Method = function (callSite, target) {
var realTarget = (isStaticCall ? target.__PublicInterface__ : target);
return realTarget[useMemberName].apply(realTarget, typeArguments).apply(realTarget, Array.prototype.slice.call(arguments, 2));
};
} else {
binder.Method = function (callSite, target) {
var realTarget = (isStaticCall ? target.__PublicInterface__ : target);
return realTarget[name].apply(realTarget, Array.prototype.slice.call(arguments, 2));
};
}
return binder;
});

$.RawMethod(true, "IsEvent",
function(flags, name, context) {
var binder = new $jsilcore.System.Runtime.CompilerServices.CallSiteBinder();
binder.Method = function () {
return false;
};
return binder;
});

$.RawMethod(true, "SetIndex",
function(flags, context, argumentInfo) {
var binder = new $jsilcore.System.Runtime.CompilerServices.CallSiteBinder();
var isStaticCall = (argumentInfo[0].Flags & $jsilcore.Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags.IsStaticType) > 0;
binder.Method = function (callSite, target) {
var realTarget = (isStaticCall ? target.__PublicInterface__ : target);
if ("set_Item" in realTarget) {
return realTarget["set_Item"].apply(realTarget, Array.prototype.slice.call(arguments, 2));
} else {
// TODO: Jagged arrays support
if (arguments.length === 4) {
realTarget[arguments[2]] = arguments[3];
} else {
throw new Error("Cannot use multi-dimensional indexer for object without indexed property.");
}
}
};
return binder;
});

$.RawMethod(true, "SetMember",
function(flags, name, context, argumentInfo) {
var binder = new $jsilcore.System.Runtime.CompilerServices.CallSiteBinder();
var isStaticCall = (argumentInfo[0].Flags & $jsilcore.Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags.IsStaticType) > 0;
binder.Method = function(callSite, target, value) {
var realTarget = (isStaticCall ? target.__PublicInterface__ : target);
if (("set_" + name) in realTarget) {
return realTarget["set_" + name](value);
} else {
realTarget[name] = value;
}
};
return binder;
});

$.RawMethod(true, "UnaryOperation",
function(flags, operation, context, argumentInfo) {
var binder = new $jsilcore.System.Runtime.CompilerServices.CallSiteBinder();
if (operation === $jsilcore.System.Linq.Expressions.ExpressionType.UnaryPlus) {
binder.Method = function(callSite, target) {
return target;
};
} else if (operation === $jsilcore.System.Linq.Expressions.ExpressionType.Negate || operation === $jsilcore.System.Linq.Expressions.ExpressionType.NegateChecked) {
binder.Method = function (callSite, target) {
return -target;
};
} else if (operation === $jsilcore.System.Linq.Expressions.ExpressionType.Not) {
binder.Method = function (callSite, target) {
if (typeof(target) === "boolean") {
return ~target;
}
return ~target;
};
} else if (operation === $jsilcore.System.Linq.Expressions.ExpressionType.IsTrue) {
binder.Method = function (callSite, target) {
return target === true;
};
} else if (operation === $jsilcore.System.Linq.Expressions.ExpressionType.IsFalse) {
binder.Method = function (callSite, target) {
return target === false;
};
} else {
throw new Error("Unary operator is not supported.");
}
return binder;
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
JSIL.MakeClass("System.Object", "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo", true, [], function ($) {
$.Method({ Static: false, Public: true }, ".ctor",
new JSIL.MethodSignature(null, [], []),
function () {
}
);

$.Method({ Static: true, Public: true }, "Create",
new JSIL.MethodSignature($.Type, [$jsilcore.TypeRef("Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags"), $.String], []),
function CSharpArgumentInfo_Create(flags, name) {
var info = new $jsilcore.Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo();
info.Flags = flags;
info.Name = name;
return info;
}
);

$.Field({ Public: false, Static: false }, "Flags", $jsilcore.TypeRef("Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags"));
$.Field({ Public: false, Static: false }, "Name", $.String);

});
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
JSIL.MakeClass("System.Object", "System.Runtime.CompilerServices.CallSite", true, [], function ($) {
});

JSIL.MakeClass("System.Object", "System.Runtime.CompilerServices.CallSite`1", true, ["T"], function ($) {
$.Method({ Static: true, Public: true }, "Create",
new JSIL.MethodSignature($.Type, [$jsilcore.TypeRef("System.Runtime.CompilerServices.CallSiteBinder")], []),
function(binder) {
var callSite = new this();
callSite.Target = binder.Method;
return callSite;
}
);

$.Field({ Public: false, Static: false }, "Target", new JSIL.GenericParameter("T", "System.Runtime.CompilerServices.CallSite`1"));
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
JSIL.MakeClass("System.Object", "System.Runtime.CompilerServices.CallSiteBinder", true, [], function($) {
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
JSIL.MakeEnum(
"Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags", true, {
None: 0,
UseCompileTimeType: 1,
Constant: 2,
NamedArgument: 4,
IsRef: 8,
IsOut: 16,
IsStaticType: 32
}, true
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
JSIL.MakeEnum(
"Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags", true, {
None: 0,
CheckedContext: 1,
InvokeSimpleName: 2,
InvokeSpecialName: 4,
BinaryOperationLogical: 8,
ConvertExplicit: 16,
ConvertArrayIndex: 32,
ResultIndexed: 64,
ValueFromCompoundAssignment: 128,
ResultDiscarded: 256
}, true
);
Loading