public static Tuple<string, MockErrorReporter> Compile(string source, bool expectErrors = false) { var sourceFile = new MockSourceFile("file.cs", source); var er = new MockErrorReporter(!expectErrors); var n = new Namer(); var references = new[] { Files.Mscorlib }; var compilation = PreparedCompilation.CreateCompilation("x", new[] { sourceFile }, references, null);; var s = new AttributeStore(compilation.Compilation, er); var md = new MetadataImporter(er, compilation.Compilation, s, new CompilerOptions()); var rtl = new RuntimeLibrary(md, er, compilation.Compilation, n, s); var l = new MockLinker(); md.Prepare(compilation.Compilation.GetAllTypeDefinitions()); var compiler = new Compiler(md, n, rtl, er); var compiledTypes = compiler.Compile(compilation).ToList(); if (expectErrors) { Assert.That(er.AllMessages, Is.Not.Empty, "Compile should have generated errors"); return Tuple.Create((string)null, er); } Assert.That(er.AllMessages, Is.Empty, "Compile should not generate errors"); var js = new OOPEmulatorInvoker(new OOPEmulator(compilation.Compilation, md, rtl, n, l, s, er), md, er).Process(compiledTypes, null); js = new Linker(md, n, s, compilation.Compilation).Process(js); string script = OutputFormatter.Format(js, allowIntermediates: false); return Tuple.Create(script, er); }
protected void Prepare(string source, bool minimizeNames = true, bool expectErrors = false) { IProjectContent project = new CSharpProjectContent(); var parser = new CSharpParser(); using (var rdr = new StringReader(source)) { var pf = new CSharpUnresolvedFile { FileName = "File.cs" }; var syntaxTree = parser.Parse(rdr, pf.FileName); syntaxTree.AcceptVisitor(new TypeSystemConvertVisitor(pf)); project = project.AddOrUpdateFiles(pf); } project = project.AddAssemblyReferences(new[] { Files.Mscorlib }); _errorReporter = new MockErrorReporter(!expectErrors); var compilation = project.CreateCompilation(); var s = new AttributeStore(compilation, _errorReporter); RunAutomaticMetadataAttributeAppliers(s, compilation); s.RunAttributeCode(); Metadata = new MetadataImporter(_errorReporter, compilation, s, new CompilerOptions { MinimizeScript = minimizeNames }); Metadata.Prepare(compilation.GetAllTypeDefinitions()); AllErrors = _errorReporter.AllMessages.ToList().AsReadOnly(); AllErrorTexts = _errorReporter.AllMessages.Select(m => m.FormattedMessage).ToList().AsReadOnly(); if (expectErrors) { Assert.That(AllErrorTexts, Is.Not.Empty, "Compile should have generated errors"); } else { Assert.That(AllErrorTexts, Is.Empty, "Compile should not generate errors"); } AllTypes = compilation.MainAssembly.TopLevelTypeDefinitions.SelectMany(SelfAndNested).ToDictionary(t => t.ReflectionName); }
public void ConstructorsAreReportedAsJsonConstructors() { var compilation = new SimpleCompilation(new CSharpProjectContent()); var er = new MockErrorReporter(true); var md = new MetadataImporter(er, compilation, new CompilerOptions()); Assert.That(er.AllMessages, Is.Empty, "Prepare should not generate errors"); var t = CreateType(compilation); var c = md.GetConstructorSemantics(DefaultResolvedMethod.GetDummyConstructor(compilation, t)); Assert.That(c.Type, Is.EqualTo(ConstructorScriptSemantics.ImplType.Json)); }
public void ReflectionOnUnusablePropertyIsAnError() { var er = new MockErrorReporter(); EmulateType(@" using System.Runtime.CompilerServices; public class C1 { [NonScriptable, Reflectable] public int P { get; set; } } ", "C1", errorReporter: er); Assert.That(er.AllMessages.Count, Is.EqualTo(1)); Assert.That(er.AllMessages.Any(m => m.Severity == MessageSeverity.Error && m.Code == 7201 && m.FormattedMessage.Contains("C1.P") && m.FormattedMessage.Contains("property") && m.FormattedMessage.Contains("reflection"))); }
public void ReflectionOnUnusableFieldIsAnError() { var er = new MockErrorReporter(); Process(@" using System.Runtime.CompilerServices; public class C1 { [NonScriptable, Reflectable] public int F = 0; } ", errorReporter: er); Assert.That(er.AllMessages.Count, Is.EqualTo(1)); Assert.That(er.AllMessages.Any(m => m.Severity == MessageSeverity.Error && m.Code == 7201 && m.FormattedMessage.Contains("C1.F") && m.FormattedMessage.Contains("field") && m.FormattedMessage.Contains("reflection"))); }
public void ReflectionOnInlineConstantFieldIsAnError() { var er = new MockErrorReporter(); EmulateType(@" using System.Runtime.CompilerServices; public class C1 { [InlineConstant, Reflectable] public const int F = 0; } ", "C1", errorReporter: er); Assert.That(er.AllMessages.Count, Is.EqualTo(1)); Assert.That(er.AllMessages.Any(m => m.Severity == MessageSeverity.Error && m.Code == 7201 && m.FormattedMessage.Contains("C1.F") && m.FormattedMessage.Contains("field") && m.FormattedMessage.Contains("reflection"))); }
public void ReflectionOnNativeOperatorMethodIsAnError() { var er = new MockErrorReporter(); EmulateType(@" using System.Runtime.CompilerServices; public class C1 { [IntrinsicOperator, Reflectable] public static C1 operator *(C1 x, C1 y) { return null; } } ", "C1", errorReporter: er); Assert.That(er.AllMessages.Count, Is.EqualTo(1)); Assert.That(er.AllMessages.Any(m => m.Severity == MessageSeverity.Error && m.Code == 7201 && m.FormattedMessage.Contains("C1.op_Multiply") && m.FormattedMessage.Contains("method") && m.FormattedMessage.Contains("reflection"))); }
public void TransparentIdentiferIsValidJavascriptIdentifierStartingWithDollar() { var compilation = new SimpleCompilation(new CSharpProjectContent()); var er = new MockErrorReporter(true); var md = new MetadataImporter(er, compilation, new CompilerOptions()); Assert.That(er.AllMessages, Is.Empty, "Prepare should not generate errors"); var t = CreateType(compilation, new[] { "<>Identifier" }); var c = md.GetPropertySemantics(t.GetProperties().Single()); Assert.That(c.Type, Is.EqualTo(PropertyScriptSemantics.ImplType.Field)); Assert.That(c.FieldName, Is.EqualTo("$Identifier")); }
protected Tuple<ICompilation, List<JsType>> Compile(string source, IEnumerable<IAssemblyResource> resources = null) { var errorReporter = new MockErrorReporter(true); var sourceFile = new MockSourceFile("file.cs", source); var n = new Namer(); var references = new[] { Files.Mscorlib }; var compilation = PreparedCompilation.CreateCompilation("x", new[] { sourceFile }, references, null, resources); var md = new MetadataImporter(errorReporter, compilation.Compilation, new CompilerOptions()); var rtl = new RuntimeLibrary(md, errorReporter, compilation.Compilation, n); md.Prepare(compilation.Compilation.GetAllTypeDefinitions()); var compiler = new Compiler(md, n, rtl, errorReporter); var compiledTypes = compiler.Compile(compilation).ToList(); return Tuple.Create(compilation.Compilation, compiledTypes); }
public void AnonymousTypePropertyNamesAreNotMinimized() { var compilation = new SimpleCompilation(new CSharpProjectContent()); var er = new MockErrorReporter(true); var md = new MetadataImporter(er, compilation, new CompilerOptions()); Assert.That(er.AllMessages, Is.Empty, "Prepare should not generate errors"); var t = CreateType(compilation); var p1 = md.GetPropertySemantics(t.GetProperties().Single(p => p.Name == "prop1")); Assert.That(p1.Type, Is.EqualTo(PropertyScriptSemantics.ImplType.Field)); Assert.That(p1.FieldName, Is.EqualTo("prop1")); var p2 = md.GetPropertySemantics(t.GetProperties().Single(p => p.Name == "Prop2")); Assert.That(p2.Type, Is.EqualTo(PropertyScriptSemantics.ImplType.Field)); Assert.That(p2.FieldName, Is.EqualTo("Prop2")); }
public void PropertiesAreImplementedAsFieldsWithTheSameName() { var compilation = new SimpleCompilation(new CSharpProjectContent()); var er = new MockErrorReporter(true); var s = new AttributeStore(compilation, er); var md = new MetadataImporter(er, compilation, s, new CompilerOptions()); Assert.That(er.AllMessages, Is.Empty, "Prepare should not generate errors"); var t = CreateType(compilation); var p1 = md.GetPropertySemantics(t.GetProperties().Single(p => p.Name == "prop1")); Assert.That(p1.Type, Is.EqualTo(PropertyScriptSemantics.ImplType.Field)); Assert.That(p1.FieldName, Is.EqualTo("prop1")); var p2 = md.GetPropertySemantics(t.GetProperties().Single(p => p.Name == "Prop2")); Assert.That(p2.Type, Is.EqualTo(PropertyScriptSemantics.ImplType.Field)); Assert.That(p2.FieldName, Is.EqualTo("Prop2")); }
private void Prepare(string source, Action preparer) { IProjectContent project = new CSharpProjectContent(); var parser = new CSharpParser(); using (var rdr = new StringReader(source)) { var pf = new CSharpUnresolvedFile("File.cs"); var syntaxTree = parser.Parse(rdr, pf.FileName); syntaxTree.AcceptVisitor(new TypeSystemConvertVisitor(pf)); project = project.AddOrUpdateFiles(pf); } project = project.AddAssemblyReferences(new[] { Files.Mscorlib }); var compilation = project.CreateCompilation(); AllTypes = compilation.MainAssembly.TopLevelTypeDefinitions.SelectMany(SelfAndNested).ToDictionary(t => t.ReflectionName); var er = new MockErrorReporter(true); Metadata = new MetadataImporter(er, compilation, new CompilerOptions()); preparer(); Metadata.Prepare(compilation.GetAllTypeDefinitions()); Assert.That(er.AllMessages, Is.Empty, "Should not generate errrors"); }
public void InstanceMethodWithScriptSkipAttributeCannotHaveParameters() { var er = new MockErrorReporter(false); Prepare(@"using System.Runtime.CompilerServices; public class C1 { [ScriptSkip] void M(int i); }", expectErrors: true); Assert.That(AllErrorTexts, Has.Count.EqualTo(1)); Assert.That(AllErrorTexts[0].Contains("C1.M") && AllErrorTexts[0].Contains("ScriptSkipAttribute") && AllErrorTexts[0].Contains("no parameters")); er = new MockErrorReporter(false); Prepare(@"using System.Runtime.CompilerServices; public class C1 { [ScriptSkip] void M(int i, int j); }", expectErrors: true); Assert.That(AllErrorTexts, Has.Count.EqualTo(1)); Assert.That(AllErrorTexts[0].Contains("C1.M") && AllErrorTexts[0].Contains("ScriptSkipAttribute") && AllErrorTexts[0].Contains("no parameters")); }
public void StaticMethodWithScriptSkipAttributeMustHaveExactlyOneParameter() { var er = new MockErrorReporter(false); Prepare(@"using System.Runtime.CompilerServices; public class C1 { [ScriptSkip] static void M(); }", expectErrors: true); Assert.That(AllErrorTexts, Has.Count.EqualTo(1)); Assert.That(AllErrorTexts[0].Contains("C1.M") && AllErrorTexts[0].Contains("ScriptSkipAttribute") && AllErrorTexts[0].Contains("one parameter")); er = new MockErrorReporter(false); Prepare(@"using System.Runtime.CompilerServices; public class C1 { [ScriptSkip] static void M(int i, int j); }", expectErrors: true); Assert.That(AllErrorTexts, Has.Count.EqualTo(1)); Assert.That(AllErrorTexts[0].Contains("C1.M") && AllErrorTexts[0].Contains("ScriptSkipAttribute") && AllErrorTexts[0].Contains("one parameter")); }
public void ScriptSkipAttributeCannotBeSpecifiedOnMethodThatOverridesABaseMember() { var er = new MockErrorReporter(false); Prepare(@"using System.Runtime.CompilerServices; public class B { public virtual void M() {} } public class D : B { [ScriptSkip] public sealed override void M() {} }", expectErrors: true); Assert.That(AllErrorTexts, Has.Count.EqualTo(1)); Assert.That(AllErrorTexts[0].Contains("D.M") && AllErrorTexts[0].Contains("ScriptSkipAttribute") && AllErrorTexts[0].Contains("overrides")); }
public void ScriptSkipAttributeCannotBeSpecifiedOnMethodImplementingInterfaceMember() { var er = new MockErrorReporter(false); Prepare(@"using System.Runtime.CompilerServices; public interface I { void M(); } public class C : I { [ScriptSkip] public void M() {} }", expectErrors: true); Assert.That(AllErrorTexts, Has.Count.EqualTo(1)); Assert.That(AllErrorTexts[0].Contains("C.M") && AllErrorTexts[0].Contains("ScriptSkipAttribute") && AllErrorTexts[0].Contains("implements")); }
public void ScriptSkipAttributeCannotBeSpecifiedOnVirtualOrAbstractMethod() { var er = new MockErrorReporter(false); Prepare(@"using System.Runtime.CompilerServices; public class C1 { [ScriptSkip] public virtual void M() {} }", expectErrors: true); Assert.That(AllErrorTexts, Has.Count.EqualTo(1)); Assert.That(AllErrorTexts[0].Contains("C1.M") && AllErrorTexts[0].Contains("ScriptSkipAttribute") && AllErrorTexts[0].Contains("overridable")); er = new MockErrorReporter(false); Prepare(@"using System.Runtime.CompilerServices; public class C1 { [ScriptSkip] public abstract void M() {} }", expectErrors: true); Assert.That(AllErrorTexts, Has.Count.EqualTo(1)); Assert.That(AllErrorTexts[0].Contains("C1.M") && AllErrorTexts[0].Contains("ScriptSkipAttribute") && AllErrorTexts[0].Contains("overridable")); }
public void SyntaxErrorInSerializableTypeCheckCodeIsAnError() { var er = new MockErrorReporter(); EmulateType(@" [System.Serializable(TypeCheckCode = ""{{this} == 1""), System.Runtime.CompilerServices.IncludeGenericArguments(false)] public class C1<T> {} ", "C1", errorReporter: er); Assert.That(er.AllMessages.Count, Is.EqualTo(1)); Assert.That(er.AllMessages.Any(m => m.Severity == MessageSeverity.Error && m.Code == 7157 && m.FormattedMessage.Contains("C1") && m.FormattedMessage.Contains("syntax error"))); }
public void ScriptNamespaceAttributeArgumentMustBeAValidJSQualifiedIdentifierOrBeEmpty() { var er = new MockErrorReporter(false); Prepare(@"using System.Runtime.CompilerServices; [ScriptNamespace(""a b"")] public class C1 {}", expectErrors: true); Assert.That(AllErrorTexts, Has.Count.EqualTo(1)); Assert.That(AllErrorTexts[0].Contains("C1") && AllErrorTexts[0].Contains("ScriptNamespace") && AllErrorTexts[0].Contains("must be a valid JavaScript qualified identifier")); er = new MockErrorReporter(false); Prepare(@"using System.Runtime.CompilerServices; [ScriptNamespace("" "")] public class C1 {}", expectErrors: true); Assert.That(AllErrorTexts, Has.Count.EqualTo(1)); Assert.That(AllErrorTexts[0].Contains("C1") && AllErrorTexts[0].Contains("ScriptNamespace") && AllErrorTexts[0].Contains("must be a valid JavaScript qualified identifier")); }
public void ReferencingNonExistentTypeInSerializableTypeCheckCodeIsAnError() { var er = new MockErrorReporter(); Process(@" [System.Serializable(TypeCheckCode = ""{this} == {$Some.Nonexistent.Type}""), System.Runtime.CompilerServices.IncludeGenericArguments(false)] public class C1<T> {} ", errorReporter: er); Assert.That(er.AllMessages.Count, Is.EqualTo(1)); Assert.That(er.AllMessages.Any(m => m.Severity == MessageSeverity.Error && m.Code == 7157 && m.FormattedMessage.Contains("C1") && m.FormattedMessage.Contains("Some.Nonexistent.Type"))); }
public void AnErrorIsIssuedIfTheMainMethodIsNotImplementedAsANormalMethod() { var er = new MockErrorReporter(); Process( @"public class MyClass { [System.Runtime.CompilerServices.InlineCode(""X"")] public static void Main() {} }", entryPoint: "MyClass.Main", errorReporter: er); Assert.That(er.AllMessages, Has.Count.EqualTo(1)); Assert.That(er.AllMessages.Any(m => m.Code == 7801 && (string)m.Args[0] == "MyClass.Main")); }
public void AnErrorIsIssuedIfTheMainMethodHasParameters() { var er = new MockErrorReporter(); Process( @"public class MyClass { public static void Main(string[] args) {} }", entryPoint: "MyClass.Main", errorReporter: er); Assert.That(er.AllMessages, Has.Count.EqualTo(1)); Assert.That(er.AllMessages.Any(m => m.Code == 7800 && (string)m.Args[0] == "MyClass.Main")); }
public void ReflectionOnEventWithUnusableRemoverIsAnError() { var er = new MockErrorReporter(); EmulateType(@" using System.Runtime.CompilerServices; public class C1 { [Reflectable] public event System.Action E { add {} [NonScriptable] remove {} } } ", "C1", errorReporter: er); Assert.That(er.AllMessages.Count, Is.EqualTo(1)); Assert.That(er.AllMessages.Any(m => m.Severity == MessageSeverity.Error && m.Code == 7202 && m.FormattedMessage.Contains("C1.E") && m.FormattedMessage.Contains("event") && m.FormattedMessage.Contains("remove accessor") && m.FormattedMessage.Contains("reflection"))); }
public void ScriptSkipAttributeCannotBeSpecifiedOnInterfaceMethod() { var er = new MockErrorReporter(false); Prepare(@"using System.Runtime.CompilerServices; public interface I1 { [ScriptSkip] void M(); }", expectErrors: true); Assert.That(AllErrorTexts, Has.Count.EqualTo(1)); Assert.That(AllErrorTexts[0].Contains("I1.M") && AllErrorTexts[0].Contains("ScriptSkipAttribute") && AllErrorTexts[0].Contains("interface method")); }
public void UsingUnavailableTypeArgumentInInheritanceListIsAnError() { var er = new MockErrorReporter(); EmulateType(@" using System.Runtime.CompilerServices; public interface I<T> {} [IncludeGenericArguments(false)] public class D1<T> : I<T> {} ", "D1", errorReporter: er); Assert.That(er.AllMessages.Count, Is.EqualTo(1)); Assert.That(er.AllMessages.Any(m => m.Severity == MessageSeverity.Error && m.Code == 7536 && m.FormattedMessage.Contains("IncludeGenericArguments") && m.FormattedMessage.Contains("type D1"))); }
public void UsingUnavailableTypeParameterInSerializableTypeCheckCodeIsAnError() { var er = new MockErrorReporter(); Process(@" [System.Serializable(TypeCheckCode = ""{this} == {T}""), System.Runtime.CompilerServices.IncludeGenericArguments(false)] public class C1<T> {} ", errorReporter: er); Assert.That(er.AllMessages.Count, Is.EqualTo(1)); Assert.That(er.AllMessages.Any(m => m.Severity == MessageSeverity.Error && m.Code == 7536 && m.FormattedMessage.Contains("IncludeGenericArguments") && m.FormattedMessage.Contains("type C1"))); }
public void EmptyScriptNameCannotBeSpecifiedOnStaticMethod() { var er = new MockErrorReporter(false); Prepare(@"using System.Runtime.CompilerServices; public class C1 { [ScriptName("""")] public static void M() {} }", expectErrors: true); Assert.That(AllErrorTexts, Has.Count.EqualTo(1)); Assert.That(AllErrorTexts[0].Contains("C1.M") && AllErrorTexts[0].Contains("ScriptName") && AllErrorTexts[0].Contains("static") && AllErrorTexts[0].Contains("empty name")); }