public void Rewrite_Moves_Whitespace_Preceeding_ExpressionBlock_To_Parent_Block() { // Arrange var factory = SpanFactory.CreateCsHtml(); var start = new MarkupBlock( factory.Markup("test"), new ExpressionBlock( factory.Code(" ").AsExpression(), factory.CodeTransition(SyntaxConstants.TransitionString), factory.Code("foo").AsExpression() ), factory.Markup("test") ); var rewriter = new WhiteSpaceRewriter(new HtmlMarkupParser().BuildSpan); var rewritingContext = new RewritingContext(start, new ParserErrorSink()); // Act rewriter.Rewrite(rewritingContext); factory.Reset(); // Assert ParserTestBase.EvaluateParseTree(rewritingContext.SyntaxTree, new MarkupBlock( factory.Markup("test"), factory.Markup(" "), new ExpressionBlock( factory.CodeTransition(SyntaxConstants.TransitionString), factory.Code("foo").AsExpression() ), factory.Markup("test") )); }
private ParserResults ParseCore(ITextDocument input) { // Setup the parser context var context = new ParserContext(input, CodeParser, MarkupParser, MarkupParser) { DesignTimeMode = DesignTimeMode }; MarkupParser.Context = context; CodeParser.Context = context; // Execute the parse MarkupParser.ParseDocument(); // Get the result var results = context.CompleteParse(); // Rewrite whitespace if supported var rewritingContext = new RewritingContext(results.Document); foreach (ISyntaxTreeRewriter rewriter in Optimizers) { rewriter.Rewrite(rewritingContext); } if (TagHelperDescriptorResolver != null) { var descriptors = GetTagHelperDescriptors(rewritingContext.SyntaxTree); var tagHelperProvider = new TagHelperDescriptorProvider(descriptors); var tagHelperParseTreeRewriter = new TagHelperParseTreeRewriter(tagHelperProvider); // Rewrite the document to utilize tag helpers tagHelperParseTreeRewriter.Rewrite(rewritingContext); } var syntaxTree = rewritingContext.SyntaxTree; // Link the leaf nodes into a chain Span prev = null; foreach (Span node in syntaxTree.Flatten()) { node.Previous = prev; if (prev != null) { prev.Next = node; } prev = node; } // We want to surface both the parsing and rewriting errors as one unified list of errors because // both parsing and rewriting errors affect the end users Razor page. var errors = results.ParserErrors.Concat(rewritingContext.Errors).ToList(); // Return the new result return(new ParserResults(syntaxTree, errors)); }
private ParserResults ParseCore(ITextDocument input) { // Setup the parser context var errorSink = new ErrorSink(); var context = new ParserContext(input, CodeParser, MarkupParser, MarkupParser, errorSink) { DesignTimeMode = DesignTimeMode }; MarkupParser.Context = context; CodeParser.Context = context; // Execute the parse MarkupParser.ParseDocument(); // Get the result var results = context.CompleteParse(); // Rewrite whitespace if supported var rewritingContext = new RewritingContext(results.Document, errorSink); foreach (ISyntaxTreeRewriter rewriter in Optimizers) { rewriter.Rewrite(rewritingContext); } var descriptors = Enumerable.Empty <TagHelperDescriptor>(); if (TagHelperDescriptorResolver != null) { descriptors = GetTagHelperDescriptors(rewritingContext.SyntaxTree, rewritingContext.ErrorSink); var tagHelperProvider = new TagHelperDescriptorProvider(descriptors); var tagHelperParseTreeRewriter = new TagHelperParseTreeRewriter(tagHelperProvider); // Rewrite the document to utilize tag helpers tagHelperParseTreeRewriter.Rewrite(rewritingContext); } var syntaxTree = rewritingContext.SyntaxTree; // Link the leaf nodes into a chain Span prev = null; foreach (Span node in syntaxTree.Flatten()) { node.Previous = prev; if (prev != null) { prev.Next = node; } prev = node; } // Return the new result return(new ParserResults(syntaxTree, descriptors, errorSink)); }
public void EvaluateData( TagHelperDescriptorProvider provider, string documentContent, MarkupBlock expectedOutput, IEnumerable<RazorError> expectedErrors) { var errorSink = new ErrorSink(); var results = ParseDocument(documentContent, errorSink); var rewritingContext = new RewritingContext(results.Document, errorSink); new TagHelperParseTreeRewriter(provider).Rewrite(rewritingContext); var rewritten = rewritingContext.SyntaxTree; var actualErrors = errorSink.Errors.OrderBy(error => error.Location.AbsoluteIndex) .ToList(); EvaluateRazorErrors(actualErrors, expectedErrors.ToList()); EvaluateParseTree(rewritten, expectedOutput); }
public void ConditionalAttributesDoNotCreateExtraDataForEntirelyLiteralAttribute() { // Arrange const string code = @"<div class=""sidebar""> <h1>Title</h1> <p> As the author, you can <a href=""/Photo/Edit/photoId"">edit</a> or <a href=""/Photo/Remove/photoId"">remove</a> this photo. </p> <dl> <dt class=""description"">Description</dt> <dd class=""description""> The uploader did not provide a description for this photo. </dd> <dt class=""uploaded-by"">Uploaded by</dt> <dd class=""uploaded-by""><a href=""/User/View/user.UserId"">user.DisplayName</a></dd> <dt class=""upload-date"">Upload date</dt> <dd class=""upload-date"">photo.UploadDate</dd> <dt class=""part-of-gallery"">Gallery</dt> <dd><a href=""/View/gallery.Id"" title=""View gallery.Name gallery"">gallery.Name</a></dd> <dt class=""tags"">Tags</dt> <dd class=""tags""> <ul class=""tags""> <li>This photo has no tags.</li> </ul> <a href=""/Photo/EditTags/photoId"">edit tags</a> </dd> </dl> <p> <a class=""download"" href=""/Photo/Full/photoId"" title=""Download: (photo.FileTitle + photo.FileExtension)"">Download full photo</a> ((photo.FileSize / 1024) KB) </p> </div> <div class=""main""> <img class=""large-photo"" alt=""photo.FileTitle"" src=""/Photo/Thumbnail"" /> <h2>Nobody has commented on this photo</h2> <ol class=""comments""> <li> <h3 class=""comment-header""> <a href=""/User/View/comment.UserId"" title=""View comment.DisplayName's profile"">comment.DisplayName</a> commented at comment.CommentDate: </h3> <p class=""comment-body"">comment.CommentText</p> </li> </ol> <form method=""post"" action=""""> <fieldset id=""addComment""> <legend>Post new comment</legend> <ol> <li> <label for=""newComment"">Comment</label> <textarea id=""newComment"" name=""newComment"" title=""Your comment"" rows=""6"" cols=""70""></textarea> </li> </ol> <p class=""form-actions""> <input type=""submit"" title=""Add comment"" value=""Add comment"" /> </p> </fieldset> </form> </div>"; // Act var results = ParseDocument(code); var rewritingContext = new RewritingContext(results.Document, new ParserErrorSink()); new ConditionalAttributeCollapser(new HtmlMarkupParser().BuildSpan).Rewrite(rewritingContext); new MarkupCollapser(new HtmlMarkupParser().BuildSpan).Rewrite(rewritingContext); var rewritten = rewritingContext.SyntaxTree; // Assert Assert.Equal(0, results.ParserErrors.Count()); Assert.Equal(rewritten.Children.Count(), results.Document.Children.Count()); }
public void ConditionalAttributeCollapserDoesNotRemoveUrlAttributeValues() { // Act var results = ParseDocument("<a href='~/Foo/Bar' />"); var rewritingContext = new RewritingContext(results.Document, new ParserErrorSink()); new ConditionalAttributeCollapser(new HtmlMarkupParser().BuildSpan).Rewrite(rewritingContext); new MarkupCollapser(new HtmlMarkupParser().BuildSpan).Rewrite(rewritingContext); var rewritten = rewritingContext.SyntaxTree; // Assert Assert.Equal(0, results.ParserErrors.Count()); EvaluateParseTree(rewritten, new MarkupBlock( new MarkupTagBlock( Factory.Markup("<a"), new MarkupBlock(new AttributeBlockCodeGenerator(name: "href", prefix: new LocationTagged<string>(" href='", 2, 0, 2), suffix: new LocationTagged<string>("'", 18, 0, 18)), Factory.Markup(" href='").With(SpanCodeGenerator.Null), Factory.Markup("~/Foo/Bar") .WithEditorHints(EditorHints.VirtualPath) .With(new LiteralAttributeCodeGenerator( new LocationTagged<string>(string.Empty, 9, 0, 9), new LocationTagged<SpanCodeGenerator>(new ResolveUrlCodeGenerator(), 9, 0, 9))), Factory.Markup("'").With(SpanCodeGenerator.Null)), Factory.Markup(" />")))); }
public virtual void Rewrite(RewritingContext context) { context.SyntaxTree.Accept(this); Debug.Assert(_blocks.Count == 1); context.SyntaxTree = _blocks.Pop().Build(); }
public void ConditionalAttributeCollapserDoesNotRewriteEscapedTransitions() { // Act var results = ParseDocument("<span foo='@@' />"); var rewritingContext = new RewritingContext(results.Document, new ErrorSink()); new ConditionalAttributeCollapser(new HtmlMarkupParser().BuildSpan).Rewrite(rewritingContext); var rewritten = rewritingContext.SyntaxTree; // Assert Assert.Equal(0, results.ParserErrors.Count()); EvaluateParseTree(rewritten, new MarkupBlock( new MarkupTagBlock( Factory.Markup("<span"), new MarkupBlock( new AttributeBlockChunkGenerator("foo", new LocationTagged<string>(" foo='", 5, 0, 5), new LocationTagged<string>("'", 13, 0, 13)), Factory.Markup(" foo='").With(SpanChunkGenerator.Null), new MarkupBlock( Factory.Markup("@").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 11, 0, 11), new LocationTagged<string>("@", 11, 0, 11))).Accepts(AcceptedCharacters.None), Factory.Markup("@").With(SpanChunkGenerator.Null).Accepts(AcceptedCharacters.None)), Factory.Markup("'").With(SpanChunkGenerator.Null)), Factory.Markup(" />")))); }
private ParserResults ParseCore(ITextDocument input) { // Setup the parser context var errorSink = new ParserErrorSink(); var context = new ParserContext(input, CodeParser, MarkupParser, MarkupParser, errorSink) { DesignTimeMode = DesignTimeMode }; MarkupParser.Context = context; CodeParser.Context = context; // Execute the parse MarkupParser.ParseDocument(); // Get the result var results = context.CompleteParse(); // Rewrite whitespace if supported var rewritingContext = new RewritingContext(results.Document, errorSink); foreach (ISyntaxTreeRewriter rewriter in Optimizers) { rewriter.Rewrite(rewritingContext); } var descriptors = Enumerable.Empty<TagHelperDescriptor>(); if (TagHelperDescriptorResolver != null) { descriptors = GetTagHelperDescriptors(rewritingContext.SyntaxTree, rewritingContext.ErrorSink); var tagHelperProvider = new TagHelperDescriptorProvider(descriptors); var tagHelperParseTreeRewriter = new TagHelperParseTreeRewriter(tagHelperProvider); // Rewrite the document to utilize tag helpers tagHelperParseTreeRewriter.Rewrite(rewritingContext); } var syntaxTree = rewritingContext.SyntaxTree; // Link the leaf nodes into a chain Span prev = null; foreach (Span node in syntaxTree.Flatten()) { node.Previous = prev; if (prev != null) { prev.Next = node; } prev = node; } // Return the new result return new ParserResults(syntaxTree, descriptors, errorSink); }
public virtual void Rewrite(RewritingContext context) { context.SyntaxTree.Accept(this); Debug.Assert(_blocks.Count == 1); context.SyntaxTree = _blocks.Pop().Build(); }