diff --git a/es2panda/lexer/token/token.cpp b/es2panda/lexer/token/token.cpp index 12521b9dada193b33275e445a53d6700fe3a9e84..ba04e5d974b6ad3ba5311ee9f045d729d15fb55f 100644 --- a/es2panda/lexer/token/token.cpp +++ b/es2panda/lexer/token/token.cpp @@ -92,6 +92,27 @@ bool Token::IsReservedTypeName() const } } +bool Token::IsJsStrictReservedWord() const +{ + switch (keywordType_) + { + case TokenType::KEYW_ARGUMENTS: + case TokenType::KEYW_EVAL: + case TokenType::KEYW_STATIC: + case TokenType::KEYW_PRIVATE: + case TokenType::KEYW_PROTECTED: + case TokenType::KEYW_PUBLIC: + case TokenType::KEYW_IMPLEMENTS: + case TokenType::KEYW_INTERFACE: + case TokenType::KEYW_PACKAGE: + case TokenType::KEYW_LET: + case TokenType::KEYW_YIELD: + return true; + default: + return false; + } +} + bool Token::IsBinaryToken(TokenType type) { return (type >= TokenType::PUNCTUATOR_NULLISH_COALESCING && type <= TokenType::PUNCTUATOR_EXPONENTIATION); diff --git a/es2panda/lexer/token/token.h b/es2panda/lexer/token/token.h index 46a87d432cc1ff7cf96671e75e9391c196b298ae..26edb60d38c145034069ad58cb977c668d3cdd0b 100644 --- a/es2panda/lexer/token/token.h +++ b/es2panda/lexer/token/token.h @@ -116,6 +116,7 @@ public: bool IsPropNameLiteral() const; bool IsKeyword() const; bool IsReservedTypeName() const; + bool IsJsStrictReservedWord() const; static bool IsBinaryToken(TokenType type); static bool IsBinaryLvalueToken(TokenType type); diff --git a/es2panda/parser/expressionParser.cpp b/es2panda/parser/expressionParser.cpp index e66239d1893d2a2d1d6f74b61677e1ce24c94336..46443592412709c21b3abff2a2bbd84a12894dca 100644 --- a/es2panda/parser/expressionParser.cpp +++ b/es2panda/parser/expressionParser.cpp @@ -2339,9 +2339,7 @@ ir::FunctionExpression *ParserImpl::ParseFunctionExpression(ParserStatus newStat ThrowSyntaxError("Expected an identifier."); } - if (lexer_->GetToken().KeywordType() >= lexer::TokenType::KEYW_ARGUMENTS) { - ThrowSyntaxError("Unexpected reserved word in strict mode."); - } + CheckStrictReservedWord(); ident = AllocNode(lexer_->GetToken().Ident(), Allocator()); ident->SetRange(lexer_->GetToken().Loc()); diff --git a/es2panda/parser/parserImpl.cpp b/es2panda/parser/parserImpl.cpp index d3039e2a13f1e9f951552eec55d0d17801a936de..7e415b24808adefa29c660ebefe38bafef6a658e 100644 --- a/es2panda/parser/parserImpl.cpp +++ b/es2panda/parser/parserImpl.cpp @@ -3450,4 +3450,17 @@ void ParserImpl::AddHotfixHelper(util::Hotfix *hotfixHelper) program_.AddHotfixHelper(hotfixHelper); } +void ParserImpl::CheckStrictReservedWord() const +{ + if (Extension() == ScriptExtension::JS) { + if (lexer_->GetToken().IsJsStrictReservedWord()) { + ThrowSyntaxError("Unexpected reserved word in strict mode."); + } + } else { + if (lexer_->GetToken().KeywordType() >= lexer::TokenType::KEYW_ARGUMENTS) { + ThrowSyntaxError("Unexpected reserved word in strict mode."); + } + } +} + } // namespace panda::es2panda::parser diff --git a/es2panda/parser/parserImpl.h b/es2panda/parser/parserImpl.h index 19138ee7a615536b4fad877dbac54e4cc32b94d6..edbee27d3a68699a491fc5723c64d6e12b35f92b 100644 --- a/es2panda/parser/parserImpl.h +++ b/es2panda/parser/parserImpl.h @@ -401,6 +401,7 @@ private: ir::ExportNamedDeclaration *ParseNamedExportDeclaration(const lexer::SourcePosition &startLoc, ArenaVector &&decorators); ir::Identifier *ParseNamedExport(const lexer::Token &exportedToken); + void CheckStrictReservedWord() const; // StatementParser.Cpp diff --git a/es2panda/parser/statementParser.cpp b/es2panda/parser/statementParser.cpp index ffa8688480bf9dd559572bc8f493b5feca1e6889..18e08914fbd78d535c4460e42192a2cdf0f64954 100644 --- a/es2panda/parser/statementParser.cpp +++ b/es2panda/parser/statementParser.cpp @@ -1009,8 +1009,8 @@ ir::FunctionDeclaration *ParserImpl::ParseFunctionDeclaration(bool canBeAnonymou ThrowSyntaxError("Unexpected token, expected identifier after 'function' keyword"); } - if (!isDeclare && lexer_->GetToken().KeywordType() >= lexer::TokenType::KEYW_ARGUMENTS) { - ThrowSyntaxError("Unexpected reserved word in strict mode."); + if (!isDeclare) { + CheckStrictReservedWord(); } util::StringView ident = lexer_->GetToken().Ident(); diff --git a/es2panda/test/parser/js/function-declaration-arguments-expected.txt b/es2panda/test/parser/js/function-declaration-arguments-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..5ee5461ec9d9a0632d94deac1050458376799244 --- /dev/null +++ b/es2panda/test/parser/js/function-declaration-arguments-expected.txt @@ -0,0 +1 @@ +SyntaxError: Unexpected reserved word in strict mode. [function-declaration-arguments.js:3:10] diff --git a/es2panda/test/parser/js/function-declaration-arguments.js b/es2panda/test/parser/js/function-declaration-arguments.js new file mode 100644 index 0000000000000000000000000000000000000000..696c3c46cf097193965322d2101d3f0ccf650443 --- /dev/null +++ b/es2panda/test/parser/js/function-declaration-arguments.js @@ -0,0 +1,4 @@ +'use strict' + +function arguments() { +} \ No newline at end of file diff --git a/es2panda/test/parser/js/function-declaration-is-expected.txt b/es2panda/test/parser/js/function-declaration-is-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..140342c6b1a04d087e62b5799ade691a9aa44e6c --- /dev/null +++ b/es2panda/test/parser/js/function-declaration-is-expected.txt @@ -0,0 +1,101 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "StringLiteral", + "value": "use strict", + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 13 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 13 + } + } + }, + { + "type": "FunctionDeclaration", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "is", + "decorators": [], + "loc": { + "start": { + "line": 3, + "column": 10 + }, + "end": { + "line": 3, + "column": 12 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 3, + "column": 15 + }, + "end": { + "line": 4, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 3, + "column": 1 + }, + "end": { + "line": 4, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 3, + "column": 1 + }, + "end": { + "line": 4, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 4, + "column": 2 + } + } +} diff --git a/es2panda/test/parser/js/function-declaration-is.js b/es2panda/test/parser/js/function-declaration-is.js new file mode 100644 index 0000000000000000000000000000000000000000..6db6828316a80508538543c88e762699f08f1fab --- /dev/null +++ b/es2panda/test/parser/js/function-declaration-is.js @@ -0,0 +1,4 @@ +'use strict' + +function is() { +} \ No newline at end of file diff --git a/es2panda/test/parser/js/function-expression-arguments-expected.txt b/es2panda/test/parser/js/function-expression-arguments-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..18614316457858353ffd6231b62d24eceb02420f --- /dev/null +++ b/es2panda/test/parser/js/function-expression-arguments-expected.txt @@ -0,0 +1 @@ +SyntaxError: Unexpected reserved word in strict mode. [function-expression-arguments.js:3:20] diff --git a/es2panda/test/parser/js/function-expression-arguments.js b/es2panda/test/parser/js/function-expression-arguments.js new file mode 100644 index 0000000000000000000000000000000000000000..a8d93883a738a123e32bdac8dae4d75a36bd3e13 --- /dev/null +++ b/es2panda/test/parser/js/function-expression-arguments.js @@ -0,0 +1,4 @@ +'use strict' + +let foo = function arguments() { +} \ No newline at end of file diff --git a/es2panda/test/parser/js/function-expression-is-expected.txt b/es2panda/test/parser/js/function-expression-is-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..25297cebbb5a3da2e9283283780e3aefcc896f04 --- /dev/null +++ b/es2panda/test/parser/js/function-expression-is-expected.txt @@ -0,0 +1,145 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "StringLiteral", + "value": "use strict", + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 13 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 13 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "foo", + "decorators": [], + "loc": { + "start": { + "line": 3, + "column": 5 + }, + "end": { + "line": 3, + "column": 8 + } + } + }, + "init": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "is", + "decorators": [], + "loc": { + "start": { + "line": 3, + "column": 20 + }, + "end": { + "line": 3, + "column": 22 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 3, + "column": 25 + }, + "end": { + "line": 4, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 3, + "column": 11 + }, + "end": { + "line": 4, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 3, + "column": 11 + }, + "end": { + "line": 4, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 3, + "column": 5 + }, + "end": { + "line": 4, + "column": 2 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 3, + "column": 1 + }, + "end": { + "line": 4, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 4, + "column": 2 + } + } +} diff --git a/es2panda/test/parser/js/function-expression-is.js b/es2panda/test/parser/js/function-expression-is.js new file mode 100644 index 0000000000000000000000000000000000000000..6b90fce307144be5bfa55f0766d50ff1ae3fc54e --- /dev/null +++ b/es2panda/test/parser/js/function-expression-is.js @@ -0,0 +1,4 @@ +'use strict' + +let foo = function is() { +} \ No newline at end of file