Commit graph

223 commits

Author SHA1 Message Date
davidot
f75c51b097 LibJS: Allow full ModuleExportName in namespace
This means we should accept a string after 'export * as '.
2022-09-02 02:07:37 +01:00
davidot
fce2b33758 LibJS: Allow BigInts as destructuring property names
These are simply treated as their numerical value which means that above
2^32 - 1 they are strings.
2022-08-24 23:27:17 +01:00
davidot
ae349ec6a8 LibJS: Use a synthetic constructor if class with parent doesn't have one
We already did this but it called the @@iterator method of
%Array.prototype% visible to the user for example by overriding that
method. This should not be visible so we use a special version of
SuperCall now.
2022-08-20 23:53:55 +01:00
davidot
e5adc51e27 LibJS: Allow invalid string in tagged template literals
Since tagged template literals can inspect the raw string it is not a
syntax error to have invalid escapes. However the cooked value should be
`undefined`.
We accomplish this by tracking whether parse_string_literal
fails and then using a NullLiteral (since UndefinedLiteral is not a
thing) and finally converting null in tagged template execution to
undefined.
2022-08-17 23:56:24 +01:00
Ali Mohammad Pur
f4b26b0cea LibJS: Hook up the 'v' (unicodeSets) RegExp flag 2022-07-20 21:25:59 +01:00
sin-ack
3f3f45580a Everywhere: Add sv suffix to strings relying on StringView(char const*)
Each of these strings would previously rely on StringView's char const*
constructor overload, which would call __builtin_strlen on the string.
Since we now have operator ""sv, we can replace these with much simpler
versions. This opens the door to being able to remove
StringView(char const*).

No functional changes.
2022-07-12 23:11:35 +02:00
Daniel Bertalan
ebac8abc04 LibJS: Explicitly instantiate Parser::parse_function_node
Due to macOS visibility rules, this function did not end up being
exported from liblagom-js.dylib, causing LagomWeb to fail to link.
2022-07-04 21:46:02 +02:00
Linus Groh
5a26a547db LibJS: Update a couple of outdated spec comments
These are editorial changes in the ECMA-262 spec.

See:
- https://github.com/tc39/ecma262/commit/e080a7f
- https://github.com/tc39/ecma262/commit/c5a9094
- https://github.com/tc39/ecma262/commit/5091520
- https://github.com/tc39/ecma262/commit/1c6564b
- https://github.com/tc39/ecma262/commit/e06c80c
2022-05-01 22:47:38 +02:00
Luke Wilde
34f902fb52 LibJS: Add missing steps and spec comments to PerformEval
While adding spec comments to PerformEval, I noticed we were missing
multiple steps.

Namely, these were:
- Checking if the host will allow us to compile the string
  (allowing LibWeb to perform CSP for eval)
- The parser's initial state depending on the environment around us
  on direct eval:
   - Allowing new.target via eval in functions
   - Allowing super calls and super properties via eval in classes
   - Disallowing the use of the arguments object in class field
     initializers at eval's parse time
- Setting ScriptOrModule of eval's execution context

The spec allows us to apply the additional parsing steps in any order.
The method I have gone with is passing in a struct to the parser's
constructor, which overrides the parser's initial state to (dis)allow
the things stated above from the get-go.
2022-04-11 21:23:36 +01:00
Idan Horowitz
086969277e Everywhere: Run clang-format 2022-04-01 21:24:45 +01:00
Idan Horowitz
7ebb421ee9 LibJS: Implement the object literal __proto__ property key special case 2022-03-06 01:38:25 +02:00
davidot
2c6183da1e LibJS: Allow methods in classes named 'async'
Also add tests for all static, setter and getter cases.
2022-02-18 13:47:47 +00:00
davidot
65bebb5241 LibJS: Allow CallExpression as left hand side of for-of/for-in loops
Although this will fail with a ReferenceError it should pass the parser
and only fail if actually assigned to.
2022-02-18 13:47:47 +00:00
Anonymous
602190f66f LibJS: Fix mixing of logical and coalescing operators
The same expression is not allowed to contain both the
logical && and || operators, and the coalescing ?? operator.

This patch changes how "forbidden" tokens are handled, using a
finite set instead of an Vector. This supports much more efficient
merging of the forbidden tokens when propagating forward, and
allowing the return of forbidden tokens to parent contexts.
2022-02-16 11:18:41 +00:00
Anonymous
f55d7bf6f3 LibJS: Fix cases where we incorrectly allowed 'in' in for loops
We needed to propagate the forbidden token set to all parsing functions
that can call back into parse_expression.
2022-02-15 10:31:41 +00:00
Andreas Kling
50a446a5d1 LibJS: Make more use of Token::flystring_value()
This patch makes check_identifier_name_for_assignment_validity()
take a FlyString instead of a StringView. We then exploit this by
passing FlyString in more places via flystring_value().

This gives a ~1% speedup when parsing the largest Discord JS file.
2022-02-13 14:44:36 +01:00
Andreas Kling
0cb0979990 LibJS: Add Token::flystring_value() to produce FlyString directly
When parsing identifiers, we ultimately want to sink the token string
into a FlyString anyway, and since Token may have a FlyString already
inside it, this allows us to bypass the costly FlyString(StringView).

This gives a ~3% speedup when parsing the largest Discord JS file.
2022-02-13 14:44:36 +01:00
Andreas Kling
1a3fa2d88b LibJS: Make Parser::ScopePusher::has_declaration() take FlyString
Everyone who calls this already has a FlyString, so we were doing *way*
more work by pessimizing it to a StringView.

This gives a ~2% speedup when parsing the largest Discord JS file.
2022-02-13 14:44:36 +01:00
davidot
4136cbdb09 LibJS: Convert ScopeNode declaration functions to ThrowCompletionOr
This removes a number of vm.exception() checks which are now caught
directly by TRY. Make use of these checks in
{Global, Eval}DeclarationInstantiation and while we're here add spec
comments.
2022-02-08 09:12:42 +00:00
Linus Groh
6f20f49b21 Everywhere: Rename JS::PropertyKey variables from property_{name => key}
PropertyKey used to be called PropertyName, but got renamed. Let's
update all the variables of this type as well.
2022-02-06 22:02:45 +00:00
davidot
e0e4ead2c8 LibJS: Follow the spec with storing im- and export entries
Because we can have arbitrary in- and export names with strings we can
have '*' and '' which means using '*' as an indicating namespace imports
failed / behaved incorrectly for string imports '*'.
We now use more specific types to indicate these special states instead
of these 'magic' string values.

Do note that 'default' is not actually a magic string value but one
specified by the spec. And you can in fact export the default value by
doing: `export { 1 as default }`.
2022-01-30 17:40:20 +00:00
davidot
99edf5b25a LibJS: Track whether a program has a top level await statement 2022-01-22 01:21:18 +00:00
davidot
aca427fc8c LibJS: Make parsing import and export entries follow the spec
The big changes are:
- Allow strings as Module{Export, Import}Name
- Properly track declarations in default export statements

However, the spec is a little strange in that it allows function and
class declarations without a name in default export statements.
This is quite hard to fully implement without rewriting more of the
parser so for now this behavior is emulated by faking things with
function and class expressions. See the comments in
parse_export_statement for details on the hacks and where it goes wrong.
2022-01-22 01:21:18 +00:00
Linus Groh
531d1ac734 LibJS: Capture source text of FunctionNode and ClassExpression 2022-01-19 20:33:08 +00:00
Linus Groh
95a9f12b97 LibJS: Set Token's m_offset to the value's start index
This makes much more sense than the current way of setting it to the
Lexer's m_position after consuming the full value.
2022-01-19 20:33:08 +00:00
Linus Groh
e8519156bc LibJS: Implement create_dynamic_function() according to the spec
The three major changes are:

- Parsing parameters, the function body, and then the full assembled
  function source all separately. This is required by the spec, as
  function parameters and body must be valid each on their own, which
  cannot be guaranteed if we only ever parse the full function.
- Returning an ECMAScriptFunctionObject instead of a FunctionExpression
  that needs to be evaluated separately. This vastly simplifies the
  {Async,AsyncGenerator,Generator,}Function constructor implementations.
  Drop '_node' from the function name accordingly.
- The prototype is now determined via GetPrototypeFromConstructor and
  passed to OrdinaryFunctionCreate.
2022-01-16 01:54:48 +01:00
Linus Groh
f0b2179bd7 LibJS: Don't require ParenClose in Parser::parse_formal_parameters()
The parentheses are dealt with outside this function, so we shouldn't
use the (non)existence of one as the condition for consuming another
comma and then parameter. Just check for a comma instead. This becomes
relevant when parsing standalone function parameters as per the spec in
the CreateDynamicFunction AO.
2022-01-16 01:54:48 +01:00
Linus Groh
e730ada07d LibJS: Consume curly braces outside of Parser::parse_function_body()
The curly braces are not part of the FunctionBody production. This
becomes relevant when parsing a standalone function body as per the spec
in the CreateDynamicFunction AO.
2022-01-16 01:54:48 +01:00
Linus Groh
0c73fbbba5 LibJS: Rename FunctionKind::{Regular => Normal}
This is what CreateDynamicFunction calls it.
2022-01-16 01:54:48 +01:00
Linus Groh
9d0d3affd4 LibJS: Replace the custom unwind mechanism with completions :^)
This includes:

- Parsing proper LabelledStatements with try_parse_labelled_statement()
- Removing LabelableStatement
- Implementing the LoopEvaluation semantics via loop_evaluation() in
  each IterationStatement subclass; and IterationStatement evaluation
  via {For,ForIn,ForOf,ForAwaitOf,While,DoWhile}Statement::execute()
- Updating ReturnStatement, BreakStatement and ContinueStatement to
  return the appropriate completion types
- Basically reimplementing TryStatement and SwitchStatement according to
  the spec, using completions
- Honoring result completion types in AsyncBlockStart and
  OrdinaryCallEvaluateBody
- Removing any uses of the VM unwind mechanism - most importantly,
  VM::throw_exception() now exclusively sets an exception and no longer
  triggers any unwinding mechanism.
  However, we already did a good job updating all of LibWeb and userland
  applications to not use it, and the few remaining uses elsewhere don't
  rely on unwinding AFAICT.
2022-01-06 12:36:23 +01:00
davidot
e179cf2540 LibJS: Don't VERIFY that the token after 'import' is one of '.' and '('
Although those are the only valid options parse_primary_expression is
sometimes called when only an expression is valid which means it did not
check match_expression and might fail the now removed VERIFY.
2021-12-29 16:57:23 +01:00
davidot
be3b806487 LibJS: Parse assert clauses of in- and export statements
Based on proposal: https://tc39.es/proposal-import-assertions
Since imports are not supported yet this is not functional.
2021-12-21 14:04:23 +01:00
davidot
81312986fe LibJS: Disallow async generator functions called 'await' or 'yield' 2021-12-21 14:04:23 +01:00
davidot
c8e80690a7 LibJS: Don't treat yield after void as identifier in generator functions 2021-12-21 14:04:23 +01:00
davidot
45578f58dc LibJS: Allow super property lookup and new.target in static init blocks 2021-12-21 14:04:23 +01:00
davidot
5010d4c20c LibJS: Don't match async \n function as an async function declaration 2021-11-30 17:05:32 +00:00
davidot
c2ebaa9d87 LibJS: Replace the verify in private identifier with a syntax error
Since sometimes expressions are parsed without checking we can hit this
expression without it being followed by an 'in'.
2021-11-30 17:05:32 +00:00
davidot
b7c7d54167 LibJS: Split parsing program to script and module separately
This allows us to only perform checks like export bindings existing only
for modules. Also this makes it easier to set strict and other state
variables with TemporaryChanges.
2021-11-30 17:05:32 +00:00
davidot
22174d3b7b LibJS: Rename in_async_function_context to await_expression_is_valid
Since await can be valid in module code which is not an async function
the old name is not really representative for the usage.
2021-11-30 17:05:32 +00:00
davidot
045a42cf35 LibJS: Parse dynamic import calls 'import()' and 'import.meta'
For now both just throw when executing but this can be implemented when
modules are implemented :^).
2021-11-30 17:05:32 +00:00
davidot
73eb29dabe LibJS: Lookahead for a period when parsing new.target
This allows us to skip saving and loading the state whenever we parse
'new'.
2021-11-30 17:05:32 +00:00
davidot
4d7e79fb72 LibJS: Stop parsing an expression on comma after a yield 2021-11-30 17:05:32 +00:00
davidot
156dfe3d62 LibJS: Disallow member expression in binding pattern as parameters 2021-11-30 17:05:32 +00:00
davidot
51e23cd043 LibJS: Disallow shorthand properties with reserved names 2021-11-30 17:05:32 +00:00
davidot
e491fc0e81 LibJS: Allow defining class fields with "keyword" names 2021-11-30 17:05:32 +00:00
davidot
cbbfcd35e7 LibJS: Disallow await keywords in static init blocks
In static init blocks 'await' cannot be used. Note that this does not
cover all the cases since the parser currently cannot distinguish
between expressions within parenthesis and direct expressions.
2021-11-30 17:05:32 +00:00
davidot
c57721cf83 LibJS: Allow escaped 'async' as identifier
Since 'async' is only special if it occurs before a function it can be
used as escaped identifier in all cases.
2021-11-30 17:05:32 +00:00
davidot
e751dcea43 LibJS: Treat private identifier as divisible token
And also make sure private identifiers are correctly checked when
synthesizing a binding pattern.
2021-11-30 17:05:32 +00:00
davidot
32016d3924 LibJS: Allow object properties called 'async' 2021-11-30 17:05:32 +00:00
davidot
e69276e704 LibJS: Implement parsing and executing for-await-of loops 2021-11-29 15:20:07 +00:00
davidot
0982a73d1d LibJS: Parse async generator functions 2021-11-21 21:46:39 +00:00
davidot
de46a2cff1 LibJS: Parse async arrow functions 2021-11-21 21:46:39 +00:00
Andreas Kling
8b1108e485 Everywhere: Pass AK::StringView by value 2021-11-11 01:27:46 +01:00
Idan Horowitz
d5f637fa21 LibJS: Do not parse async methods with a new line after the "async"
This was already checked in normal function expressions, but was
missing for Object Expressions.
2021-11-10 18:11:26 +00:00
Idan Horowitz
46dabf02ec LibJS: Add support for await expressions 2021-11-10 08:48:27 +00:00
Idan Horowitz
681787de76 LibJS: Add support for async functions
This commit adds support for the most bare bones version of async
functions, support for async generator functions, async arrow functions
and await expressions are TODO.
2021-11-10 08:48:27 +00:00
Andreas Kling
398c181c79 LibJS: Rename PropertyName to PropertyKey
Let's use the same name as the spec. :^)
2021-10-24 17:18:07 +02:00
davidot
2d48529073 LibJS: Implement private identifiers in optional chains 2021-10-20 23:19:17 +01:00
davidot
4c8090a45d LibJS: Use ClassFieldInitializerStatement for class fields
This is necessary as we might have to perform named evaluation with the
field name.
Ideally we would also skip some setup parts of the function like
function_declaration_instantiation however this would require bigger
changes to ECMAScriptFunctionObject.
2021-10-20 23:19:17 +01:00
davidot
7e8724db71 LibJS: Add support for the '#privateName in obj' expression 2021-10-20 23:19:17 +01:00
davidot
16cc82460f LibJS: Add parsing and evaluation of private fields and methods 2021-10-20 23:19:17 +01:00
davidot
6b2accce31 LibJS: Add static initializers to classes 2021-10-20 23:19:17 +01:00
davidot
1245512c50 LibJS: Make class definition evaluation more spec like in ordering 2021-10-20 23:19:17 +01:00
davidot
9394cbcd24 LibJS: Do not save state for peeking at the next token from the lexer
This saves having to save and load the parser state.
This could give an incorrect token in some cases where the parser
communicates to the lexer. However this is not applicable in any of the
current usages and this would require one to parse the current token
as normal which is exactly what you don't want to do in that scenario.
2021-10-15 10:27:16 +01:00
Ali Mohammad Pur
13138811df LibJS: Partially revert 12b283f
This commit partially reverts "LibJS: Make accessing the current
function's arguments cheaper".
While the change passed all the currently passing test262 tests, it
seems to have _some_ flaw that silently breaks with some real-world
websites.
As the speedup with negligible at best, let's just revert it until we
can implement it more correctly.
2021-10-08 19:56:02 +03:30
Andreas Kling
b2de563166 LibJS: Propagate "contains direct call to eval()" flag from parser
We now propagate this flag to FunctionDeclaration, and then also into
ECMAScriptFunctionObject.

This will be used to disable optimizations that aren't safe in the
presence of direct eval().
2021-10-08 12:43:38 +02:00
Ali Mohammad Pur
12b283f32f LibJS: Make accessing the current function's arguments cheaper
Instead of going through an environment record, make arguments of the
currently executing function generate references via the argument index,
which can later be resolved directly through the ExecutionContext.
2021-10-08 12:25:24 +02:00
Ali Mohammad Pur
da296ffd56 LibJS: Treat the Catch binding identifier as a var binding 2021-10-08 12:25:24 +02:00
Linus Groh
4fa5748093 LibJS: Add an optimization to avoid needless arguments object creation
This gives FunctionNode a "might need arguments object" boolean flag and
sets it based on the simplest possible heuristic for this: if we
encounter an identifier called "arguments" or "eval" up to the next
(nested) function declaration or expression, we won't need an arguments
object. Otherwise, we *might* need one - the final decision is made in
the FunctionDeclarationInstantiation AO.

Now, this is obviously not perfect. Even if you avoid eval, something
like `foo.arguments` will still trigger a false positive - but it's a
start and already massively cuts down on needlessly allocated objects,
especially in real-world code that is often minified, and so a full
"arguments" identifier will be an actual arguments object more often
than not.

To illustrate the actual impact of this change, here's the number of
allocated arguments objects during a full test-js run:

Before:
- Unmapped arguments objects: 78765
- Mapped arguments objects: 2455

After:
- Unmapped arguments objects: 18
- Mapped arguments objects: 37

This results in a ~5% speedup of test-js on my Linux host machine, and
about 3.5% on i686 Serenity in QEMU (warm runs, average of 5).

The following microbenchmark (calling an empty function 1M times) runs
25% faster on Linux and 45% on Serenity:

    function foo() {}
    for (var i = 0; i < 1_000_000; ++i)
        foo();

test262 reports no changes in either direction, apart from a speedup :^)
2021-10-05 10:15:14 +01:00
davidot
1bc945860d Everywhere: Use my awesome new serenityos email :^) 2021-10-03 13:53:47 +01:00
davidot
830ea0414c LibJS: Make scoping follow the spec
Before this we used an ad-hoc combination of references and 'variables'
stored in a hashmap. This worked in most cases but is not spec like.
Additionally hoisting, dynamically naming functions and scope analysis
was not done properly.

This patch fixes all of that by:
  - Implement BindingInitialization for destructuring assignment.
  - Implementing a new ScopePusher which tracks the lexical and var
    scoped declarations. This hoists functions to the top level if no
    lexical declaration name overlaps. Furthermore we do checking of
    redeclarations in the ScopePusher now requiring less checks all over
    the place.
  - Add methods for parsing the directives and statement lists instead
    of having that code duplicated in multiple places. This allows
    declarations to pushed to the appropriate scope more easily.
  - Remove the non spec way of storing 'variables' in
    DeclarativeEnvironment and make Reference follow the spec instead of
    checking both the bindings and 'variables'.
  - Remove all scoping related things from the Interpreter. And instead
    use environments as specified by the spec. This also includes fixing
    that NativeFunctions did not produce a valid FunctionEnvironment
    which could cause issues with callbacks and eval. All
    FunctionObjects now have a valid NewFunctionEnvironment
    implementation.
  - Remove execute_statements from Interpreter and instead use
    ASTNode::execute everywhere this simplifies AST.cpp as you no longer
    need to worry about which method to call.
  - Make ScopeNodes setup their own environment. This uses four
    different methods specified by the spec
    {Block, Function, Eval, Global}DeclarationInstantiation with the
    annexB extensions.
  - Implement and use NamedEvaluation where specified.

Additionally there are fixes to things exposed by these changes to eval,
{for, for-in, for-of} loops and assignment.

Finally it also fixes some tests in test-js which where passing before
but not now that we have correct behavior :^).
2021-09-30 08:16:32 +01:00
davidot
4428e494b0 LibJS: Handle escaped keywords in more cases and handle 'await' labels 2021-09-30 08:16:32 +01:00
davidot
79caca8ca2 LibJS: Allow multiple labels on the same statement
Since there are only a number of statements where labels can actually be
used we now also only store labels when necessary.
Also now tracks the first continue usage of a label since this might not
be valid but that can only be determined after we have parsed the
statement.
Also ensures the correct error does not get wiped by load_state.
2021-09-30 08:16:32 +01:00
davidot
bfc1b4ba61 LibJS: Allow member expressions in binding patterns
Also allows literal string and numbers as property names in object
binding patterns.
2021-09-30 08:16:32 +01:00
davidot
9cb5700398 LibJS: Disallow comma after rest parameter in formal parameters 2021-09-30 08:16:32 +01:00
Andreas Kling
3252d984ae LibJS: Allow statements to have multiple labels
This is a curious thing that occurs more often than you'd think in
minified JavaScript:

    a: b: c: for (...) { ... break b; ... }
2021-09-26 18:24:19 +02:00
Linus Groh
32932f83be LibJS: Rename {Abstract,Typed => Loosely,Strictly}{Equals,Inequals}
This affects the AST's BinaryOp enum as well as the Bytecode's
ENUMERATE_BYTECODE_OPS and JS_ENUMERATE_COMMON_BINARY_OPS macros.
2021-09-24 09:13:57 +02:00
Ben Wiederhake
32e98d0924 Libraries: Use AK::Variant default initialization where appropriate 2021-09-21 04:22:52 +04:30
Andreas Kling
33f038ba7a LibJS: Add fast failure path to try_parse_labelled_statement()
If the next token isn't a TokenType::Colon (:), this can't possibly be a
labelled statement, so we can fail before having to save_state().

This improves parsing time on a large chunk of JS by ~12.5%.
2021-09-18 19:54:24 +02:00
Ali Mohammad Pur
c7a99aafac LibJS: Use ScopePusher to correctly push the scope in for statements
We were previously pushing a scope but forgetting to actually set it as
the current scope.
2021-09-16 21:51:45 +02:00
Ali Mohammad Pur
72ddaa31e3 LibJS: Implement parsing and execution of optional chains 2021-09-14 20:03:27 +01:00
Andreas Kling
910de95e7a LibJS: Add a fast failure path to try_parse_arrow_function_expression()
The save/load of parser state performed by lookahead parsing is quite
expensive so let's try to avoid it in the most common case.

This is a 15-20% speedup on various chunks of JS I've tested. :^)
2021-09-14 02:51:16 +02:00
davidot
3fee7b0d0b LibJS: Fix that windows style line endings were not ignored or converted
These are tested by test262 but the current test262-runner reads the
files in python which automatically converts \r\n to \n.
This meant that we passed the tests while we should not have.
2021-09-06 08:43:38 +01:00
Daniel Bertalan
d7b6cc6421 Everywhere: Prevent risky implicit casts of (Nonnull)RefPtr
Our existing implementation did not check the element type of the other
pointer in the constructors and move assignment operators. This meant
that some operations that would require explicit casting on raw pointers
were done implicitly, such as:
- downcasting a base class to a derived class (e.g. `Kernel::Inode` =>
  `Kernel::ProcFSDirectoryInode` in Kernel/ProcFS.cpp),
- casting to an unrelated type (e.g. `Promise<bool>` => `Promise<Empty>`
  in LibIMAP/Client.cpp)

This, of course, allows gross violations of the type system, and makes
the need to type-check less obvious before downcasting. Luckily, while
adding the `static_ptr_cast`s, only two truly incorrect usages were
found; in the other instances, our casts just needed to be made
explicit.
2021-09-03 23:20:23 +02:00
Andreas Kling
eaf88cc78a AK: Rename create<T> => make_ref_counted<T>
And also try_create<T> => try_make_ref_counted<T>.

A global "create" was a bit much. The new name matches make<T> better,
which we've used for making single-owner objects since forever.
2021-09-03 02:36:09 +02:00
davidot
def8b44c40 LibJS: Add support for public fields in classes 2021-09-01 13:39:14 +01:00
davidot
3b6a8d1d53 LibJS: Fix small issues in parser
- Fix some places where escaped keywords are (not) allowed.
- Be more strict about parameters for functions with 'use strict'.
- Fix that expressions statements allowed functions and classes.
- Fix that class expressions were not allowed.
- Added a new next_token() method for checking the look ahead.
- Fix that continue labels could jump to non iterating targets.
- Fix that generator functions cannot be declared in if statements.
2021-09-01 13:39:14 +01:00
davidot
c108c8ff24 LibJS: Disallow yield expression correctly in formal parameters
And add ZERO WIDTH NO BREAK SPACE to valid whitespace.
2021-08-24 07:42:37 +01:00
davidot
7bcffd1b6a LibJS: Fix some small remaining issues with parsing unicode escapes
Added a test to ensure the behavior stays the same.
We now throw on a direct usage of an escaped keywords with a specific
error to make it more clear to the user.
2021-08-24 07:42:37 +01:00
Timothy Flynn
1259dc3623 LibJS: Allow Unicode escape sequences in identifiers
For example, "property.br\u{64}wn" should resolve to "property.brown".

To support this behavior, this commit changes the Token class to hold
both the evaluated identifier name and a view into the original source
for the unevaluated name. There are some contexts in which identifiers
are not allowed to contain Unicode escape sequences; for example, export
statements of the form "export {} from foo.js" forbid escapes in the
identifier "from".

The test file is added to .prettierignore because prettier will replace
all escaped Unicode sequences with their unescaped value.
2021-08-19 23:49:25 +02:00
davidot
4d6502de42 LibJS: Disallow standalone super expression 2021-08-16 23:20:04 +01:00
davidot
a8b25d6c36 LibJS: Handle '++' and '--' more correctly within expression 2021-08-16 23:20:04 +01:00
davidot
5f344f7ca3 LibJS: Check that 'let' is followed by declaration before matching it
Since 'let' is a valid variable name (in non-strict mode) let may not be
the start of a declaration but just an identifier.
2021-08-16 23:20:04 +01:00
davidot
179c48e1a4 LibJS: Add optional extra strict checks in parse_binding_pattern 2021-08-16 23:20:04 +01:00
davidot
f1f338edcd LibJS: Tighten default values in formal parameter parsing
Disallow default parameter for rest parameters.
Disallow yield expressions as default values.
2021-08-16 23:20:04 +01:00
davidot
4989e79c45 LibJS: Allow yielding a class 2021-08-16 23:20:04 +01:00
davidot
19582ccad8 LibJS: Treat yield as an identifier in more non-generator contexts
And disallow some cases where we are in a generator context.
2021-08-16 23:20:04 +01:00
davidot
26177b1826 LibJS: Add more duplicated declarations detection
This is a small step in the right direction although the amount of
different checks is becoming unsustainable. In the future we probably
want to have the current_scope handle all declarations.
2021-08-16 23:20:04 +01:00
davidot
085c7df895 LibJS: Be more strict about the lhs of a for in/of loop
This is not entirely correct as really Object- and ArrayExpressions are
not allowed but that requires a bigger refactoring of for statement
parsing.
2021-08-16 23:20:04 +01:00
davidot
106f9e30d7 LibJS: Force the lexer to parse a regex when expecting a statement 2021-08-16 23:20:04 +01:00