public void CyclesInDependencyGraphAreHandledGracefully() { var asm = Common.CreateMockAssembly(); var a = Common.CreateMockTypeDefinition("A1", asm); var b = Common.CreateMockTypeDefinition("B1", asm); var c = Common.CreateMockTypeDefinition("C1", asm); var d = Common.CreateMockTypeDefinition("D1", asm); var deps = new Dictionary <ITypeDefinition, IEnumerable <ITypeDefinition> > { { a, new[] { b } }, { b, new[] { c } }, { c, new[] { a } }, { d, new ITypeDefinition[0] }, }; var er = new MockErrorReporter(); var invoker = new OOPEmulatorInvoker(new MockOOPEmulator { EmulateType = t => new TypeOOPEmulation(new[] { new TypeOOPEmulationPhase(deps[t.CSharpTypeDefinition], new[] { (JsStatement)JsExpression.Null }) }) }, new MockMetadataImporter(), er); invoker.Process(new[] { new JsClass(a), new JsClass(b), new JsClass(c), new JsClass(d) }, null); Assert.That(er.AllMessages, Has.Count.EqualTo(1)); Assert.That(er.AllMessages.Any(m => m.Code == 7802 && ((string)m.Args[0]).Contains("A1") && ((string)m.Args[0]).Contains("B1") && ((string)m.Args[0]).Contains("C1"))); }
private void AssertCorrect(IList <JsType> types, string expected, IOOPEmulator emulator, IMethod entryPoint) { var invoker = new OOPEmulatorInvoker(emulator, new MockMetadataImporter(), new MockErrorReporter()); var result = invoker.Process(types, entryPoint); var actual = OutputFormatter.Format(result, allowIntermediates: true).Replace("\r\n", "\n"); Assert.That(actual, Is.EqualTo(expected.Replace("\r\n", "\n"))); }
public void AnErrorIsIssuedIfTheMainMethodHasParameters() { var er = new MockErrorReporter(); var invoker = new OOPEmulatorInvoker(new MockOOPEmulator(), new MockMetadataImporter(), er); var cu = new CSharpParser().Parse(@"class MyClass { public void Main(string[] args) { } }", "file.cs").ToTypeSystem(); var compilation = new CSharpProjectContent().AddOrUpdateFiles(new IUnresolvedFile[] { cu }).AddAssemblyReferences(new[] { MinimalCorlib.Instance }).CreateCompilation(); var typeResolveContext = new SimpleTypeResolveContext(compilation.MainAssembly); invoker.Process(cu.GetAllTypeDefinitions().Select(t => new JsClass(t.Resolve(typeResolveContext).GetDefinition())).ToList <JsType>(), compilation.FindType(new FullTypeName("MyClass")).GetMethods().Single(m => m.Name == "Main")); Assert.That(er.AllMessages, Has.Count.EqualTo(1)); Assert.That(er.AllMessages.Any(m => m.Code == 7800 && (string)m.Args[0] == "MyClass.Main")); }
public bool Compile(CompilerOptions options) { string intermediateAssemblyFile = Path.GetTempFileName(), intermediateDocFile = Path.GetTempFileName(); var actualOut = Console.Out; var er = new ErrorReporterWrapper(_errorReporter, actualOut); try { Console.SetOut(new StringWriter()); // I don't trust the third-party libs to not generate spurious random messages, so make sure that any of those messages are suppressed. var settings = MapSettings(options, intermediateAssemblyFile, intermediateDocFile, er); if (er.HasErrors) return false; if (!options.AlreadyCompiled) { // Compile the assembly var ctx = new CompilerContext(settings, new ConvertingReportPrinter(er)); var d = new Mono.CSharp.Driver(ctx); d.Compile(); if (er.HasErrors) return false; } var references = LoadReferences(settings.AssemblyReferences, er); if (references == null) return false; PreparedCompilation compilation = PreparedCompilation.CreateCompilation(settings.AssemblyName, options.SourceFiles.Select(f => new SimpleSourceFile(f, settings.Encoding)), references.Select(r => r.Item1), options.DefineConstants, LoadResources(options.EmbeddedResources)); IMethod entryPoint = FindEntryPoint(options, er, compilation); var container = new WindsorContainer(); foreach (var plugin in TopologicalSortPlugins(references).Reverse()) RegisterPlugin(container, plugin); container.Register(Component.For<IErrorReporter>().Instance(er), Component.For<CompilerOptions>().Instance(options), Component.For<ICompilation>().Instance(compilation.Compilation), Component.For<ICompiler>().ImplementedBy<Compiler.Compiler>() ); container.Resolve<IMetadataImporter>().Prepare(compilation.Compilation.GetAllTypeDefinitions()); var compiledTypes = container.Resolve<ICompiler>().Compile(compilation); foreach (var rewriter in container.ResolveAll<IJSTypeSystemRewriter>()) compiledTypes = rewriter.Rewrite(compiledTypes); var invoker = new OOPEmulatorInvoker(container.Resolve<IOOPEmulator>(), container.Resolve<IMetadataImporter>(), container.Resolve<IErrorReporter>()); var js = invoker.Process(compiledTypes.ToList(), entryPoint); js = container.Resolve<ILinker>().Process(js); if (er.HasErrors) return false; string outputAssemblyPath = !string.IsNullOrEmpty(options.OutputAssemblyPath) ? options.OutputAssemblyPath : Path.ChangeExtension(options.SourceFiles[0], ".dll"); string outputScriptPath = !string.IsNullOrEmpty(options.OutputScriptPath) ? options.OutputScriptPath : Path.ChangeExtension(options.SourceFiles[0], ".js"); if (!options.AlreadyCompiled) { try { File.Copy(intermediateAssemblyFile, outputAssemblyPath, true); } catch (IOException ex) { er.Region = DomRegion.Empty; er.Message(Messages._7950, ex.Message); return false; } if (!string.IsNullOrEmpty(options.DocumentationFile)) { try { File.Copy(intermediateDocFile, options.DocumentationFile, true); } catch (IOException ex) { er.Region = DomRegion.Empty; er.Message(Messages._7952, ex.Message); return false; } } } if (options.MinimizeScript) { js = ((JsBlockStatement)Minifier.Process(JsStatement.Block(js))).Statements; } string script = options.MinimizeScript ? OutputFormatter.FormatMinified(js) : OutputFormatter.Format(js); try { File.WriteAllText(outputScriptPath, script, settings.Encoding); } catch (IOException ex) { er.Region = DomRegion.Empty; er.Message(Messages._7951, ex.Message); return false; } return true; } catch (Exception ex) { er.Region = DomRegion.Empty; er.InternalError(ex.ToString()); return false; } finally { if (!options.AlreadyCompiled) { try { File.Delete(intermediateAssemblyFile); } catch {} try { File.Delete(intermediateDocFile); } catch {} } if (actualOut != null) { Console.SetOut(actualOut); } } }
public void CyclesInDependencyGraphAreHandledGracefully() { var asm = Common.CreateMockAssembly(); var a = Common.CreateMockTypeDefinition("A1", asm); var b = Common.CreateMockTypeDefinition("B1", asm); var c = Common.CreateMockTypeDefinition("C1", asm); var d = Common.CreateMockTypeDefinition("D1", asm); var deps = new Dictionary<ITypeDefinition, IEnumerable<ITypeDefinition>> { { a, new[] { b } }, { b, new[] { c } }, { c, new[] { a } }, { d, new ITypeDefinition[0] }, }; var er = new MockErrorReporter(); var invoker = new OOPEmulatorInvoker(new MockOOPEmulator { EmulateType = t => new TypeOOPEmulation(new[] { new TypeOOPEmulationPhase(deps[t.CSharpTypeDefinition], new[] { (JsStatement)JsExpression.Null }) }) }, new MockMetadataImporter(), er); invoker.Process(new[] { new JsClass(a), new JsClass(b), new JsClass(c), new JsClass(d) }, null); Assert.That(er.AllMessages, Has.Count.EqualTo(1)); Assert.That(er.AllMessages.Any(m => m.Code == 7802 && ((string)m.Args[0]).Contains("A1") && ((string)m.Args[0]).Contains("B1") && ((string)m.Args[0]).Contains("C1"))); }
private void AssertCorrect(IList<JsType> types, string expected, IOOPEmulator emulator, IMethod entryPoint) { var invoker = new OOPEmulatorInvoker(emulator, new MockMetadataImporter(), new MockErrorReporter()); var result = invoker.Process(types, entryPoint); var actual = OutputFormatter.Format(result, allowIntermediates: true).Replace("\r\n", "\n"); Assert.That(actual, Is.EqualTo(expected.Replace("\r\n", "\n"))); }
public void AnErrorIsIssuedIfTheMainMethodIsNotImplementedAsANormalMethod() { var er = new MockErrorReporter(); var invoker = new OOPEmulatorInvoker(new MockOOPEmulator(), new MockMetadataImporter { GetMethodSemantics = m => m.Name == "Main" ? MethodScriptSemantics.InlineCode("X") : MethodScriptSemantics.NormalMethod(m.Name) }, er); var cu = new CSharpParser().Parse(@"class MyClass { public void Main() { } }", "file.cs").ToTypeSystem(); var compilation = new CSharpProjectContent().AddOrUpdateFiles(new IUnresolvedFile[] { cu }).AddAssemblyReferences(new[] { MinimalCorlib.Instance }).CreateCompilation(); var typeResolveContext = new SimpleTypeResolveContext(compilation.MainAssembly); invoker.Process(cu.GetAllTypeDefinitions().Select(t => new JsClass(t.Resolve(typeResolveContext).GetDefinition())).ToList<JsType>(), compilation.FindType(new FullTypeName("MyClass")).GetMethods().Single(m => m.Name == "Main")); Assert.That(er.AllMessages, Has.Count.EqualTo(1)); Assert.That(er.AllMessages.Any(m => m.Code == 7801 && (string)m.Args[0] == "MyClass.Main")); }
public bool Compile(CompilerOptions options) { string intermediateAssemblyFile = Path.GetTempFileName(), intermediateDocFile = Path.GetTempFileName(); var actualOut = Console.Out; var er = new ErrorReporterWrapper(_errorReporter, actualOut); try { Console.SetOut(new StringWriter()); // I don't trust the third-party libs to not generate spurious random messages, so make sure that any of those messages are suppressed. var settings = MapSettings(options, intermediateAssemblyFile, intermediateDocFile, er); if (er.HasErrors) { return(false); } if (!options.AlreadyCompiled) { // Compile the assembly var ctx = new CompilerContext(settings, new ConvertingReportPrinter(er)); var d = new Mono.CSharp.Driver(ctx); d.Compile(); if (er.HasErrors) { return(false); } } var references = LoadReferences(settings.AssemblyReferences, er); if (references == null) { return(false); } PreparedCompilation compilation = PreparedCompilation.CreateCompilation(settings.AssemblyName, options.SourceFiles.Select(f => new SimpleSourceFile(f, settings.Encoding)), references.Select(r => r.Item1), options.DefineConstants, LoadResources(options.EmbeddedResources)); IMethod entryPoint = FindEntryPoint(options, er, compilation); var container = new WindsorContainer(); foreach (var plugin in TopologicalSortPlugins(references).Reverse()) { RegisterPlugin(container, plugin); } var attributeStore = new AttributeStore(compilation.Compilation, er); container.Register(Component.For <IErrorReporter>().Instance(er), Component.For <CompilerOptions>().Instance(options), Component.For <IAttributeStore>().Instance(attributeStore), Component.For <ICompilation>().Instance(compilation.Compilation), Component.For <ICompiler>().ImplementedBy <Compiler.Compiler>() ); InitializeAttributeStore(attributeStore, container, compilation.Compilation); container.Resolve <IMetadataImporter>().Prepare(compilation.Compilation.GetAllTypeDefinitions()); var compiledTypes = container.Resolve <ICompiler>().Compile(compilation); foreach (var rewriter in container.ResolveAll <IJSTypeSystemRewriter>()) { compiledTypes = rewriter.Rewrite(compiledTypes); } var invoker = new OOPEmulatorInvoker(container.Resolve <IOOPEmulator>(), container.Resolve <IMetadataImporter>(), container.Resolve <IErrorReporter>()); var js = invoker.Process(compiledTypes.ToList(), entryPoint); js = container.Resolve <ILinker>().Process(js); if (er.HasErrors) { return(false); } string outputAssemblyPath = !string.IsNullOrEmpty(options.OutputAssemblyPath) ? options.OutputAssemblyPath : Path.ChangeExtension(options.SourceFiles[0], ".dll"); string outputScriptPath = !string.IsNullOrEmpty(options.OutputScriptPath) ? options.OutputScriptPath : Path.ChangeExtension(options.SourceFiles[0], ".js"); if (!options.AlreadyCompiled) { try { File.Copy(intermediateAssemblyFile, outputAssemblyPath, true); } catch (IOException ex) { er.Region = DomRegion.Empty; er.Message(Messages._7950, ex.Message); return(false); } if (!string.IsNullOrEmpty(options.DocumentationFile)) { try { File.Copy(intermediateDocFile, options.DocumentationFile, true); } catch (IOException ex) { er.Region = DomRegion.Empty; er.Message(Messages._7952, ex.Message); return(false); } } } if (options.MinimizeScript) { js = ((JsBlockStatement)Minifier.Process(JsStatement.Block(js))).Statements; } string script = options.MinimizeScript ? OutputFormatter.FormatMinified(js) : OutputFormatter.Format(js); try { File.WriteAllText(outputScriptPath, script, settings.Encoding); } catch (IOException ex) { er.Region = DomRegion.Empty; er.Message(Messages._7951, ex.Message); return(false); } return(true); } catch (Exception ex) { er.Region = DomRegion.Empty; er.InternalError(ex.ToString()); return(false); } finally { if (!options.AlreadyCompiled) { try { File.Delete(intermediateAssemblyFile); } catch {} try { File.Delete(intermediateDocFile); } catch {} } if (actualOut != null) { Console.SetOut(actualOut); } } }