Thanks to visit codestin.com
Credit goes to github.com

Skip to content

feat: Implemented new expression parser for NativeScript Core #9729

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

CatchABus
Copy link
Contributor

@CatchABus CatchABus commented Jan 5, 2022

PR Checklist

What is the current behavior?

For years now, vanilla NativeScript has been providing us with its own data-binding system that can also be used inside XML which has been really helpful.

However, in additional to popular frameworks, one has very limited options for composing an expression in NativeScript Core.
For example, one cannot call any functions that are not direct properties of binding context or let's say use features from newest ECMA versions.

To parse expressions, NativeScript is using a certain package's sources inside repo: https://www.npmjs.com/package/polymer-expressions.
The polymer-expressions package has been abandoned for 5 years now, and Polymer library itself is in maintainance mode.
It's using version 2.0.0-dev of esprima parser which is also quite old, to manage an AST Expression schema and all in all it has very limited features.

Here is a very small sample of what is the current state of expression parsing:

<Page actionBarHidden="true" xmlns="http://www.nativescript.org/tns.xsd">
	<StackLayout>
		<Label text="{{ funcOfContext() }}"/> <!-- Possible -->
		<Label text="{{ propertyOfContext.func() }}"/> <!-- Not possible -->
                <Label text="{{ funcOfContext(...prop) }}"/> <!-- Not Possible -->

		<Label text="{{ prop.test }}"/> <!-- Possible -->
		<Label text="{{ prop?.test }}"/> <!-- Not possible -->

		<Label text="{{ prop || prop2 }}"/> <!-- Possible -->
		<Label text="{{ prop ?? prop2 }}"/> <!-- Not possible -->

		<Label text="in Operator" textWrap="{{ prop in obj ? true : false }}"/> <!-- Not possible -->
		<Label text="typeof Operator" textWrap="{{ typeof prop == 'object' ? true : false }}"/> <!-- Not possible -->
	</StackLayout>
</Page>

What is the new behavior?

This began as an experiment at holidays and I ended up composing a new AST parser that keeps existing behaviour and adds more features.
On top of that, it makes possible what is impossible in the XML example below.

There is a dozen of methods to parse AST schemas out there, with browserify's static-eval being a good option but none of them had an out-of-the-box proper support for NativeScript features and contained few bugs.

Just like before, expression parsing is done using AST pattern and parsed expression results are stored in custom parser's cache to avoid parsing over and over.

Features

I have made sure to support lots of additional features like constructor calls, spread operator for both arrays and objects which can also be used as a function arguments, null coalescing operator, optional chaining, in & typeof operators, and even untagged template literal syntax!

The old approach did not support function and arrow lambda expressions and so does the new one. Adding support for such expressions will make things too complicated as there will be the need of statements support like variable declarations, assign operators and more.

Old mechanism used esprima. I started creating this patch using the same parser but I eventually switched to acorn since it's already used in NativeScript for webpack functionality and supports latest ecma features.

I have also made sure function calls and converters have their appropriate call context.

Converters

https://v7.docs.nativescript.org/core-concepts/data-binding#using-converters-in-bindings

Regarding NativeScript converters, there is a small detail that makes new behaviour differ from the old:
This reference is deprecated as converter usage has become identical to old one.

Error Reporting

Regarding expression parsing errors, the old approach enclosed all logic inside a try catch which would print a not-so-specific message about a binding error. The new approach uses a separate try catch for acorn parse, in order to print parser errors regarding expression syntax and other stuff during parsing.

Conclusion

This will have positive results for vanilla NS developers. There have been many times I have personally attempted to make something work in XML without much effort but failed. On top of that, this will add missing new ecma features in the XML part of NativeScript.

…ators even though esprima 4 does not support it.
@cla-bot cla-bot bot added the cla: yes label Jan 5, 2022
@NathanWalker NathanWalker changed the base branch from master to release/8.2.0 January 5, 2022 23:08
@NathanWalker NathanWalker added this to the 8.2 milestone Jan 5, 2022
@NathanWalker
Copy link
Contributor

We will put this out with next alpha testing target of 8.2 - excellent work @dimitrisrk

@CatchABus
Copy link
Contributor Author

CatchABus commented Jan 5, 2022

We will put this out with next alpha testing target of 8.2 - excellent work @dimitrisrk

Thank you very much! It would be great if this gets into alpha!

PS: My bad, I noticed few test fails in iOS. I didn't notice them due to already existing tests failing in master branch.
I'll run automated locally and try get rid of those as soon as possible.

@cla-bot
Copy link

cla-bot bot commented Jan 5, 2022

Thank you for your pull request and welcome to our community. We could not parse the GitHub identity of the following contributors: FUELICS PC.
This is most likely caused by a git client misconfiguration; please make sure to:

  1. check if your git client is configured with an email to sign commits git config --list | grep email
  2. If not, set it up using git config --global user.email [email protected]
  3. Make sure that the git commit email is configured in your GitHub account settings, see https://github.com/settings/emails

@cla-bot cla-bot bot removed the cla: yes label Jan 5, 2022
@cla-bot
Copy link

cla-bot bot commented Jan 6, 2022

Thank you for your pull request and welcome to our community. We could not parse the GitHub identity of the following contributors: FUELICS PC.
This is most likely caused by a git client misconfiguration; please make sure to:

  1. check if your git client is configured with an email to sign commits git config --list | grep email
  2. If not, set it up using git config --global user.email [email protected]
  3. Make sure that the git commit email is configured in your GitHub account settings, see https://github.com/settings/emails

@CatchABus
Copy link
Contributor Author

@cla-bot check

@cla-bot
Copy link

cla-bot bot commented Jan 6, 2022

Thank you for your pull request and welcome to our community. We could not parse the GitHub identity of the following contributors: FUELICS PC.
This is most likely caused by a git client misconfiguration; please make sure to:

  1. check if your git client is configured with an email to sign commits git config --list | grep email
  2. If not, set it up using git config --global user.email [email protected]
  3. Make sure that the git commit email is configured in your GitHub account settings, see https://github.com/settings/emails

@cla-bot
Copy link

cla-bot bot commented Jan 6, 2022

The cla-bot has been summoned, and re-checked this pull request!

@CatchABus CatchABus force-pushed the ns-xml-expression-parser branch from 4ed88e4 to 2f7627d Compare January 6, 2022 00:18
@cla-bot cla-bot bot added the cla: yes label Jan 6, 2022
@CatchABus
Copy link
Contributor Author

CatchABus commented Jan 6, 2022

There have been few fixes that also let tests pass. No related tests are breaking now.

@farfromrefug
Copy link
Collaborator

@dimitrisrk this is pretty awesome! and you also actually reduce N package significantly

@CatchABus
Copy link
Contributor Author

CatchABus commented Jan 6, 2022

@dimitrisrk this is pretty awesome! and you also actually reduce N package significantly

Thank you Martin!! I really hope this makes things easier.

Might also be the first step to get rid of outdated core jslib directory that contains 3rd-party package sources.
The only thing left in there is easysax XML parser whose sources are taken from here: https://www.npmjs.com/package/easysax
I'm positive its functionality may easily be covered using sax or saxes along with few tweaks for Angular parsing.

@NathanWalker NathanWalker merged commit bb71526 into NativeScript:release/8.2.0 Jan 6, 2022
@NathanWalker
Copy link
Contributor

@dimitrisrk this is in 8.2.0-alpha.1 now.

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

Successfully merging this pull request may close these issues.

3 participants