public Compilation Compile(Post post)
        {
            if (post == null)
            {
                throw new ArgumentNullException("post");
            }

            var console = SyntaxTree.ParseCompilationUnit("public static readonly StringWriter __Console = new StringWriter();",
                                                          options: new ParseOptions(kind: SourceCodeKind.Script));

            var entry = SyntaxTree.ParseCompilationUnit(EntryPoint);

            var prompt = SyntaxTree.ParseCompilationUnit(BuildScript(post.Content), fileName: "Prompt",
                                                         options: new ParseOptions(kind: SourceCodeKind.Interactive))
                                   .RewriteWith<MissingSemicolonRewriter>();

            var editor = SyntaxTree.ParseCompilationUnit(post.Classes ?? string.Empty, fileName: "Editor",
                                                         options: new ParseOptions(kind: SourceCodeKind.Script))
                                   .RewriteWith<MissingSemicolonRewriter>();

            var compilation =  Compile(post.Title ?? "Untitled", new[] { entry, prompt, editor, console });

            var newPrompt = prompt.RewriteWith(new ConsoleRewriter("__Console", compilation.GetSemanticModel(prompt)));
            var newEditor = editor.RewriteWith(new ConsoleRewriter("__Console", compilation.GetSemanticModel(editor)));

            return compilation.ReplaceSyntaxTree(prompt, newPrompt).ReplaceSyntaxTree(editor, newEditor);
        }
예제 #2
0
        public ActionResult Index()
        {
            var classesBuilder = new StringBuilder();

            classesBuilder.AppendLine("public interface IPerson");
            classesBuilder.AppendLine("{");
            classesBuilder.AppendLine("    string Name { get; }");
            classesBuilder.AppendLine();
            classesBuilder.AppendLine("    string Greet();");
            classesBuilder.AppendLine("}");
            classesBuilder.AppendLine();
            classesBuilder.AppendLine("class Person : IPerson");
            classesBuilder.AppendLine("{");
            classesBuilder.AppendLine("    public Person(string name)");
            classesBuilder.AppendLine("    {");
            classesBuilder.AppendLine("        Name = name;");
            classesBuilder.AppendLine("    }");
            classesBuilder.AppendLine();
            classesBuilder.AppendLine("    public string Name { get; private set; }");
            classesBuilder.AppendLine();
            classesBuilder.AppendLine("    public string Greet()");
            classesBuilder.AppendLine("    {");
            classesBuilder.AppendLine("        if (Name == null)");
            classesBuilder.AppendLine("            return \"Hello, stranger!\";");
            classesBuilder.AppendLine();
            classesBuilder.AppendLine("        return string.Format(\"Hello, {0}!\", Name);");
            classesBuilder.AppendLine("    }");
            classesBuilder.AppendLine("}");

            var commandBuilder = new StringBuilder();

            commandBuilder.AppendLine("IPerson person = new Person(name: null);");
            commandBuilder.AppendLine("");
            commandBuilder.AppendLine("return person.Greet();");

            var post = new Post { Content = commandBuilder.ToString(), Classes = classesBuilder.ToString() };

            var errors = compiler.GetCompilationErrors(post.Content, post.Classes)
                                 .Select(x => new EditorError
                                              {
                                                  Location = x.Location.GetLineSpan(true),
                                                  Message = x.Info.GetMessage()
                                              });

            var viewModel = new PostViewModel
                            {
                                Post = post,
                                Errors = errors
                            };

            return View("Show", viewModel);
        }
예제 #3
0
        public ActionResult Save(string slug, Post post)
        {
            var result = db.Save(slug, post);

            var routeValues = new RouteValueDictionary { { "slug", result.Slug } };

            if (result.Version > 1)
            {
                routeValues.Add("version", result.Version);
            }

            var url = Url.Action("Show", routeValues);
            return Json(new { status = "ok", data = new { slug = result.Slug, version = result.Version, url = url } });
        }
예제 #4
0
        public Post ToPost()
        {
            var post = new Post
                       {
                           Slug = Slug,
                           Version = Version,
                       };

            foreach (var doc in Documents)
            {
                post.AddOrUpdateDocument(doc.Name, doc.Text);
            }

            return post;
        }
예제 #5
0
        public ActionResult Save(string slug, Post post)
        {
            if (Request.IsAuthenticated)
            {
                var userId = User.Identity.ToCompilifyIdentity().UserId;
                if (post.AuthorId != userId)
                {
                    slug = null;
                }

                post.AuthorId = userId;
            }

            var result = db.Save(slug, post);

            return RedirectToAction("Show", BuildRouteParametersForPost(result.Slug, result.Version));
        }
예제 #6
0
        public PostViewModel(Post post)
        {
            if (post != null)
            {
                Slug = post.Slug;
                Version = post.Version;

                Title = post.Title;
                Description = post.Description;
                AuthorId = post.AuthorId;

                Tags = string.Join(" ", post.Tags.OrderBy(x => x).ToArray());

                Content = post.Content;
                Classes = post.Classes;
            }

            Errors = new List<EditorError>();
        }
예제 #7
0
        public static PostViewModel Create(Post post)
        {
            if (post == null)
            {
                return null;
            }

            var model = new PostViewModel
                        {
                            Slug = post.Slug,
                            Version = post.Version,
                            AuthorId = post.AuthorId,
                            Documents = post.Documents
                               .Select(doc => new DocumentModel { Name = doc.Name, Text = doc.GetText() })
                               .ToArray()
                        };

            return model;
        }
예제 #8
0
        public ExecutionResult Execute(Post post)
        {
            var compilation = compiler.Compile(post);

            byte[] compiledAssembly;
            using (var stream = new MemoryStream())
            {
                var emitResult = compilation.Emit(stream);

                if (!emitResult.Success)
                {
                    return new ExecutionResult { Result = "[Compilation failed]" };
                }

                compiledAssembly = stream.ToArray();
            }

            using (var sandbox = new Sandbox(compiledAssembly))
            {
                return sandbox.Run("EntryPoint", "Result", TimeSpan.FromSeconds(5));
            }
        }
예제 #9
0
        public Task<PostViewModel> Execute()
        {
            var post = new Post();
            var builder = new StringBuilder();

            builder.AppendLine("class Person")
                .AppendLine("{")
                .AppendLine("    public Person(string name)")
                .AppendLine("    {")
                .AppendLine("        Name = name;")
                .AppendLine("    }")
                .AppendLine()
                .AppendLine("    public string Name { get; private set; }")
                .AppendLine()
                .AppendLine("    public string Greet()")
                .AppendLine("    {")
                .AppendLine("        if (Name == null)")
                .AppendLine("            return \"Hello, stranger!\";")
                .AppendLine()
                .AppendLine("        return string.Format(\"Hello, {0}!\", Name);")
                .AppendLine("    }")
                .AppendLine("}");

            post.Classes = builder.ToString();

            builder.Clear()
                .AppendLine("var person = new Person(name: null);")
                .AppendLine()
                .AppendLine("return person.Greet();");

            post.Content = builder.ToString();

            var result = PostViewModel.Create(post);

            result.Errors = validator.GetCompilationErrors(post);

            return Task.FromResult(result);
        }
예제 #10
0
        public Post Save(string slug, Post content)
        {
            var isNew = string.IsNullOrEmpty(slug);
            if (isNew)
            {
                // No slug was specified, so we need to get the next one
                var docs = db.GetCollection("sequences");

                docs.EnsureIndex(IndexKeys.Ascending("Name"), IndexOptions.SetUnique(true));

                var sequence = docs.FindAndModify(Query.EQ("Name", "slug"), null, Update.Inc("Current", 1), true, true)
                                   .GetModifiedDocumentAs<Incrementor>();

                slug = Base32Encoder.Encode(sequence.Current);
            }

            content.Slug = slug;

            content.Version = isNew ? 1 : GetLatestVersion(slug) + 1;

            db.GetCollection<Post>("posts").Save(content, SafeMode.True);

            return content;
        }
예제 #11
0
        public ActionResult Save(string slug, Post post)
        {
            var result = db.Save(slug, post);

            var routeValues = new RouteValueDictionary { { "slug", result.Slug } };

            if (result.Version > 1)
            {
                routeValues.Add("version", result.Version);
            }

            return RedirectToAction("Show", routeValues);
        }
예제 #12
0
        public IEnumerable<IDiagnostic> GetCompilationErrors(Post post)
        {
            var result = compiler.Compile(post).Emit();

            return result.Diagnostics;
        }
예제 #13
0
        private static void ProcessQueue(string[] queues)
        {
            var stopWatch = new Stopwatch();

            Logger.Info("ProcessQueue started.");

            while (true)
            {
                var cmd = WaitForCommandFromQueue(queues);

                if (cmd == null)
                {
                    continue;
                }

                var timeInQueue = DateTime.UtcNow - cmd.Submitted;

                Logger.Info("Job received after {0:N3} seconds in queue.", timeInQueue.TotalSeconds);

                if (timeInQueue > cmd.TimeoutPeriod)
                {
                    Logger.Warn("Job was in queue for longer than {0} seconds, skipping!", cmd.TimeoutPeriod.Seconds);
                    continue;
                }

                var post = new Post { Content = cmd.Code, Classes = cmd.Classes };

                stopWatch.Start();

                var result = Executer.Execute(post);

                stopWatch.Stop();

                Logger.Info("Work completed in {0} milliseconds.", stopWatch.ElapsedMilliseconds);

                try
                {
                    var response = new WorkerResult
                                   {
                                       // code = cmd.Code,
                                       // classes = cmd.Classes,
                                       Time = DateTime.UtcNow,
                                       Duration = stopWatch.ElapsedMilliseconds,
                                       ExecutionResult = result
                                   };

                    var listeners = PublishToClient(cmd.ClientId, response.GetBytes());

                    Logger.Info("Work results published to {0} listeners.", listeners.Result);
                }
                catch (JsonSerializationException ex)
                {
                    Logger.ErrorException("An error occurred while attempting to serialize the JSON result.", ex);
                }

                stopWatch.Reset();
            }
        }
예제 #14
0
        public Post ToPost()
        {
            var post = new Post
                       {
                           Slug = Slug,
                           Version = Version,

                           Title = Title,
                           Description = Description,

                           Content = Content,
                           Classes = Classes
                       };

            if (!string.IsNullOrEmpty(Tags))
            {
                foreach (var tag in Tags.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries))
                {
                    post.Tags.Add(tag);
                }
            }

            return post;
        }
예제 #15
0
 public PostViewModel()
 {
     Post = new Post();
     Errors = new List<EditorError>();
 }
예제 #16
0
 public PostViewModel()
 {
     Post = new Post();
     Errors = new List<string>();
 }
예제 #17
0
        private static Post BuildSamplePost()
        {
            var post = new Post();
            var builder = new StringBuilder();

            post.Classes = builder.AppendLine("class Person")
                                  .AppendLine("{")
                                  .AppendLine("    public Person(string name)")
                                  .AppendLine("    {")
                                  .AppendLine("        Name = name;")
                                  .AppendLine("    }")
                                  .AppendLine()
                                  .AppendLine("    public string Name { get; private set; }")
                                  .AppendLine()
                                  .AppendLine("    public string Greet()")
                                  .AppendLine("    {")
                                  .AppendLine("        if (Name == null)")
                                  .AppendLine("            return \"Hello, stranger!\";")
                                  .AppendLine()
                                  .AppendLine("        return string.Format(\"Hello, {0}!\", Name);")
                                  .AppendLine("    }")
                                  .AppendLine("}")
                                  .ToString();

            post.Content = builder.Clear()
                                  .AppendLine("var person = new Person(name: null);")
                                  .AppendLine("")
                                  .AppendLine("return person.Greet();")
                                  .ToString();

            return post;
        }
예제 #18
0
 public IEnumerable<EditorError> Execute(Post post)
 {
     return validator.GetCompilationErrors(post);
 }
예제 #19
0
        public ActionResult Validate(ValidateViewModel viewModel)
        {
            var post = new Post { Classes = viewModel.Classes, Content = viewModel.Command };

            var errors = compiler.GetCompilationErrors(post)
                                 .Where(x => x.Info.Severity > DiagnosticSeverity.Warning)
                                 .Select(x => new EditorError
                                              {
                                                  Location = x.Location.GetLineSpan(true),
                                                  Message = x.Info.GetMessage()
                                              });

            return Json(new { status = "ok", data = errors });
        }