Skip to content

Conversation

@zdenko
Copy link
Collaborator

@zdenko zdenko commented Nov 29, 2017

React fragment syntax (#4802).

Component = (props) =>
  <>
    <OtherComponent />
    <OtherComponent />
  </>

Output:

Component = (props) => {
  return <>
    <OtherComponent />
    <OtherComponent />
  </>;
};

src/lexer.coffee Outdated
# Fragment: <></>
CSX_FRAGMENT_IDENTIFIER = /// ^
(?![\d<]) # Must not start with `<`.
( (?=>) ) # Ends immediately with '>.
Copy link
Collaborator

@vendethiel vendethiel Nov 29, 2017

Choose a reason for hiding this comment

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

why does this need to be a lookahead? why capture a zero-width positive lookahead?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

For normal CSX tags RegEx will capture tag name, e,g, div from <div>.
The fragment tag is empty (<>) which means that tag name is '', and has to be compared to '' from closing tag </>.
I'm far from RexEg mastery and open to any better suggestion.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Aren’t you just trying to match exactly <> or </>? So

/(<>)|(<\/>)/

https://regex101.com/r/68Imt8/2

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, something like that. But, the way CSX processing works in the lexer is more complex and I'm trying to reuse existing code by adding RegEx for empty tag <>. This basically means I need to capture `` in <> which is then used for creating `CSX` token and finding the matching closing tag.
I'm working on RegEx improvement at the moment.

test/csx.coffee Outdated
<h2>Another heading</h2>
Even more text.
</>;
'''
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we also add a test for the example from #4802?

Component = (props) =>
  <Fragment>
    <OtherComponent />
    <OtherComponent />
  </Fragment>

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done.

CSX_FRAGMENT_IDENTIFIER = /// ^
(?![\d<]) # Must not start with number or `<`
(.{0}(?=>)) # Ends immediately with '>.
///
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this could become:

CSX_FRAGMENT_IDENTIFIER = /^((?=>))/ # Ends immediately with `>`.

You’re really only looking for the next character to be >, and capturing a zero-length string so that the regex exec matches. The stuff about “must not start with a number or <“ refers to the identifier inside a normal CSX tag, e.g. the div in <div>. But by definition a fragment has no identifier, so we don’t need to validate one.

src/lexer.coffee Outdated
(?![\d<]) # Must not start with number or `<`
(.{0}(?=>)) # Ends immediately with '>.
///
CSX_FRAGMENT_IDENTIFIER = /// ^ ((?=>)) # Ends immediately with '>`. ///
Copy link
Collaborator

Choose a reason for hiding this comment

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

You want `>`, not '>`. And don't you think the comment should go outside of the regex? It describes the entire regex.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Actually, it’s odd that this even compiles. I would think that the latter /// would be considered part of the comment, leaving this an unclosed regex.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Looks like you found a bug! #4811

@GeoffreyBooth
Copy link
Collaborator

I think this is okay. @vendethiel?

src/lexer.coffee Outdated
///

# Fragment: <></>
CSX_FRAGMENT_IDENTIFIER = /// ^ ((?=>)) /// # Ends immediately with '>'.
Copy link
Collaborator

Choose a reason for hiding this comment

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

why not just /// ^ () > ///?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I've tried that one before but didn't work. At first, I thought I got it wrong and moved on to the different pattern.
But, now after your suggestion, I took a closer look and actually found a bug in the lexer where start and end CSX tag where compared. The code compares group match of the start tag with the full match of the end tag.
It accidentally worked since they are the same, but it failed on fragment tag since the full match is > and group match is ''.

@GeoffreyBooth
Copy link
Collaborator

@vendethiel Did you have any other notes?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants