public void ConstructorChainingWithReorderedAndDefaultArgumentsWorks() { AssertCorrect( @"class C { public void M() {} static int F1() { return 0; } static int F2() { return 0; } static int F3() { return 0; } static int F4() { return 0; } public C(int a = 1, int b = 2, int c = 3, int d = 4, int e = 5, int f = 6, int g = 7) { } [System.Runtime.CompilerServices.CompilerGenerated] public C() : this(d: F1(), g: F2(), f: F3(), b: F4()) { M(); } }", @"function() { var $tmp1 = {sm_C}.F1(); var $tmp2 = {sm_C}.F2(); var $tmp3 = {sm_C}.F3(); {inst_C}.call(this, 1, {sm_C}.F4(), 3, $tmp1, 5, $tmp3, $tmp2); this.M(); }", metadataImporter: new MockMetadataImporter { GetConstructorSemantics = c => c.Parameters.Count == 0 ? ConstructorScriptSemantics.Named("ctor1") : ConstructorScriptSemantics.Unnamed() }); }
public void ChainingToUnnamedParamArrayConstructorThatExpandsArgumentsInNonExpandedFormWorks() { AssertCorrect( @"class C1 { static int[] args = new[] { 59, 12, 4 }; public C1(int x, int y, params int[] args) {} [System.Runtime.CompilerServices.CompilerGenerated] public C1() : this(4, 8, args) {} }", @"function() { {sm_C1}.apply(this, [4, 8].concat({sm_C1}.$args)); }", metadataImporter: new MockMetadataImporter { GetConstructorSemantics = c => c.Parameters.Count == 0 ? ConstructorScriptSemantics.Named("x") : ConstructorScriptSemantics.Unnamed(expandParams: true) }); AssertCorrect( @"class C1 { public C1(int x, int y, params int[] args) {} [System.Runtime.CompilerServices.CompilerGenerated] public C1() : this(4, 8, new[] { 59, 12, 4 }) {} }", @"function() { {sm_C1}.call(this, 4, 8, 59, 12, 4); }", metadataImporter: new MockMetadataImporter { GetConstructorSemantics = c => c.Parameters.Count == 0 ? ConstructorScriptSemantics.Named("x") : ConstructorScriptSemantics.Unnamed(expandParams: true) }); }
public void CanCallNamedConstructorWithReorderedAndDefaultArguments() { AssertCorrect( @"class X { public X(int a = 1, int b = 2, int c = 3, int d = 4, int e = 5, int f = 6, int g = 7) {} } int F1() { return 0; } int F2() { return 0; } int F3() { return 0; } int F4() { return 0; } public void M() { int a = 0, b = 0, c = 0; // BEGIN var x = new X(d: F1(), g: F2(), f: F3(), b: F4()); // END }", @" var $tmp1 = this.$F1(); var $tmp2 = this.$F2(); var $tmp3 = this.$F3(); var $x = new {inst_X}.$ctor2(1, this.$F4(), 3, $tmp1, 5, $tmp3, $tmp2); ", metadataImporter: new MockMetadataImporter { GetConstructorSemantics = c => ConstructorScriptSemantics.Named("$ctor2"), GetMethodSemantics = m => MethodScriptSemantics.NormalMethod("$" + m.Name) }); }
public void SetConstructorSemanticsWorks() { Prepare(@"public class C { public C() {} public C(int i) {} }", () => { Metadata.SetConstructorSemantics(FindConstructor("C", 0), ConstructorScriptSemantics.Named("__something_else__")); }); Assert.AreEqual(Metadata.GetConstructorSemantics(FindConstructor("C", 0)).Type, ConstructorScriptSemantics.ImplType.NamedConstructor); Assert.AreEqual(Metadata.GetConstructorSemantics(FindConstructor("C", 0)).Name, "__something_else__"); Assert.AreEqual(Metadata.GetConstructorSemantics(FindConstructor("C", 1)).Type, ConstructorScriptSemantics.ImplType.UnnamedConstructor); }
public void InvokingNamedParamArrayConstructorThatExpandsArgumentsInExpandedFormWorks() { AssertCorrect( @"class C1 { public C1(int x, int y, params int[] args) {} } public void M() { // BEGIN var c = new C1(4, 8, 59, 12, 4); // END }", @" var $c = new {sm_C1}.X(4, 8, 59, 12, 4); ", metadataImporter: new MockMetadataImporter { GetConstructorSemantics = c => ConstructorScriptSemantics.Named("X", expandParams: true) }); }
public void CanCallNamedConstructorWithNoArguments() { AssertCorrect( @"class X { } public void M() { // BEGIN var c = new X(); // END }", @" var $c = new {inst_X}.$ctor2(); ", metadataImporter: new MockMetadataImporter { GetConstructorSemantics = c => ConstructorScriptSemantics.Named("$ctor2") }); }
public void ChainingToUnnamedParamArrayConstructorThatDoesNotExpandArgumentsInExpandedFormWorks() { AssertCorrect( @"class C1 { public C1(int x, int y, params int[] args) {} [System.Runtime.CompilerServices.CompilerGenerated] public C1() : this(4, 8, 59, 12, 4) {} }", @"function() { {sm_C1}.call(this, 4, 8, [59, 12, 4]); }", metadataImporter: new MockMetadataImporter { GetConstructorSemantics = c => c.Parameters.Count == 0 ? ConstructorScriptSemantics.Named("x") : ConstructorScriptSemantics.Unnamed() }); }
public void CanCallNamedConstructorWithArguments() { AssertCorrect( @"class X { public X(int x, int y, int z) {} } public void M() { int a = 0, b = 0, c = 0; // BEGIN var t = new X(a, b, c); // END }", @" var $t = new {inst_X}.$ctor2($a, $b, $c); ", metadataImporter: new MockMetadataImporter { GetConstructorSemantics = c => ConstructorScriptSemantics.Named("$ctor2") }); }
public MockMetadataImporter() { GetTypeSemantics = t => { if (t.DeclaringTypeDefinition == null) { return(TypeScriptSemantics.NormalType(t.FullName)); } else { return(TypeScriptSemantics.NormalType(GetTypeSemantics(t.DeclaringTypeDefinition).Name + "$" + t.Name)); } }; GetMethodSemantics = m => MethodScriptSemantics.NormalMethod(m.Name); GetConstructorSemantics = c => { if (c.DeclaringType.Kind == TypeKind.Anonymous) { return(ConstructorScriptSemantics.Json(new IMember[0])); } else if (c.DeclaringType.GetConstructors().Count() == 1 || c.Parameters.Count == 0) { return(ConstructorScriptSemantics.Unnamed()); } else { return(ConstructorScriptSemantics.Named("ctor$" + String.Join("$", c.Parameters.Select(p => p.Type.Name)))); } }; GetPropertySemantics = p => { if (p.DeclaringType.Kind == TypeKind.Anonymous || (p.DeclaringType.FullName == "System.Array" && p.Name == "Length")) { string name = p.Name.Replace("<>", "$"); return(PropertyScriptSemantics.Field(name.StartsWith("$") ? name : ("$" + name))); } else { return(PropertyScriptSemantics.GetAndSetMethods(MethodScriptSemantics.NormalMethod("get_" + p.Name), MethodScriptSemantics.NormalMethod("set_" + p.Name))); } }; GetDelegateSemantics = d => new DelegateScriptSemantics(); GetAutoPropertyBackingFieldName = p => "$" + p.Name; ShouldGenerateAutoPropertyBackingField = p => true; GetFieldSemantics = f => FieldScriptSemantics.Field("$" + f.Name); GetEventSemantics = e => EventScriptSemantics.AddAndRemoveMethods(MethodScriptSemantics.NormalMethod("add_" + e.Name), MethodScriptSemantics.NormalMethod("remove_" + e.Name)); GetAutoEventBackingFieldName = e => "$" + e.Name; ShouldGenerateAutoEventBackingField = e => true; }
public void CreatingObjectWithDynamicArgumentGivesAnErrorWhenNamesDifferBetweenApplicableMethods() { var er = new MockErrorReporter(); Compile(new[] { @"public class C1 { public C1(int x) {} public C1(string x) {} } public class C { public void M() { dynamic d = null; // BEGIN var c = new C1(d); // END } }" }, metadataImporter: new MockMetadataImporter { GetConstructorSemantics = c => c.Parameters.Count > 0 ? ConstructorScriptSemantics.Named("C$" + c.Parameters[0].Type.Name) : ConstructorScriptSemantics.Unnamed() }, errorReporter: er); Assert.That(er.AllMessages.Count, Is.EqualTo(1)); Assert.That(er.AllMessages.Any(m => m.Code == 7531)); er = new MockErrorReporter(); Compile(new[] { @"public class C1 { public C1(int x) {} public C1(string x) {} } public class C { public void M() { dynamic d = null; // BEGIN var c = new C1(d); // END } }" }, metadataImporter: new MockMetadataImporter { GetConstructorSemantics = c => c.Parameters.Count > 0 ? ConstructorScriptSemantics.StaticMethod("C$" + c.Parameters[0].Type.Name) : ConstructorScriptSemantics.Unnamed() }, errorReporter: er); Assert.That(er.AllMessages.Count, Is.EqualTo(1)); Assert.That(er.AllMessages.Any(m => m.Code == 7531)); }
public void CreatingObjectWithDynamicArgumentWorksWhenAllCandidatesAreNamedConstructorsWithTheSameName() { AssertCorrect( @"public class C1 { public C1(int x) {} public C1(string x) {} } public void M() { dynamic d = null; // BEGIN var c = new C1(d); // END }", @" var $c = new {inst_C1}.X($d); ", metadataImporter: new MockMetadataImporter { GetConstructorSemantics = c => ConstructorScriptSemantics.Named("X", generateCode: false) }); }
public void InvokingNamedParamArrayConstructorThatExpandsArgumentsInNonExpandedFormWorks() { AssertCorrect( @"public C(int x, int y, params int[] args) {} public void M() { var args = new[] { 59, 12, 4 }; // BEGIN var c1 = new C(4, 8, args); var c2 = new C(4, 8, new[] { 59, 12, 4 }); // END }", @" var $c1 = $ApplyConstructor({sm_C}.X, [4, 8].concat($args)); var $c2 = new {sm_C}.X(4, 8, 59, 12, 4); ", metadataImporter: new MockMetadataImporter { GetConstructorSemantics = c => ConstructorScriptSemantics.Named("X", expandParams: true) }); AssertCorrect( @"public C(int x, params int[] args) {} public void M() { var args = new[] { 59, 12, 4 }; // BEGIN var c = new C(4, args); // END }", @" var $c = $ApplyConstructor({sm_C}.X, [4].concat($args)); ", metadataImporter: new MockMetadataImporter { GetConstructorSemantics = c => ConstructorScriptSemantics.Named("X", expandParams: true) }); AssertCorrect( @"public C(params int[] args) {} public void M() { var args = new[] { 59, 12, 4 }; // BEGIN var c = new C(args); // END }", @" var $c = $ApplyConstructor({sm_C}.X, $args); ", metadataImporter: new MockMetadataImporter { GetConstructorSemantics = c => ConstructorScriptSemantics.Named("X", expandParams: true) }); }
public void ChainingToParamArrayConstructorThatExpandsArgumentsInNonExpandedFormIsAnError() { var er = new MockErrorReporter(false); Compile(new[] { @"class C1 { public C1(int x, int y, params int[] args) {} [System.Runtime.CompilerServices.CompilerGenerated] public C1() : this(4, 8, new[] { 59, 12, 4 }) {} }" }, metadataImporter: new MockMetadataImporter { GetConstructorSemantics = c => c.Parameters.Count == 0 ? ConstructorScriptSemantics.Unnamed() : ConstructorScriptSemantics.Named("x", expandParams: true) }, errorReporter: er); Assert.That(er.AllMessagesText.Count, Is.EqualTo(1)); Assert.That(er.AllMessagesText[0].Contains("C1") && er.AllMessagesText[0].Contains("constructor") && er.AllMessagesText[0].Contains("expanded form")); }
public void ConstructorsCanBeOverloadedWithDifferentImplementations() { var metadataImporter = new MockMetadataImporter { GetConstructorSemantics = ctor => ctor.Parameters[0].Type.Name == "String" ? ConstructorScriptSemantics.Named("StringCtor") : ConstructorScriptSemantics.StaticMethod("IntCtor") }; Compile(new[] { "class C { C(int i) {} C(string s) {} }" }, metadataImporter: metadataImporter); FindClass("C").NamedConstructors.Should().HaveCount(1); FindClass("C").StaticMethods.Should().HaveCount(1); FindNamedConstructor("C.StringCtor").Should().NotBeNull(); FindStaticMethod("C.IntCtor").Should().NotBeNull(); }
public void DefaultConstructorIsNotInsertedIfOtherConstructorIsDefined() { var metadataImporter = new MockMetadataImporter() { GetConstructorSemantics = c => c.Parameters.Count == 0 ? ConstructorScriptSemantics.Unnamed() : ConstructorScriptSemantics.Named("ctor$" + string.Join("$", c.Parameters.Select(p => p.Type.Name))) }; Compile(new[] { "class C { C(int i) {} }" }, metadataImporter: metadataImporter); var cls = FindClass("C"); cls.UnnamedConstructor.Should().BeNull(); cls.NamedConstructors.Should().HaveCount(1); cls.NamedConstructors[0].Name.Should().Be("ctor$Int32"); cls.NamedConstructors[0].Definition.Should().NotBeNull(); }