Skip to content
This repository was archived by the owner on Dec 19, 2018. It is now read-only.

Razor parser rewrite #2590

Merged
merged 6 commits into from
Nov 17, 2018
Merged

Razor parser rewrite #2590

merged 6 commits into from
Nov 17, 2018

Conversation

ajaybhargavb
Copy link
Contributor

@ajaybhargavb ajaybhargavb commented Sep 12, 2018

#2579, #2580, #2581, #2584, #2582, #2587, #2585, #2700, #2689

  • Rewrite CSharp parser
  • Basic rewrite of HTML parser (More improvements to follow)
  • Define and generate syntax nodes and boilerplate
  • Rewrite ClassifiedSpan and TagHelperSpan generation logic
  • Rewrite TagHelper phase
  • Rewrite Intermediate phase
  • Rewrite other miscellaneous features and bug fixes
  • Rewrite partial parsing
  • Added some syntax manipulation APIs
  • Removed unused legacy types
  • Update parser test infrastructure
  • Update tests
  • Regenerated baselines

@NTaylorMullen
Copy link

NTaylorMullen commented Sep 13, 2018

image
😲

@ajaybhargavb
Copy link
Contributor Author

ajaybhargavb commented Sep 13, 2018

It just looks that way because I've duplicated the Html and CSharp parser code instead of editing it directly to keep things building. Reviewing this shouldn't be as painful as it seems but anyways don't bother reviewing this too hard just yet. I suggest skimming it just to look for red flags if any. It will be much easier to review later on when things are cleaner.

This is now ready for review

@ajaybhargavb ajaybhargavb force-pushed the feature/razor-parser branch 6 times, most recently from edbb012 to 88cca81 Compare September 25, 2018 22:21
@ajaybhargavb ajaybhargavb force-pushed the feature/razor-parser branch 2 times, most recently from f6d1798 to 93ce3f1 Compare September 27, 2018 23:40
@ajaybhargavb ajaybhargavb force-pushed the feature/razor-parser branch 3 times, most recently from 64b594f to 85c71b2 Compare November 13, 2018 22:35
@ajaybhargavb ajaybhargavb changed the title [Design] Razor parser rewrite Razor parser rewrite Nov 13, 2018
}
else
else if (context.ChunkGenerator is DirectiveTokenChunkGenerator tokenChunkGenerator)
Copy link
Contributor Author

@ajaybhargavb ajaybhargavb Nov 13, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Intermediate phase is still dependent on ChunkGenerators because the old code was heavily dependent on it. I plan to remove it in the future. #ByDesign

{
if (node.Value != null && node.Value.ChildNodes().All(c => c is MarkupLiteralAttributeValueSyntax))
{
// We need to do what ConditionalAttributeCollapser used to do.
Copy link
Contributor Author

@ajaybhargavb ajaybhargavb Nov 13, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because we got rid of ConditionalAttributeCollapser, I need this logic to merge contiguous MarkupLiterals so we generate a single Intermediate node for all of it. I'll change the above comment to explain this. #ByDesign

@@ -14,23 +14,6 @@ public AddImportChunkGenerator(string ns)

public string Namespace { get; }

public override void Accept(ParserVisitor visitor, Span span)
Copy link
Contributor Author

@ajaybhargavb ajaybhargavb Nov 13, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ChunkGenerators don't really do anything anymore other than be a marker. #ByDesign

}

private static void ConfigureNonStringAttribute(SpanBuilder builder, bool isDuplicateAttribute)
private class AttributeValueRewriter : SyntaxRewriter
Copy link
Contributor Author

@ajaybhargavb ajaybhargavb Nov 13, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whatever is in it is probably ugly. TagHelperBlockRewriter used to do a whole bunch of "special" rewriting of attribute values. Keeping the same behavior while operating on the new tree makes it really ugly. I plan to clean this up as much as possible as part of attribute value syntax improvements. #ByDesign

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesomeness!


namespace Microsoft.AspNetCore.Razor.Language.Syntax
{
internal readonly struct ChildSyntaxList : IEquatable<ChildSyntaxList>, IReadOnlyList<SyntaxNode>
Copy link
Contributor Author

@ajaybhargavb ajaybhargavb Nov 13, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From Roslyn #ByDesign

{
private static readonly string TagHelperAttributeInfoKey = typeof(TagHelperAttributeInfo).Name;

public TagHelperAttributeInfo TagHelperAttributeInfo
Copy link
Contributor Author

@ajaybhargavb ajaybhargavb Nov 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added Metadata about the node as first class properties instead on an annotation. #ByDesign


namespace Microsoft.AspNetCore.Razor.Language.Syntax
{
internal abstract partial class SyntaxNode
Copy link
Contributor Author

@ajaybhargavb ajaybhargavb Nov 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From Roslyn #ByDesign

return content;
}

public static string GetTagName(this MarkupTagBlockSyntax tagBlock)
Copy link
Contributor Author

@ajaybhargavb ajaybhargavb Nov 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are currently extension methods. But these will go away once the structure of a Tag Block is improved. #ByDesign


namespace Microsoft.AspNetCore.Razor.Language.Syntax
{
internal static class SyntaxReplacer
Copy link
Contributor Author

@ajaybhargavb ajaybhargavb Nov 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From Roslyn #ByDesign


namespace Microsoft.AspNetCore.Razor.Language.Syntax
{
internal abstract partial class SyntaxRewriter : SyntaxVisitor<SyntaxNode>
Copy link
Contributor Author

@ajaybhargavb ajaybhargavb Nov 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From Roslyn #ByDesign


namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax
{
internal class SyntaxListPool
Copy link
Contributor Author

@ajaybhargavb ajaybhargavb Nov 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From Roslyn #ByDesign


namespace Microsoft.AspNetCore.Razor.Language.Legacy
{
internal class SpanContext
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SpanContext [](start = 19, length = 11)

I see that this is in the .Leygacy namespace which is OK. I'm hoping that this is somewhat of a temporary bridge between old code and new code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes but they won't go away anytime soon because we don't have a plan for getting rid of EditHandlers


In reply to: 233617210 [](ancestors = 233617210)


namespace Microsoft.AspNetCore.Razor.Language.Syntax
{
internal static class MarkupElementRewriter
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MarkupElementRewriter [](start = 26, length = 21)

I'm assuming that this is also temporary (this is the code that groups elements/tags).

Copy link
Contributor Author

@ajaybhargavb ajaybhargavb Nov 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes but I didn't put it in Legacy because this operates completely on the new infrastructure and doesn't use any of our legacy components.


In reply to: 233619189 [](ancestors = 233619189)

if (source.Length == 0)
{
// Just a marker symbol
return new SourceLocation(source.FilePath, 0, 0, 0);
Copy link
Member

@rynowak rynowak Nov 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really correct? Don't marker symbols still have a location? #ByDesign

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The answer is yes for both questions. This is the case when the document is empty and the only thing we generate is a marker symbol.


In reply to: 233620145 [](ancestors = 233620145)

return WriteBlock(node, BlockKindInternal.Markup, base.VisitMarkupBlock);
}

public override SyntaxNode VisitGenericBlock(GenericBlockSyntax node)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I already regret having a GenericBlock. This is currently only use in attribute values. I'm hoping I can get rid of this when I clean that up.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah there shouldn't be anything generic. Everything should be specific.

Copy link

@NTaylorMullen NTaylorMullen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still poking through, just publishing the comments I have so far.

Copy link

@NTaylorMullen NTaylorMullen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More comments, still looking. Finished tokenizerbackedparser and csharp code parser O_O, they were masssssivveee. It took almost all day, but I was able to finish

Copy link

@NTaylorMullen NTaylorMullen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More comments, starting to look at TagHelper goods. Loving all of the deletions.

@@ -19,10 +19,6 @@ internal class HtmlMarkupParser : TokenizerBackedParser<HtmlTokenizer>
SyntaxFactory.Token(SyntaxKind.Bang, "!"),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not blocking the PR on this but this class definitely need to be refactored in ways like CSharpCodeParser was. CSharpCodeParser is beaaautiful in terms of its factorings and this could benefit from similar treatment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, that is the goal 🏁

@ajaybhargavb
Copy link
Contributor Author

🆙 📅

Copy link

@NTaylorMullen NTaylorMullen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not many comments in regards to the TagHelper pieces, pushing through more.

}

private static void ConfigureNonStringAttribute(SpanBuilder builder, bool isDuplicateAttribute)
private class AttributeValueRewriter : SyntaxRewriter

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesomeness!

@NTaylorMullen
Copy link

I Did it! That was super dope, nothing blocking

@ajaybhargavb
Copy link
Contributor Author

🆙 📅

    - Rewrite CSharp parser
    - Basic rewrite of HTML parser (More improvements to follow)
    - Define and generate syntax nodes and boilerplate
    - Rewrite ClassifiedSpan and TagHelperSpan generation logic
    - Rewrite TagHelper phase
    - Rewrite Intermediate phase
    - Rewrite other miscellaneous features and bug fixes
    - Rewrite partial parsing
    - Added some syntax manipulation APIs
    - Removed unused legacy types
 - Update parser test infrastructure
 - Update tests
 - Regenerated baselines
 - Removed unused legacy types
@ajaybhargavb ajaybhargavb merged commit 6c8e900 into master Nov 17, 2018
@ajaybhargavb ajaybhargavb deleted the feature/razor-parser branch November 17, 2018 01:22
@ajaybhargavb
Copy link
Contributor Author

Thanks for the review @NTaylorMullen and @rynowak

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants