Пример #1
0
        public void ChainingToConstructorImplementedAsInlineCodeFromUnnamedConstructorWprks()
        {
            AssertCorrect(
                @"class C {
	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(_(42)._('X'), this);
	this.M();
}", metadataImporter: new MockMetadataImporter {
                GetConstructorSemantics = c => c.Parameters.Count == 0 ? ConstructorScriptSemantics.Unnamed() : ConstructorScriptSemantics.InlineCode("_({x})._({s})")
            });
        }
Пример #2
0
        public void ChainingToInlineCodeConstructorInNonExpandedFormUsesNonExpandedPattern()
        {
            AssertCorrect(
                @"class C {
	public static int[] a = null;
	public C(params int[] args) {}
	[System.Runtime.CompilerServices.CompilerGenerated]
	public C() : this(a) {
	}
}",
                @"function() {
	$ShallowCopy(_2({sm_C}.$a), this);
}", metadataImporter: new MockMetadataImporter {
                GetConstructorSemantics = c => c.Parameters.Count == 1 ? ConstructorScriptSemantics.InlineCode("_({*args})", nonExpandedFormLiteralCode: "_2({args})") : ConstructorScriptSemantics.Unnamed()
            });
        }
Пример #3
0
        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();
	{sm_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()
            });
        }
Пример #4
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.AllMessages.Any(msg => msg.Severity == MessageSeverity.Error && msg.FormattedMessage.IndexOf("cannot be used", StringComparison.InvariantCultureIgnoreCase) >= 0));
        }
Пример #5
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));
        }
Пример #6
0
        public void ChainingToJsonConstructorFromStaticMethodConstructorWorks()
        {
            AssertCorrect(
                @"class C {
	static int F1() { return 0; }
	static int F2() { return 0; }
	static int F3() { return 0; }
	static int F4() { return 0; }

	public int A, B, C, D, E, F, G;

	public void M() {}

	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 $this = { $D: {sm_C}.F1(), $G: {sm_C}.F2(), $F: {sm_C}.F3(), $B: {sm_C}.F4(), $A: 1, $C: 3, $E: 5 };
	$this.M();
	return $this;
}", metadataImporter: new MockMetadataImporter {
                GetConstructorSemantics = c => c.Parameters.Count == 0 ? ConstructorScriptSemantics.StaticMethod("X") : ConstructorScriptSemantics.Json(c.Parameters.Select(p => c.DeclaringType.GetFields().Single(x => x.Name.Equals(p.Name, StringComparison.InvariantCultureIgnoreCase))))
            });
        }
Пример #7
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")
            });
        }
Пример #8
0
        public JsFunctionDefinitionExpression CompileConstructor(ConstructorDeclaration ctor, IMethod constructor, List <JsStatement> instanceInitStatements, ConstructorScriptSemantics impl)
        {
            var region = _errorReporter.Region = ctor != null?ctor.GetRegion() : constructor.DeclaringTypeDefinition.Region;

            try {
                CreateCompilationContext(ctor, constructor, constructor.DeclaringTypeDefinition, (impl.Type == ConstructorScriptSemantics.ImplType.StaticMethod ? _namer.ThisAlias : null));
                IList <JsStatement> body = new List <JsStatement>();
                body.AddRange(PrepareParameters(constructor.Parameters, variables, expandParams: impl.ExpandParams, staticMethodWithThisAsFirstArgument: false));

                if (impl.Type == ConstructorScriptSemantics.ImplType.StaticMethod)
                {
                    if (ctor != null && !ctor.Initializer.IsNull)
                    {
                        body.AddRange(_statementCompiler.CompileConstructorInitializer(ctor.Initializer, true));
                    }
                    else
                    {
                        body.AddRange(_statementCompiler.CompileImplicitBaseConstructorCall(constructor.DeclaringTypeDefinition, true));
                    }
                }

                if (ctor == null || ctor.Initializer.IsNull || ctor.Initializer.ConstructorInitializerType != ConstructorInitializerType.This)
                {
                    if (impl.Type == ConstructorScriptSemantics.ImplType.StaticMethod)
                    {
                        // The compiler one step up has created the statements as "this.a = b;", but we need to replace that with "$this.a = b;" (or whatever name the this alias has).
                        var replacer = new ThisReplacer(JsExpression.Identifier(_namer.ThisAlias));
                        instanceInitStatements = instanceInitStatements.Select(s => replacer.VisitStatement(s, null)).ToList();
                    }
                    body.AddRange(instanceInitStatements);                      // Don't initialize fields when we are chaining, but do it when we 1) compile the default constructor, 2) don't have an initializer, or 3) when the initializer is not this(...).
                }

                if (impl.Type != ConstructorScriptSemantics.ImplType.StaticMethod)
                {
                    if (ctor != null && !ctor.Initializer.IsNull)
                    {
                        body.AddRange(_statementCompiler.CompileConstructorInitializer(ctor.Initializer, false));
                    }
                    else
                    {
                        body.AddRange(_statementCompiler.CompileImplicitBaseConstructorCall(constructor.DeclaringTypeDefinition, false));
                    }
                }

                if (ctor != null)
                {
                    body.AddRange(_statementCompiler.Compile(ctor.Body).Statements);
                }

                if (impl.Type == ConstructorScriptSemantics.ImplType.StaticMethod)
                {
                    if (body.Count == 0 || !(body[body.Count - 1] is JsReturnStatement))
                    {
                        body.Add(JsStatement.Return());
                    }
                    body = StaticMethodConstructorReturnPatcher.Process(body, _namer.ThisAlias).AsReadOnly();
                }

                var compiled = JsExpression.FunctionDefinition(constructor.Parameters.Where((p, i) => i != constructor.Parameters.Count - 1 || !impl.ExpandParams).Select(p => variables[p].Name), JsStatement.Block(body));
                return(_statementCompiler.StateMachineRewriteNormalMethod(compiled));
            }
            catch (Exception ex) {
                _errorReporter.Region = region;
                _errorReporter.InternalError(ex);
                return(JsExpression.FunctionDefinition(new string[0], JsStatement.EmptyBlock));
            }
        }
Пример #9
0
 public JsFunctionDefinitionExpression CompileDefaultConstructor(IMethod constructor, List <JsStatement> instanceInitStatements, ConstructorScriptSemantics impl)
 {
     return(CompileConstructor(null, constructor, instanceInitStatements, impl));
 }
        public void JsonConstructorWithParameterToMemberMapWorks()
        {
            AssertCorrect(
                @"class C1 { public C1(int a, int b) {} public int a2, int b2; }
public int F1() { return 0; }
public int F2() { return 0; }
public int P { get; set; }

public void M() {
	// BEGIN
	var c = new C1(F1(), P = F2());
	// END
}",
                @"	var $tmp2 = this.F1();
	var $tmp1 = this.F2();
	this.set_P($tmp1);
	var $c = { $a2: $tmp2, $b2: $tmp1 };
", metadataImporter: new MockMetadataImporter {
                GetConstructorSemantics = c => c.DeclaringType.Name == "C1" ? ConstructorScriptSemantics.Json(new[] { c.DeclaringType.GetFields().Single(f => f.Name == "a2"), c.DeclaringType.GetFields().Single(f => f.Name == "b2") }) : ConstructorScriptSemantics.Unnamed()
            });
        }
        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));
        }
Пример #12
0
 public virtual void SetConstructorSemantics(IMethod method, ConstructorScriptSemantics semantics)
 {
     _prev.SetConstructorSemantics(method, semantics);
 }
Пример #13
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"));
        }
Пример #14
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));
        }
Пример #15
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))))
            });
        }
Пример #16
0
 void IMetadataImporter.SetConstructorSemantics(IMethod method, ConstructorScriptSemantics semantics)
 {
 }
Пример #17
0
        public void ChainingToConstructorImplementedAsInlineCodeFromStaticMethodConstructorWorks()
        {
            AssertCorrect(
                @"class C {
	public void M() {}

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

	public C(int x, string s) {
	}
}",
                @"function() {
	var $this = __Literal_(0)._X__;
	$this.M();
	return $this;
}", metadataImporter: new MockMetadataImporter {
                GetConstructorSemantics = c => c.Parameters.Count == 0 ? ConstructorScriptSemantics.StaticMethod("M") : ConstructorScriptSemantics.InlineCode("__Literal_({x})._{@s}__")
            });
        }
Пример #18
0
        public void ChainingToNamedParamArrayConstructorThatDoesNotExpandArgumentsInExpandedFormWorks()
        {
            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}.x.call(this, 4, 8, [59, 12, 4]);
}", metadataImporter: new MockMetadataImporter {
                GetConstructorSemantics = c => c.Parameters.Count == 0 ? ConstructorScriptSemantics.Unnamed() : ConstructorScriptSemantics.Named("x")
            });
        }
Пример #19
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")
            });
        }
Пример #20
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)
            });
        }
Пример #21
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.AllMessages.Any(msg => msg.Severity == MessageSeverity.Error && msg.FormattedMessage.IndexOf("cannot be used", StringComparison.InvariantCultureIgnoreCase) >= 0));
        }
Пример #22
0
        public void ChainingToInlineCodeConstructorThatUsesExpandedParameterPlaceholderInNonExpandedFormIsAnError()
        {
            var er = new MockErrorReporter(false);

            Compile(new[] {
                @"class C1 {
	public static int[] a = null;

	public C1(params int[] args) {}

	[System.Runtime.CompilerServices.CompilerGenerated]
	public C1() : this(a) {
	}
}"
            }, metadataImporter: new MockMetadataImporter {
                GetConstructorSemantics = c => c.Parameters.Count == 1 ? ConstructorScriptSemantics.InlineCode("_({*args})") : ConstructorScriptSemantics.Unnamed()
            }, errorReporter: er);
            Assert.That(er.AllMessages.Any(msg => msg.Severity == MessageSeverity.Error && msg.FormattedMessage.Contains("constructor") && msg.FormattedMessage.Contains("C1") && msg.FormattedMessage.Contains("params parameter expanded")));
        }
Пример #23
0
        public void ChainingToAnonymousConstructorFromStaticMethodConstructorWorks()
        {
            AssertCorrect(
                @"class C {
	static int F1() { return 0; }
	static int F2() { return 0; }
	static int F3() { return 0; }
	static int F4() { return 0; }

	public void M() {}

	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();
	var $this = new {sm_C}(1, {sm_C}.F4(), 3, $tmp1, 5, $tmp3, $tmp2);
	$this.M();
	return $this;
}", metadataImporter: new MockMetadataImporter {
                GetConstructorSemantics = c => c.DeclaringType.Name == "C" && c.Parameters.Count == 0 ? ConstructorScriptSemantics.StaticMethod("ctor") : ConstructorScriptSemantics.Unnamed()
            });
        }
Пример #24
0
        public void ChainingToConstructorImplementedAsJsonFromUnnamedConstructorIsAnError()
        {
            var rpt = new MockErrorReporter(false);

            Compile(new[] {
                @"class C {
	public void M() {}

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

	public C(int x, string s) {
	}
}"
            }, errorReporter: rpt, metadataImporter: new MockMetadataImporter {
                GetConstructorSemantics = c => c.Parameters.Count == 0 ? ConstructorScriptSemantics.Unnamed() : ConstructorScriptSemantics.Json(new IMember[0])
            });
            Assert.That(rpt.AllMessagesText.Any(msg => msg.StartsWith("Error", StringComparison.InvariantCultureIgnoreCase) && msg.IndexOf("not supported", StringComparison.InvariantCultureIgnoreCase) >= 0));
        }