public void MethodGroupConversionOnInlineCodeStaticMethodPrefixedWithClassNameWorks() { AssertCorrect( @"static void F(int x) {} public void M() { System.Action<int> f; // BEGIN f = C.F; // END }", @" $f = function($tmp1) { $tmp1; }; ", metadataImporter: new MockMetadataImporter { GetMethodSemantics = m => m.Name == "F" ? MethodScriptSemantics.InlineCode("{x}") : MethodScriptSemantics.NormalMethod(m.Name) }); }
public void AssigningToPropertyWithSetMethodImplementedAsInlineCodeWorksStruct() { AssertCorrect( @"int P { get; set; } public void M() { int i = 0; // BEGIN P = i; // END }", @" set_(this)._($Clone($i, {to_Int32})); ", metadataImporter: new MockMetadataImporter { GetPropertySemantics = p => PropertyScriptSemantics.GetAndSetMethods(MethodScriptSemantics.InlineCode("get_({this})"), MethodScriptSemantics.InlineCode("set_({this})._({value})")), GetTypeSemantics = t => TypeScriptSemantics.MutableValueType(t.Name) }); }
public void GetEnumeratorAsInlineCodeWithEnumerateAsArray() { AssertCorrect( @"public class X { class MyEnumerable { public MyEnumerator GetEnumerator() { return null; } } sealed class MyEnumerator { public int Current { get { return 0; } } public bool MoveNext() {} } public void M() { var enm = new MyEnumerable(); // BEGIN foreach (var item in enm) { int x = 0; } // END }", @" for (var $tmp1 = 0; $tmp1 < $enm.$Length; $tmp1++) { var $item = $enm[$tmp1]; var $x = 0; } ", metadataImporter: new MockMetadataImporter { GetMethodSemantics = m => m.Name == "GetEnumerator" ? MethodScriptSemantics.InlineCode("X", enumerateAsArray: true) : MethodScriptSemantics.NormalMethod("$" + m.Name) }); }
public void UsingEventRemoveAccessorImplementedAsInlineCodeWorks() { AssertCorrect( @"event System.EventHandler MyEvent; public void M() { System.EventHandler h = null; // BEGIN MyEvent -= h; // END }", @" remove_(this)._($h); ", metadataImporter: new MockMetadataImporter() { GetEventSemantics = e => EventScriptSemantics.AddAndRemoveMethods(MethodScriptSemantics.InlineCode("add_({this})._({value})"), MethodScriptSemantics.InlineCode("remove_({this})._({value})")) }); }
public void AssigningToIndexerImplementedAsInlineCodeWorksStruct() { AssertCorrect( @"int this[int x, int y] { get { return 0; } set {} } public void M() { int i = 0, j = 1, k = 2; // BEGIN this[i, j] = k; // END }", @" set_(this)._($Clone($i, {to_Int32}))._($Clone($j, {to_Int32}))._($Clone($k, {to_Int32})); ", metadataImporter: new MockMetadataImporter { GetPropertySemantics = p => p.IsIndexer ? PropertyScriptSemantics.GetAndSetMethods(MethodScriptSemantics.InlineCode("get_({this})._({x})._({y})"), MethodScriptSemantics.InlineCode("set_({this})._({x})._({y})._({value})")) : PropertyScriptSemantics.Field(p.Name), GetTypeSemantics = t => TypeScriptSemantics.MutableValueType(t.Name) }); }
public void InlineCodeWithSyntaxErrorIsAnError() { var er = new MockErrorReporter(false); Compile(new[] { @"class C { public void F(string p1, int p2, params string[] p3) {} public void M() { string[] args = null; // BEGIN F(""x"", 1, ""y"", ""z""); // END } }" }, metadataImporter: new MockMetadataImporter { GetMethodSemantics = m => m.Name == "F" ? MethodScriptSemantics.InlineCode("{p1}*{p2}+") : MethodScriptSemantics.NormalMethod(m.Name) }, errorReporter: er); Assert.That(er.AllMessagesText.Count, Is.EqualTo(1)); Assert.That(er.AllMessagesText.Any(m => m.Contains("syntax error"))); }
public void InvokingInlineCodeMethodWithTypeParameterAsTypeArgumentWorks() { AssertCorrect( @"public class C2<T1> { public void F<T2>() {} } public class C<T3> { public void M<T4>() { var c = new C2<T3>(); // BEGIN c.F<T4>(); // END } }", @" ga_$T3._(ga_$T4); ", addSkeleton: false, metadataImporter: new MockMetadataImporter { GetMethodSemantics = m => m.Name == "F" ? MethodScriptSemantics.InlineCode("{T1}._({T2})") : MethodScriptSemantics.NormalMethod(m.Name) }); }
public void PostfixForIndexerImplementedAsInlineCodeWorks() { AssertCorrect( @"int this[int x, int y] { get { return 0; } set {} } public void M() { int i = 0, j = 1, k = 2; // BEGIN ++this[i, j]; // END }", @" set_(this)._($i)._($j)._(get_(this)._($i)._($j) + 1); ", metadataImporter: new MockMetadataImporter { GetPropertySemantics = p => p.IsIndexer ? PropertyScriptSemantics.GetAndSetMethods(MethodScriptSemantics.InlineCode("get_({this})._({x})._({y})"), MethodScriptSemantics.InlineCode("set_({this})._({x})._({y})._({value})")) : PropertyScriptSemantics.Field(p.Name) }); }
public void UsingTextWithBracesInLiteralCodeWorks() { AssertCorrect( @"public void F(int arg1, string arg2) {} public void M() { // BEGIN F(45, ""test""); // END }", @" {}; ", metadataImporter: new MockMetadataImporter { GetMethodSemantics = m => m.Name == "F" ? MethodScriptSemantics.InlineCode("{{ }}") : MethodScriptSemantics.NormalMethod(m.Name) }); }
public void InlineCodeImplementationOfGetResultWorks() { try { StatementCompiler.DisableStateMachineRewriteTestingUseOnly = true; AssertCorrect(@" using System; public class MyAwaiter : System.Runtime.CompilerServices.INotifyCompletion { public bool IsCompleted { get { return false; } } public void OnCompleted(Action continuation) {} public int GetResult() {} } public class Awaitable { public MyAwaiter GetAwaiter() { return null; } } public class C { public async void M() { Awaitable x = null; // BEGIN await x; // END } } ", @" var $tmp1 = $x.$GetAwaiter(); await $tmp1:$OnCompleted; _GetResult($tmp1)._; ", addSkeleton: false, metadataImporter: new MockMetadataImporter { GetMethodSemantics = m => m.Name == "GetResult" ? MethodScriptSemantics.InlineCode("_GetResult({this})._") : MethodScriptSemantics.NormalMethod("$" + m.Name) }); } finally { StatementCompiler.DisableStateMachineRewriteTestingUseOnly = false; } }
public void InlineCodeImplementationOfOnCompletedIsAnError() { var er = new MockErrorReporter(); Compile(new[] { @" using System; public class MyAwaiter : System.Runtime.CompilerServices.INotifyCompletion { public bool IsCompleted { get { return false; } } public void OnCompleted(Action continuation) {} public int GetResult() {} } public class Awaitable { public MyAwaiter GetAwaiter() { return null; } } public class C { public async void M() { Awaitable x = null; await x; } }" }, metadataImporter: new MockMetadataImporter { GetMethodSemantics = m => m.Name == "OnCompleted" ? MethodScriptSemantics.InlineCode("_OnCompleted({this})._") : MethodScriptSemantics.NormalMethod("$" + m.Name) }, errorReporter: er); Assert.That(er.AllMessagesText.Count, Is.EqualTo(1)); Assert.That(er.AllMessagesText.Any(e => e.Contains("OnCompleted") && e.Contains("normal method") && e.Contains("await"))); }
public void MethodGroupConversionOnExtensionMethodImplementedAsInlineCodeAppliedToThis() { AssertCorrect( @"using System; static class Ext { public static void F(this C c, int a, int b) {} } class C { public void M() { // BEGIN Action<int, int> f = this.F; // END } } ", @" var $f = $Bind(function($tmp1, $tmp2) { _(this)._($tmp1)._($tmp2); }, this); ", addSkeleton: false, metadataImporter: new MockMetadataImporter { GetMethodSemantics = m => m.Name == "F" ? MethodScriptSemantics.InlineCode("_({c})._({a})._({b})") : MethodScriptSemantics.NormalMethod("$" + m.Name) }); }
public void MethodGroupConversionOnExtensionMethodImplementedAsInlineCode_ExpandParams() { AssertCorrect( @"using System; static class Ext { public static void F(this string s, int a, int[] b) {} } class C { public void M() { string s = null; // BEGIN Action<int, int[]> f = s.F; // END } } ", @" var $f = function($tmp1) { _($s)._($tmp1)._(Array.prototype.slice.call(arguments, 1)); }; ", addSkeleton: false, metadataImporter: new MockMetadataImporter { GetMethodSemantics = m => m.Name == "F" ? MethodScriptSemantics.InlineCode("_({s})._({a})._({b})") : MethodScriptSemantics.NormalMethod("$" + m.Name), GetDelegateSemantics = d => new DelegateScriptSemantics(expandParams: true) }); }
public void MethodGroupConversionOnExtensionMethodImplementedAsInlineCode_WithReturnValue() { AssertCorrect( @"using System; static class Ext { public static int F(this string s, int a, params int[] b) { return 0; } } class C { public void M() { string s = null; // BEGIN Func<int, int[], int> f = s.F; // END } } ", @" var $f = function($tmp1, $tmp2) { return _($s)._($tmp1)._($tmp2); }; ", addSkeleton: false, metadataImporter: new MockMetadataImporter { GetMethodSemantics = m => m.Name == "F" ? MethodScriptSemantics.InlineCode("_({s})._({a})._({b})") : MethodScriptSemantics.NormalMethod("$" + m.Name) }); }
public void InvokingMethodWithExpandedParamArrayWorksForNewExpressions() { AssertCorrect( @"public void F(string p1, int p2, params string[] p3) {} public void M() { // BEGIN F(""x"", 4); F(""x"", 4, ""y""); F(""x"", 4, ""y"", ""z""); // END }", @" 'x' * new 4(); 'x' * new 4('y'); 'x' * new 4('y', 'z'); ", metadataImporter: new MockMetadataImporter { GetMethodSemantics = m => m.Name == "F" ? MethodScriptSemantics.InlineCode("{p1}* new {p2}({*p3})") : MethodScriptSemantics.NormalMethod(m.Name) }); AssertCorrect( @"public void F(string p1, int p2, params string[] p3) {} public void M() { // BEGIN F(""x"", 4); F(""x"", 4, ""y""); F(""x"", 4, ""y"", ""z""); // END }", @" 'x' * new 4(A); 'x' * new 4(A, 'y'); 'x' * new 4(A, 'y', 'z'); ", metadataImporter: new MockMetadataImporter { GetMethodSemantics = m => m.Name == "F" ? MethodScriptSemantics.InlineCode("{p1}* new {p2}(A, {*p3})") : MethodScriptSemantics.NormalMethod(m.Name) }); }
public void UsingParametersFromLiteralCodeWorks() { AssertCorrect( @"public void F(int arg1, string arg2) {} public void M() { // BEGIN F(45, ""test""); // END }", @" { item1: 45, item2: 'test' }; ", metadataImporter: new MockMetadataImporter { GetMethodSemantics = m => m.Name == "F" ? MethodScriptSemantics.InlineCode("{{ item1: {arg1}, item2: {arg2} }}") : MethodScriptSemantics.NormalMethod(m.Name) }); }
public void InvokingMethodWithExpandedParamArrayWorksForArrayLiterals() { AssertCorrect( @"public void F(string p1, int p2, params string[] p3) {} public void M() { // BEGIN F(""x"", 4); F(""x"", 4, ""y""); F(""x"", 4, ""y"", ""z""); // END }", @" 'x' * 4 + []; 'x' * 4 + ['y']; 'x' * 4 + ['y', 'z']; ", metadataImporter: new MockMetadataImporter { GetMethodSemantics = m => m.Name == "F" ? MethodScriptSemantics.InlineCode("{p1}*{p2} + [{*p3}]") : MethodScriptSemantics.NormalMethod(m.Name) }); AssertCorrect( @"public void F(string p1, int p2, params string[] p3) {} public void M() { // BEGIN F(""x"", 4); F(""x"", 4, ""y""); F(""x"", 4, ""y"", ""z""); // END }", @" 'x' * 4 + [A]; 'x' * 4 + [A, 'y']; 'x' * 4 + [A, 'y', 'z']; ", metadataImporter: new MockMetadataImporter { GetMethodSemantics = m => m.Name == "F" ? MethodScriptSemantics.InlineCode("{p1}*{p2} + [A, {*p3}]") : MethodScriptSemantics.NormalMethod(m.Name) }); }
public void UsingThisInInlineCodeForInstanceMethodWorks() { AssertCorrect( @"class C1 { public void F() {} } public void M() { var c = new C1(); // BEGIN c.F(); // END }", @" [$c]; ", metadataImporter: new MockMetadataImporter { GetMethodSemantics = m => m.Name == "F" ? MethodScriptSemantics.InlineCode("[ {this} ]") : MethodScriptSemantics.NormalMethod(m.Name) }); }
public void InvokingMethodWithExpandedParamArrayInNonExpandedFormIsAnError() { var er = new MockErrorReporter(false); Compile(new[] { @"class C { public void F(string p1, int p2, params string[] p3) {} public void M() { string[] args = null; // BEGIN F(""x"", 1, new[] { ""y"", ""z"" }); // END } }" }, metadataImporter: new MockMetadataImporter { GetMethodSemantics = m => m.Name == "F" ? MethodScriptSemantics.InlineCode("{p1}*{p2}({*p3})") : MethodScriptSemantics.NormalMethod(m.Name) }, errorReporter: er); Assert.That(er.AllMessagesText.Count, Is.EqualTo(1)); Assert.That(er.AllMessagesText.Any(m => m.Contains("C.F") && m.Contains("expanded"))); }
public void UsingMethodTypeArgumentsFromLiteralCodeWorks() { AssertCorrect( @"public void F<T1, T2>(T1 arg1, T2 arg2) {} public void M() { // BEGIN F(45, ""test""); // END }", @" { item1: {ga_Int32}, item2: {ga_String} }; ", metadataImporter: new MockMetadataImporter { GetMethodSemantics = m => m.Name == "F" ? MethodScriptSemantics.InlineCode("{{ item1: {T1}, item2: {T2} }}") : MethodScriptSemantics.NormalMethod(m.Name) }); }
private void AssertCorrect(string csharp, string expected) { AssertCorrect(@" using System; using System.Collections.Generic; using System.Linq; class C { " + csharp + @" }", expected, references: _referencesLazy.Value, addSkeleton: false, metadataImporter: new MockMetadataImporter { GetMethodSemantics = m => m.DeclaringTypeDefinition.FullName == "System.Linq.Enumerable" ? MethodScriptSemantics.InlineCode("{" + m.Parameters[0].Name + "}.$" + m.Name + "(" + string.Join(", ", m.Parameters.Skip(1).Select(p => "{" + p.Name + "}")) + ")") : MethodScriptSemantics.NormalMethod("$" + m.Name, ignoreGenericArguments: true), GetTypeSemantics = t => TypeScriptSemantics.NormalType(t.Name, ignoreGenericArguments: true) }, runtimeLibrary: new MockRuntimeLibrary { Upcast = (e, _1, _2, _) => e }); }
public void UsingTypeTypeArgumentsFromLiteralCodeWorks() { AssertCorrect( @"class C1<T1> { public class C2<T2> { public void F() { } } } public void M() { var c = new C1<int>.C2<string>(); // BEGIN c.F(); // END }", @" { item1: {ga_Int32}, item2: {ga_String} }; ", metadataImporter: new MockMetadataImporter { GetMethodSemantics = m => m.Name == "F" ? MethodScriptSemantics.InlineCode("{{ item1: {T1}, item2: {T2} }}") : MethodScriptSemantics.NormalMethod(m.Name) }); }
public void ReadingPropertyWithGetMethodImplementedAsInlineCodeWorks() { AssertCorrect( @"int P { get; set; } public void M() { // BEGIN int i = P; // END }", @" var $i = get_(this); ", metadataImporter: new MockMetadataImporter { GetPropertySemantics = p => PropertyScriptSemantics.GetAndSetMethods(MethodScriptSemantics.InlineCode("get_({this})"), MethodScriptSemantics.InlineCode("set_({this})._({value})")) }); }
public void UsingTypeReferenceFromLiteralCodeWorks() { AssertCorrect( @"public void F() {} public void M() { // BEGIN F(); // END }", @" [{ga_String}, {ga_Int32}]; ", metadataImporter: new MockMetadataImporter { GetMethodSemantics = m => m.Name == "F" ? MethodScriptSemantics.InlineCode("[ {$System.String}, {$System.Int32} ]") : MethodScriptSemantics.NormalMethod(m.Name) }); }
public void AssigningToPropertyWithSetMethodImplementedAsInlineCodeWorks() { AssertCorrect( @"int P { get; set; } public void M() { int i = 0; // BEGIN P = i; // END }", @" set_(this)._($i); ", metadataImporter: new MockMetadataImporter { GetPropertySemantics = p => PropertyScriptSemantics.GetAndSetMethods(MethodScriptSemantics.InlineCode("get_({this})"), MethodScriptSemantics.InlineCode("set_({this})._({value})")) }); }
public void UsingLiteralStringParameterToUseAsIdentifierFromLiteralCodeWorks() { AssertCorrect( @"public void F(string s) {} public void M() { // BEGIN F(""X""); // END }", @" invoke_X; ", metadataImporter: new MockMetadataImporter { GetMethodSemantics = m => m.Name == "F" ? MethodScriptSemantics.InlineCode("invoke_{@s}") : MethodScriptSemantics.NormalMethod(m.Name) }); }
public virtual void SetMethodSemantics(IMethod method, MethodScriptSemantics semantics) { _prev.SetMethodSemantics(method, semantics); }
public void InvokingMethodThatExpectsLiteralStringWithSomethingElseIsAnError() { var er = new MockErrorReporter(false); Compile(new[] { @"class C { public void F(string myParameter) {} public void M() { string s = ""X""; // BEGIN F(s); // END } }" }, metadataImporter: new MockMetadataImporter { GetMethodSemantics = m => m.Name == "F" ? MethodScriptSemantics.InlineCode("invoke_{@myParameter}") : MethodScriptSemantics.NormalMethod(m.Name) }, errorReporter: er); Assert.That(er.AllMessagesText.Count, Is.EqualTo(1)); Assert.That(er.AllMessagesText.Any(m => m.Contains("myParameter") && m.Contains("literal string"))); }
public void UsingAMethodMarkedAsNotUsableFromScriptGivesAnError() { var er = new MockErrorReporter(false); Compile(new[] { "class Class { int UnusableMethod() {} public void M() { System.Func<int> f; f = UnusableMethod; } }" }, metadataImporter: new MockMetadataImporter { GetMethodSemantics = m => m.Name == "UnusableMethod" ? MethodScriptSemantics.NotUsableFromScript() : MethodScriptSemantics.NormalMethod(m.Name) }, errorReporter: er); Assert.That(er.AllMessages.Any(msg => msg.Severity == MessageSeverity.Error && msg.FormattedMessage.Contains("Class.UnusableMethod"))); }
public void CannotPerformMethodGroupConversionOnStaticMethodWithThisAsFirstArgumentThatExpandsParamsToDelegateThatDoesNot() { var er = new MockErrorReporter(false); Compile(new[] { @"class C1 { public void F(int x, int y, params int[] args) {} public void M() { System.Action<int, int, int[]> a = F; } }" }, metadataImporter: new MockMetadataImporter { GetMethodSemantics = m => m.Name == "F" ? MethodScriptSemantics.StaticMethodWithThisAsFirstArgument("$F", expandParams: true) : MethodScriptSemantics.NormalMethod(m.Name) }, errorReporter: er); Assert.That(er.AllMessages.Count, Is.EqualTo(1)); Assert.That(er.AllMessages[0].FormattedMessage.Contains("C1.F") && er.AllMessages[0].FormattedMessage.Contains("System.Action") && er.AllMessages[0].FormattedMessage.Contains("expand") && er.AllMessages[0].FormattedMessage.Contains("param array")); }