Beispiel #1
0
        public void StaticConstructorBodyGetsAddedLastInTheStaticInitStatements()
        {
            var metadataImporter = new MockMetadataImporter {
                GetConstructorSemantics = ctor => { if (ctor.IsStatic)
                                                    {
                                                        throw new InvalidOperationException();
                                                    }
                                                    else
                                                    {
                                                        return(ConstructorScriptSemantics.Unnamed());
                                                    } }
            };

            Compile(new[] {
                @"class C {
	static int x = 0;
	static C() {
		int z = 2;
	}
	static int y = 1;
}"
            }, metadataImporter: metadataImporter);

            var cctor = OutputFormatter.Format(FindClass("C").StaticInitStatements, allowIntermediates: true);

            cctor.Replace("\r\n", "\n").Should().Be(
                @"$Init({sm_C}, '$x', 0);
$Init({sm_C}, '$y', 1);
var $z = 2;
".Replace("\r\n", "\n"));
        }
Beispiel #2
0
        public void StaticFieldsWithInitializersInGenericTypeAreInitialized()
        {
            var metadataImporter = new MockMetadataImporter {
                GetConstructorSemantics = ctor => { if (ctor.IsStatic)
                                                    {
                                                        throw new InvalidOperationException();
                                                    }
                                                    else
                                                    {
                                                        return(ConstructorScriptSemantics.Unnamed());
                                                    } }
            };

            Compile(new[] {
                @"class C<T> {
	static T x = default(T);
	static int y = 42;
	static string z = ""X"";
}"
            }, metadataImporter: metadataImporter);

            var cctor = OutputFormatter.Format(FindClass("C").StaticInitStatements, allowIntermediates: true);

            cctor.Replace("\r\n", "\n").Should().Be(
                @"$Init(sm_$InstantiateGenericType({C}, $T), '$x', $Default($T));
$Init(sm_$InstantiateGenericType({C}, $T), '$y', 42);
$Init(sm_$InstantiateGenericType({C}, $T), '$z', 'X');
".Replace("\r\n", "\n"));
        }
Beispiel #3
0
        public void InvokingBaseConstructorWithReorderedAndDefaultArgumentsWorks()
        {
            AssertCorrect(
                @"class B {
	public B(int a = 1, int b = 2, int c = 3, int d = 4, int e = 5, int f = 6, int g = 7) {
	}
}

class D : B {
	public void M() {}

	static int F1() { return 0; }
	static int F2() { return 0; }
	static int F3() { return 0; }
	static int F4() { return 0; }

	[System.Runtime.CompilerServices.CompilerGenerated]
	public D() : base(d: F1(), g: F2(), f: F3(), b: F4()) {
		M();
	}
}",
                @"function() {
	var $tmp1 = {sm_D}.F1();
	var $tmp2 = {sm_D}.F2();
	var $tmp3 = {sm_D}.F3();
	{inst_B}.call(this, 1, {sm_D}.F4(), 3, $tmp1, 5, $tmp3, $tmp2);
	this.M();
}", metadataImporter: new MockMetadataImporter {
                GetConstructorSemantics = c => ConstructorScriptSemantics.Unnamed()
            });
        }
        public void StaticConstructorBodyGetsAddedLastInTheStaticInitStatements()
        {
            var metadataImporter = new MockMetadataImporter {
                GetConstructorSemantics = ctor => { if (ctor.IsStatic)
                                                    {
                                                        throw new InvalidOperationException();
                                                    }
                                                    else
                                                    {
                                                        return(ConstructorScriptSemantics.Unnamed());
                                                    } }
            };

            Compile(new[] {
                @"class C {
    static int x = 0;
    static C() {
        int z = 2;
    }
    static int y = 1;
}"
            }, metadataImporter: metadataImporter);

            var cctor = FindClass("C").StaticInitStatements.Aggregate("", (s, st) => s + OutputFormatter.Format(st, true));

            cctor.Replace("\r\n", "\n").Should().Be(
                @"{sm_C}.$x = 0;
{sm_C}.$y = 1;
var $z = 2;
".Replace("\r\n", "\n"));
        }
        public void StaticFieldsWithoutInitializersAreInitializedToDefault()
        {
            var metadataImporter = new MockMetadataImporter {
                GetConstructorSemantics = ctor => { if (ctor.IsStatic)
                                                    {
                                                        throw new InvalidOperationException();
                                                    }
                                                    else
                                                    {
                                                        return(ConstructorScriptSemantics.Unnamed());
                                                    } }
            };

            Compile(new[] {
                @"class C<T> {
    static T x;
    static int y;
	static string z;
}"
            }, metadataImporter: metadataImporter);

            var cctor = FindClass("C").StaticInitStatements.Aggregate("", (s, st) => s + OutputFormatter.Format(st, true));

            cctor.Replace("\r\n", "\n").Should().Be(
                @"sm_$InstantiateGenericType({C}, ga_$T).$x = $Default(def_$T);
sm_$InstantiateGenericType({C}, ga_$T).$y = 0;
sm_$InstantiateGenericType({C}, ga_$T).$z = null;
".Replace("\r\n", "\n"));
        }
Beispiel #6
0
        public void ChainingToConstructorImplementedAsJsonFromUnnamedConstructorWorks()
        {
            AssertCorrect(
                @"class C {
	public int X;
	public string S;

	static int P { get; set; }
	public void M() {}

	[System.Runtime.CompilerServices.CompilerGenerated]
	public C() : this(P = 42, ""X"") {
		M();
	}

	public C(int x, string s) {
	}
}",
                @"function() {
	{sm_C}.set_P(42);
	$ShallowCopy({ $X: 42, $S: 'X' }, this);
	this.M();
}", metadataImporter: new MockMetadataImporter {
                GetConstructorSemantics = c => c.Parameters.Count == 0 ? ConstructorScriptSemantics.Unnamed() : ConstructorScriptSemantics.Json(c.Parameters.Select(p => c.DeclaringType.GetFields().Single(x => x.Name.Equals(p.Name, StringComparison.InvariantCultureIgnoreCase))))
            });
        }
Beispiel #7
0
        public void ChainingToNamedParamArrayConstructorThatExpandsArgumentsInNonExpandedFormWorks()
        {
            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}.x.apply(this, [4, 8].concat({sm_C1}.$args));
}", metadataImporter: new MockMetadataImporter {
                GetConstructorSemantics = c => c.Parameters.Count == 0 ? ConstructorScriptSemantics.Unnamed() : ConstructorScriptSemantics.Named("x", 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}.x.call(this, 4, 8, 59, 12, 4);
}", metadataImporter: new MockMetadataImporter {
                GetConstructorSemantics = c => c.Parameters.Count == 0 ? ConstructorScriptSemantics.Unnamed() : ConstructorScriptSemantics.Named("x", expandParams: true)
            });
        }
        public void InstanceManualEventsWithAddRemoveMethodsWithNoCodeAreCorrectlyImported()
        {
            var metadataImporter = new MockMetadataImporter {
                GetConstructorSemantics = c => ConstructorScriptSemantics.Unnamed(skipInInitializer: c.DeclaringType.IsKnownType(KnownTypeCode.Object)), GetEventSemantics = f => EventScriptSemantics.AddAndRemoveMethods(MethodScriptSemantics.NormalMethod("add_" + f.Name, generateCode: false), MethodScriptSemantics.NormalMethod("remove_" + f.Name, generateCode: false))
            };

            Compile(new[] { "class C { public event System.EventHandler SomeProp { add {} remove{} } }" }, metadataImporter: metadataImporter);
            FindClass("C").InstanceMethods.Should().BeEmpty();
            FindClass("C").UnnamedConstructor.Body.Statements.Should().BeEmpty();
        }
Beispiel #9
0
        public void InstanceAutoPropertiesWithGetSetMethodsWithNoCodeAreCorrectlyImported()
        {
            var metadataImporter = new MockMetadataImporter {
                GetConstructorSemantics = c => ConstructorScriptSemantics.Unnamed(skipInInitializer: c.DeclaringType.IsKnownType(KnownTypeCode.Object)),
                GetPropertySemantics    = p => PropertyScriptSemantics.GetAndSetMethods(MethodScriptSemantics.NormalMethod("get_" + p.Name, generateCode: false), MethodScriptSemantics.NormalMethod("set_" + p.Name, generateCode: false)),
            };

            Compile(new[] { "class C { public string SomeProp { get; set; } }" }, metadataImporter: metadataImporter);
            FindClass("C").InstanceMethods.Should().BeEmpty();
            FindInstanceFieldInitializer("C.$SomeProp").Should().NotBeNull();
        }
        public void StaticFieldsAreCorrectlyImported()
        {
            var metadataImporter = new MockMetadataImporter {
                GetConstructorSemantics = c => ConstructorScriptSemantics.Unnamed(skipInInitializer: c.DeclaringType.IsKnownType(KnownTypeCode.Object)), GetFieldSemantics = f => FieldScriptSemantics.Field("$SomeProp")
            };

            Compile(new[] { "class C { public static int SomeField; }" }, metadataImporter: metadataImporter);
            FindStaticFieldInitializer("C.$SomeProp").Should().NotBeNull();
            FindClass("C").UnnamedConstructor.Body.Statements.Should().BeEmpty();
            FindClass("C").InstanceMethods.Should().BeEmpty();
            FindClass("C").StaticMethods.Should().BeEmpty();
        }
Beispiel #11
0
        public void InstanceAutoPropertiesWithGetSetMethodsWithNoCodeAreCorrectlyImported()
        {
            var metadataImporter = new MockMetadataImporter {
                GetConstructorSemantics         = c => ConstructorScriptSemantics.Unnamed(skipInInitializer: c.DeclaringType.IsKnownType(KnownTypeCode.Object)),
                GetPropertySemantics            = p => PropertyScriptSemantics.GetAndSetMethods(MethodScriptSemantics.NormalMethod("get_" + p.Name, generateCode: false), MethodScriptSemantics.NormalMethod("set_" + p.Name, generateCode: false)),
                GetAutoPropertyBackingFieldName = p => { throw new InvalidOperationException("Shouldn't be called"); }
            };

            Compile(new[] { "class C { public string SomeProp { get; set; } }" }, metadataImporter: metadataImporter);
            FindClass("C").InstanceMethods.Should().BeEmpty();
            FindClass("C").UnnamedConstructor.Body.Statements.Should().BeEmpty();
        }
        public void FieldsThatAreNotUsableFromScriptAreNotImported()
        {
            var metadataImporter = new MockMetadataImporter {
                GetConstructorSemantics = c => ConstructorScriptSemantics.Unnamed(skipInInitializer: c.DeclaringType.IsKnownType(KnownTypeCode.Object)), GetFieldSemantics = f => FieldScriptSemantics.NotUsableFromScript()
            };

            Compile(new[] { "class C { public int SomeField; }" }, metadataImporter: metadataImporter);
            FindClass("C").UnnamedConstructor.Body.Statements.Should().BeEmpty();
            FindClass("C").StaticInitStatements.Should().BeEmpty();
            FindClass("C").InstanceMethods.Should().BeEmpty();
            FindClass("C").StaticMethods.Should().BeEmpty();
        }
        public void InstanceAutoEventsThatShouldNotGenerateBackingFieldsDoNotGenerateBackingFields()
        {
            var metadataImporter = new MockMetadataImporter {
                GetConstructorSemantics             = c => ConstructorScriptSemantics.Unnamed(skipInInitializer: c.DeclaringType.IsKnownType(KnownTypeCode.Object)),
                ShouldGenerateAutoEventBackingField = e => false,
            };

            Compile(new[] { "class C { public event System.EventHandler SomeProp; }" }, metadataImporter: metadataImporter);
            FindInstanceMethod("C.add_SomeProp").Should().NotBeNull();
            FindInstanceMethod("C.remove_SomeProp").Should().NotBeNull();
            FindClass("C").UnnamedConstructor.Body.Statements.Should().BeEmpty();
        }
        public void InvokingParamArrayConstructorThatExpandsArgumentsInExpandedFormWorks()
        {
            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 {inst_C1}(4, 8, 59, 12, 4);
", metadataImporter: new MockMetadataImporter {
                GetConstructorSemantics = c => ConstructorScriptSemantics.Unnamed(expandParams: true)
            });
        }
Beispiel #15
0
        public void InstanceAutoPropertiesThatShouldNotGenerateBackingFieldsDoNotGenerateBackingFields()
        {
            var metadataImporter = new MockMetadataImporter {
                GetConstructorSemantics = c => ConstructorScriptSemantics.Unnamed(skipInInitializer: c.DeclaringType.IsKnownType(KnownTypeCode.Object)),
                ShouldGenerateAutoPropertyBackingField = p => false,
            };

            Compile(new[] { "class C { public string SomeProp { get; set; } }" }, metadataImporter: metadataImporter);

            Assert.That(FindInstanceMethod("C.get_SomeProp"), Is.Not.Null);
            Assert.That(FindInstanceMethod("C.set_SomeProp"), Is.Not.Null);
            FindClass("C").UnnamedConstructor.Body.Statements.Should().BeEmpty();
            Assert.That(FindClass("C").StaticInitStatements, Is.Empty);
        }
        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();
        }
Beispiel #17
0
        public void ChainingToParamArrayConstructorThatDoesNotExpandArgumentsInNonExpandedFormWorks()
        {
            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() {
	{inst_C1}.x.call(this, 4, 8, [59, 12, 4]);
}", metadataImporter: new MockMetadataImporter {
                GetConstructorSemantics = c => c.Parameters.Count == 0 ? ConstructorScriptSemantics.Unnamed() : ConstructorScriptSemantics.Named("x")
            });
        }
Beispiel #18
0
        public void InvokingBaseStaticMethodConstructorFromAnotherTypeOfConstructorIsAnError()
        {
            var rpt = new MockErrorReporter(false);

            Compile(new[] {
                @"class B {
	public B() {}
}
class D : B {
	public D() {}
}"
            }, errorReporter: rpt, metadataImporter: new MockMetadataImporter {
                GetConstructorSemantics = c => c.DeclaringType.Name == "D" ? ConstructorScriptSemantics.Unnamed() : ConstructorScriptSemantics.StaticMethod("ctor")
            });
            Assert.That(rpt.AllMessagesText.Any(msg => msg.StartsWith("Error", StringComparison.InvariantCultureIgnoreCase) && msg.IndexOf("static method", StringComparison.InvariantCultureIgnoreCase) >= 0));
        }
Beispiel #19
0
        public void InvokingBaseConstructorMarkedAsNotUsableFromScriptIsAnError()
        {
            var rpt = new MockErrorReporter(false);

            Compile(new[] {
                @"class B {
	public B() {}
}
class D : B {
	public D() {}
}"
            }, errorReporter: rpt, metadataImporter: new MockMetadataImporter {
                GetConstructorSemantics = c => c.DeclaringType.Name == "D" ? ConstructorScriptSemantics.Unnamed() : ConstructorScriptSemantics.NotUsableFromScript()
            });
            Assert.That(rpt.AllMessagesText.Any(msg => msg.StartsWith("Error", StringComparison.InvariantCultureIgnoreCase) && msg.IndexOf("cannot be used", StringComparison.InvariantCultureIgnoreCase) >= 0));
        }
Beispiel #20
0
        public void ChainingToConstructorMarkedAsNotUsableFromScriptIsAnError()
        {
            var rpt = new MockErrorReporter(false);

            Compile(new[] {
                @"class C {
	public C() : this(0) {
	}
	public C(int x) {
	}
}"
            }, errorReporter: rpt, metadataImporter: new MockMetadataImporter {
                GetConstructorSemantics = c => c.Parameters.Count == 0 ? ConstructorScriptSemantics.Unnamed() : ConstructorScriptSemantics.NotUsableFromScript()
            });
            Assert.That(rpt.AllMessagesText.Any(msg => msg.StartsWith("Error", StringComparison.InvariantCultureIgnoreCase) && msg.IndexOf("cannot be used", StringComparison.InvariantCultureIgnoreCase) >= 0));
        }
Beispiel #21
0
        public void ChainingToStaticMethodConstructorFromAnotherTypeOfConstructorIsAnError()
        {
            var rpt = new MockErrorReporter(false);

            Compile(new[] {
                @"class C {
	public C() : this(0) {
	}
	public C(int x) {
	}
}"
            }, errorReporter: rpt, metadataImporter: new MockMetadataImporter {
                GetConstructorSemantics = c => c.Parameters.Count == 0 ? ConstructorScriptSemantics.Unnamed() : ConstructorScriptSemantics.StaticMethod("ctor")
            });
            Assert.That(rpt.AllMessagesText.Any(msg => msg.StartsWith("Error", StringComparison.InvariantCultureIgnoreCase) && msg.IndexOf("static method", StringComparison.InvariantCultureIgnoreCase) >= 0));
        }
 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;
 }
Beispiel #23
0
        public void ExpandedParamArrayIsFixedAtTheTopOfConstructors()
        {
            AssertCorrectConstructor(
                @"class B {}
class C : B {
	C(int a, string b, params object[] c) {
		int x = 0;
	}
}",
                @"function($a, $b) {
	var $c = Array.prototype.slice.call(arguments, 2);
	{sm_B}.call(this);
	var $x = 0;
}", "C", metadataImporter: new MockMetadataImporter {
                GetConstructorSemantics = c => ConstructorScriptSemantics.Unnamed(expandParams: c.DeclaringType.Name == "C")
            });
        }
Beispiel #24
0
        public void ChainingToStaticMethodConstructorFromAnotherTypeOfConstructorWorks()
        {
            AssertCorrect(
                @"class C {
	public static int P { get; set; }
	[System.Runtime.CompilerServices.CompilerGenerated]
	public C() : this(P = 0) {
	}
	public C(int x) {
	}
}",
                @"function() {
	{sm_C}.set_P(0);
	$ShallowCopy({sm_C}.ctor(0), this);
}", metadataImporter: new MockMetadataImporter {
                GetConstructorSemantics = c => c.Parameters.Count == 0 ? ConstructorScriptSemantics.Unnamed() : ConstructorScriptSemantics.StaticMethod("ctor")
            });
        }
Beispiel #25
0
        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"));
        }
Beispiel #26
0
        public void InvokingBaseStaticMethodConstructorFromAnotherTypeOfConstructorWorks()
        {
            AssertCorrect(
                @"class B {
	public B(int x) {}
}
class D : B {
	public static int P { get; set; }
	[System.Runtime.CompilerServices.CompilerGenerated]
	public D() : base(P = 1) {}
}",
                @"function() {
	{sm_D}.set_P(1);
	$ShallowCopy({sm_B}.ctor(1), this);
}", metadataImporter: new MockMetadataImporter {
                GetConstructorSemantics = c => c.DeclaringType.Name == "D" ? ConstructorScriptSemantics.Unnamed() : ConstructorScriptSemantics.StaticMethod("ctor")
            });
        }
Beispiel #27
0
        public void InvokingBaseConstructorMarkedAsSkipInInitializerDoesNothing()
        {
            AssertCorrect(
                @"class B {
}
class D : B {
	public void M() {}

	[System.Runtime.CompilerServices.CompilerGenerated]
	public D() : base() {
		this.M();
	}
}",
                @"function() {
	this.M();
}", metadataImporter: new MockMetadataImporter {
                GetConstructorSemantics = c => ConstructorScriptSemantics.Unnamed(skipInInitializer: c.DeclaringType.Name == "B")
            });
        }
        public void InvokingUnnamedParamArrayConstructorThatExpandsArgumentsInNonExpandedFormWorks()
        {
            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}, [4, 8].concat($args));
	var $c2 = new {sm_C}(4, 8, 59, 12, 4);
", metadataImporter: new MockMetadataImporter {
                GetConstructorSemantics = c => ConstructorScriptSemantics.Unnamed(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}, [4].concat($args));
", metadataImporter: new MockMetadataImporter {
                GetConstructorSemantics = c => ConstructorScriptSemantics.Unnamed(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}, $args);
", metadataImporter: new MockMetadataImporter {
                GetConstructorSemantics = c => ConstructorScriptSemantics.Unnamed(expandParams: true)
            });
        }
        public void CreatingObjectWithDynamicArgumentWorksWhenAllCandidatesAreUnnamedConstructors()
        {
            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}($d);
", metadataImporter: new MockMetadataImporter {
                GetConstructorSemantics = c => ConstructorScriptSemantics.Unnamed(generateCode: false)
            });
        }
        public void InvokingParamArrayConstructorThatExpandsArgumentsInNonExpandedFormIsAnError()
        {
            var er = new MockErrorReporter(false);

            Compile(new[] {
                @"class C1 {
	public C1(int x, int y, params int[] args) {}
	public void M() {
	// BEGIN
	var c = new C1(4, 8, new[] { 59, 12, 4 });
	// END
	}
}"
            }, metadataImporter: new MockMetadataImporter {
                GetConstructorSemantics = c => ConstructorScriptSemantics.Unnamed(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"));
        }