Skip to content

Commit 66b6ebb

Browse files
committed
Add JSIL.Services.Get method in JSIL.Meta that allows you to invoke JSIL.Host.getService at runtime in JS (and always fails in C#).
1 parent 78009b9 commit 66b6ebb

6 files changed

Lines changed: 68 additions & 1 deletion

File tree

‎JSIL/AST/JSIdentifierTypes.cs‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,12 @@ public override string Identifier {
2323
public class JSRawOutputIdentifier : JSIdentifier {
2424
public readonly Action<JavascriptFormatter> Emitter;
2525

26-
public JSRawOutputIdentifier (Action<JavascriptFormatter> emitter, TypeReference type = null)
26+
public JSRawOutputIdentifier (Action<JavascriptFormatter> emitter, TypeReference type)
2727
: base(type) {
28+
29+
if (type == null)
30+
throw new ArgumentNullException("type");
31+
2832
Emitter = emitter;
2933
}
3034

‎JSIL/ILBlockTranslator.cs‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,7 @@ protected JSExpression Translate_MethodReplacement (
460460
return JSInvocationExpression.InvokeStatic(
461461
JS.eval, arguments
462462
);
463+
463464
case "System.Object JSIL.Verbatim::Expression(System.String)": {
464465
var expression = arguments[0] as JSStringLiteral;
465466
if (expression == null)
@@ -469,6 +470,7 @@ protected JSExpression Translate_MethodReplacement (
469470
method.Reference, expression.Value, null, null
470471
);
471472
}
473+
472474
case "System.Object JSIL.JSGlobal::get_Item(System.String)": {
473475
var expression = arguments[0] as JSStringLiteral;
474476
if (expression != null)
@@ -480,6 +482,7 @@ protected JSExpression Translate_MethodReplacement (
480482
JSIL.GlobalNamespace, arguments[0], TypeSystem.Object
481483
);
482484
}
485+
483486
case "System.Object JSIL.JSLocal::get_Item(System.String)": {
484487
var expression = arguments[0] as JSStringLiteral;
485488
if (expression == null)
@@ -493,6 +496,22 @@ protected JSExpression Translate_MethodReplacement (
493496

494497
case "System.Boolean JSIL.Builtins::get_IsJavascript()":
495498
return new JSBooleanLiteral(true);
499+
500+
case "System.Object JSIL.Services::Get(System.String,System.Boolean)": {
501+
if (arguments.Length != 2)
502+
throw new InvalidOperationException("JSIL.Services.Get must receive two arguments");
503+
504+
var serviceName = arguments[0];
505+
var shouldThrow = arguments[1];
506+
507+
return JSInvocationExpression.InvokeStatic(
508+
new JSRawOutputIdentifier((f) => f.WriteRaw("JSIL.Host.getService"), TypeSystem.Object),
509+
new[] {
510+
serviceName,
511+
new JSUnaryOperatorExpression(JSOperator.LogicalNot, shouldThrow, TypeSystem.Boolean)
512+
}, true
513+
);
514+
}
496515
}
497516

498517
JSExpression result = Translate_PropertyCall(thisExpression, method, arguments, @virtual, @static);

‎Meta/Verbatim.cs‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,20 @@
55
using System.Text;
66

77
namespace JSIL {
8+
public static class Services {
9+
/// <summary>
10+
/// When running as C#, this method throws (or returns null if throwIfMissing==false).
11+
/// When running as JavaScript this method returns a reference to the named runtime service.
12+
/// </summary>
13+
/// <param name="serviceName">The name of the runtime service.</param>
14+
public static object Get (string serviceName, bool throwIfMissing = true) {
15+
if (throwIfMissing)
16+
throw new NotImplementedException("Services.get is only available at runtime and you passed true for throwIfMissing.");
17+
else
18+
return null;
19+
}
20+
}
21+
822
public static class Builtins {
923
public static readonly JSGlobal Global = new JSGlobal();
1024
public static readonly JSLocal Local = new JSLocal();
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using System;
2+
using JSIL;
3+
4+
public static class Program {
5+
public static void Main (string[] args) {
6+
object service = null;
7+
8+
try {
9+
service = JSIL.Services.Get("nonexistent");
10+
Console.WriteLine("didn't throw");
11+
} catch {
12+
Console.WriteLine("threw");
13+
}
14+
15+
service = JSIL.Services.Get("stdout", false);
16+
if (service == null)
17+
Console.WriteLine("null");
18+
else
19+
Console.WriteLine("not null");
20+
}
21+
}

‎Tests/Tests.csproj‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@
301301
<None Include="ReflectionTestCases\GetConstantAttributes.cs" />
302302
<None Include="TestCases\NestedStructEquals.cs" />
303303
<None Include="TestCases\ComplexStructEquals.cs" />
304+
<None Include="SpecialTestCases\GetHostService.cs" />
304305
<Compile Include="XMLTests.cs" />
305306
<Compile Include="DependencyTests.cs" />
306307
<None Include="TestCases\GenericParameterNameShadowing.cs" />

‎Tests/VerbatimTests.cs‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,13 @@ public void BuiltinsThisEvaluatesToJSThis () {
3838
"", "Program/CustomType"
3939
);
4040
}
41+
42+
[Test]
43+
public void GetHostService () {
44+
GenericTest(
45+
@"SpecialTestCases\GetHostService.cs",
46+
"threw\r\nnull", "threw\r\nnot null"
47+
);
48+
}
4149
}
4250
}

0 commit comments

Comments
 (0)