Skip to content

Commit 7696695

Browse files
authored
Class and import related parsing fixes (#356)
* fix computed properties in classes * throw an error when "arguments" is used as the value for a property (… * hacky fix some regex problems which occurred due to different parsers * allow trailing "," in import * allow trailing second "," in import * throw error on deletion of private fields * attributes on import could be a expression * fix super access in methods * many arguments is not invalid any more * bugfix private static class members, fixes #354 * fix property access * updated allow list
1 parent 556a2b5 commit 7696695

File tree

7 files changed

+69
-1423
lines changed

7 files changed

+69
-1423
lines changed

src/Esprima/JavascriptParser.cs

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1700,7 +1700,9 @@ private Import ParseImportCall()
17001700
if (Match(","))
17011701
{
17021702
NextToken();
1703-
attributes = ParseObjectInitializer();
1703+
1704+
if (!Match(")"))
1705+
attributes = ParseAssignmentExpression();
17041706
}
17051707

17061708
_context.IsAssignmentTarget = previousIsAssignmentTarget;
@@ -1711,6 +1713,8 @@ private Import ParseImportCall()
17111713
}
17121714
else
17131715
{
1716+
if (Match(","))
1717+
NextToken();
17141718
this.Expect(")");
17151719
}
17161720

@@ -1787,7 +1791,7 @@ private Expression ParseLeftHandSideExpressionAllowCall()
17871791
: InheritCoverGrammar(_parsePrimaryExpression);
17881792
}
17891793

1790-
if (isSuper && !_context.AllowSuper)
1794+
if (isSuper && !_context.AllowSuper && (!_context.InClassConstructor || (string?) _lookahead.Value != "."))
17911795
{
17921796
TolerateError(Messages.UnexpectedSuper);
17931797
}
@@ -2074,6 +2078,10 @@ private UnaryExpression ParseBasicUnaryExpression()
20742078
{
20752079
TolerateError(Messages.StrictDelete);
20762080
}
2081+
if (_context.Strict && unaryExpr.Operator == UnaryOperator.Delete && unaryExpr.Argument is MemberExpression m && m.Property is PrivateIdentifier)
2082+
{
2083+
TolerateError(Messages.PrivateFieldNoDelete);
2084+
}
20772085

20782086
_context.IsAssignmentTarget = false;
20792087
_context.IsBindingElement = false;
@@ -4715,7 +4723,7 @@ private ClassElement ParseClassElement(ref bool hasConstructor)
47154723
token = _lookahead;
47164724
}
47174725
}
4718-
key = ParseObjectPropertyKey();
4726+
key = ParseObjectPropertyKey(isPrivate);
47194727
}
47204728
else if (Match("{"))
47214729
{
@@ -4770,7 +4778,8 @@ private ClassElement ParseClassElement(ref bool hasConstructor)
47704778
}
47714779

47724780
var lookaheadPropertyKey = QualifiedPropertyName(_lookahead);
4773-
if (token.Type == TokenType.Identifier)
4781+
if (token.Type == TokenType.Identifier ||
4782+
(token.Type == TokenType.Punctuator && (string?) token.Value != "*"))
47744783
{
47754784
if (lookaheadPropertyKey && (string?) token.Value == "get")
47764785
{
@@ -4808,12 +4817,16 @@ private ClassElement ParseClassElement(ref bool hasConstructor)
48084817
else if (!Match("("))
48094818
{
48104819
kind = PropertyKind.Property;
4811-
computed = false;
4812-
4820+
48134821
if (Match("="))
48144822
{
48154823
NextToken();
4824+
if (_lookahead.Type == TokenType.Identifier && (string?)_lookahead.Value == "arguments")
4825+
ThrowUnexpectedToken(token, Messages.ArgumentsNotAllowedInClassField);
4826+
var previousAllowSuper = _context.AllowSuper;
4827+
_context.AllowSuper = true;
48164828
value = IsolateCoverGrammar(_parseAssignmentExpression);
4829+
_context.AllowSuper = previousAllowSuper;
48174830
}
48184831
}
48194832
}
@@ -4834,15 +4847,16 @@ private ClassElement ParseClassElement(ref bool hasConstructor)
48344847
value = ParseGeneratorMethod(isAsync);
48354848
method = true;
48364849
}
4837-
4850+
48384851
if (kind == PropertyKind.None && key != null)
48394852
{
48404853
if (Match("("))
48414854
{
48424855
var previousAllowSuper = _context.AllowSuper;
48434856
var previousInClassConstructor = _context.InClassConstructor;
48444857
_context.InClassConstructor = Equals(token.Value, "constructor");
4845-
_context.AllowSuper = true;
4858+
if (!_context.InClassConstructor)
4859+
_context.AllowSuper = true;
48464860
kind = PropertyKind.Init;
48474861
value = isAsync ? ParsePropertyMethodAsyncFunction(isGenerator) : ParsePropertyMethodFunction(isGenerator);
48484862
_context.InClassConstructor = previousInClassConstructor;
@@ -4942,7 +4956,7 @@ private ClassDeclaration ParseClassDeclarationCore(in Marker node, bool identifi
49424956
var previousStrict = _context.Strict;
49434957
var previousAllowSuper = _context.AllowSuper;
49444958
_context.Strict = true;
4945-
_context.AllowSuper = true;
4959+
_context.AllowSuper = false;
49464960

49474961
ExpectKeyword("class");
49484962

@@ -4955,6 +4969,7 @@ private ClassDeclaration ParseClassDeclarationCore(in Marker node, bool identifi
49554969
{
49564970
NextToken();
49574971
superClass = IsolateCoverGrammar(_parseLeftHandSideExpressionAllowCall);
4972+
_context.AllowSuper = true;
49584973
}
49594974

49604975
var classBody = ParseClassBody();
@@ -4988,7 +5003,7 @@ private ClassExpression ParseClassExpression()
49885003
var previousStrict = _context.Strict;
49895004
var previousAllowSuper = _context.AllowSuper;
49905005
_context.Strict = true;
4991-
_context.AllowSuper = true;
5006+
_context.AllowSuper = false;
49925007

49935008
ExpectKeyword("class");
49945009
var id = _lookahead.Type == TokenType.Identifier
@@ -5000,6 +5015,7 @@ private ClassExpression ParseClassExpression()
50005015
{
50015016
NextToken();
50025017
superClass = IsolateCoverGrammar(_parseLeftHandSideExpressionAllowCall);
5018+
_context.AllowSuper = true;
50035019
}
50045020

50055021
var classBody = ParseClassBody();

src/Esprima/Messages.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// Error messages should be identical to V8.
44
public static class Messages
55
{
6+
public const string ArgumentsNotAllowedInClassField = "'arguments' is not allowed in class field initializer or static initialization block";
67
public const string AsyncFunctionInSingleStatementContext = "Async functions can only be declared at the top level or inside a block.";
78
public const string BadGetterArity = "Getter must not have any formal parameters";
89
public const string BadSetterArity = "Setter must have exactly one formal parameter";
@@ -48,6 +49,7 @@ public static class Messages
4849
public const string NumericSeparatorNotAllowedHere = "Numeric separator is not allowed here";
4950
public const string NumericSeparatorOneUnderscore = "Numeric separator must be exactly one underscore";
5051
public const string ParameterAfterRestParameter = "Rest parameter must be last formal parameter";
52+
public const string PrivateFieldNoDelete = "Private fields can not be deleted";
5153
public const string PropertyAfterRestProperty = "Unexpected token";
5254
public const string Redeclaration = "{0} \"{1}\" has already been declared";
5355
public const string RegexIncompleteQuantifier = "Invalid regular expression: Incomplete quantifier";

src/Esprima/Scanner.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2361,6 +2361,17 @@ internal string EscapeFailingRegex(string pattern)
23612361
pattern = pattern.Replace("[^]", @"[\s\S]");
23622362
}
23632363

2364+
if (pattern.Contains("--"))
2365+
{
2366+
pattern = pattern.Replace("--[", "-[");
2367+
var r = new Regex("--([^\\[\\]]*)");
2368+
pattern = r.Replace(pattern, "-[$1]"); //it should only be replaced when inside of a "[", but for this we need a regex parser.
2369+
}
2370+
2371+
if (pattern.Contains("?<$"))
2372+
{
2373+
pattern = pattern.Replace("?<$", "?<a");
2374+
}
23642375

23652376
// .NET doesn't support [] which should not match any characters (inverse of [^])
23662377
if (pattern.Contains("[]"))

0 commit comments

Comments
 (0)