Changeset 187890 in webkit
- Timestamp:
- Aug 4, 2015, 2:26:49 PM (9 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 23 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified trunk/LayoutTests/ChangeLog ¶
r187886 r187890 1 2015-08-04 Yusuke Suzuki <utatane.tea@gmail.com> 2 3 [ES6] Support Module Syntax 4 https://bugs.webkit.org/show_bug.cgi?id=147422 5 6 Reviewed by Saam Barati. 7 8 'export' and 'import' are changed from FutureReservedWord to Keyword in ES6. 9 http://www.ecma-international.org/ecma-262/6.0/#sec-keywords 10 And restrict 'super' use under the Script / Module contexts. 11 12 * js/dom/reserved-words-as-property-expected.txt: 13 * sputnik/Conformance/07_Lexical_Conventions/7.5_Tokens/7.5.3_Future_Reserved_Words/S7.5.3_A1.10-expected.txt: 14 * sputnik/Conformance/07_Lexical_Conventions/7.5_Tokens/7.5.3_Future_Reserved_Words/S7.5.3_A1.16-expected.txt: 15 * sputnik/Conformance/07_Lexical_Conventions/7.5_Tokens/7.5.3_Future_Reserved_Words/S7.5.3_A1.27-expected.txt: 16 1 17 2015-08-04 Alexey Proskuryakov <ap@apple.com> 2 18 -
TabularUnified trunk/LayoutTests/js/dom/reserved-words-as-property-expected.txt ¶
r186860 r187890 1156 1156 PASS "use strict";({ get enum(){}, set enum(x){}, parsedOkay: 42 }.parsedOkay === 42) is true 1157 1157 PASS (function(){"use strict";({ get enum(){}, set enum(x){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true 1158 PASS var export; true threw exception SyntaxError: Cannot use the reservedword 'export' as a variable name..1159 PASS (function(){var export; true}); true threw exception SyntaxError: Cannot use the reservedword 'export' as a variable name..1160 PASS var export = 42; export === 42 threw exception SyntaxError: Cannot use the reservedword 'export' as a variable name..1161 PASS (function(){var export = 42; export === 42}); true threw exception SyntaxError: Cannot use the reservedword 'export' as a variable name..1162 PASS function g(export){ }; true threw exception SyntaxError: Cannot use the reservedword 'export' as a variable name..1163 PASS (function(){function g(export){ }; true}); true threw exception SyntaxError: Cannot use the reservedword 'export' as a variable name..1164 PASS /export/.test(function g(export){ }) threw exception SyntaxError: Cannot use the reservedword 'export' as a variable name..1165 PASS (function(){/export/.test(function g(export){ })}); true threw exception SyntaxError: Cannot use the reservedword 'export' as a variable name..1166 PASS try{}catch(export){}; true threw exception SyntaxError: Cannot use the reservedword 'export' as a catch variable name..1167 PASS (function(){try{}catch(export){}; true}); true threw exception SyntaxError: Cannot use the reservedword 'export' as a catch variable name..1168 PASS function export(){ }; true threw exception SyntaxError: Cannot use the reservedword 'export' as a function name..1169 PASS (function(){function export(){ }; true}); true threw exception SyntaxError: Cannot use the reservedword 'export' as a function name..1158 PASS var export; true threw exception SyntaxError: Cannot use the keyword 'export' as a variable name.. 1159 PASS (function(){var export; true}); true threw exception SyntaxError: Cannot use the keyword 'export' as a variable name.. 1160 PASS var export = 42; export === 42 threw exception SyntaxError: Cannot use the keyword 'export' as a variable name.. 1161 PASS (function(){var export = 42; export === 42}); true threw exception SyntaxError: Cannot use the keyword 'export' as a variable name.. 1162 PASS function g(export){ }; true threw exception SyntaxError: Cannot use the keyword 'export' as a variable name.. 1163 PASS (function(){function g(export){ }; true}); true threw exception SyntaxError: Cannot use the keyword 'export' as a variable name.. 1164 PASS /export/.test(function g(export){ }) threw exception SyntaxError: Cannot use the keyword 'export' as a variable name.. 1165 PASS (function(){/export/.test(function g(export){ })}); true threw exception SyntaxError: Cannot use the keyword 'export' as a variable name.. 1166 PASS try{}catch(export){}; true threw exception SyntaxError: Cannot use the keyword 'export' as a catch variable name.. 1167 PASS (function(){try{}catch(export){}; true}); true threw exception SyntaxError: Cannot use the keyword 'export' as a catch variable name.. 1168 PASS function export(){ }; true threw exception SyntaxError: Cannot use the keyword 'export' as a function name.. 1169 PASS (function(){function export(){ }; true}); true threw exception SyntaxError: Cannot use the keyword 'export' as a function name.. 1170 1170 PASS ({ "export": 42 }.export === 42) is true 1171 1171 PASS (function(){({ "export": 42 }.export === 42)}); true is true … … 1174 1174 PASS ({ get export(){}, set export(x){}, parsedOkay: 42 }.parsedOkay === 42) is true 1175 1175 PASS (function(){({ get export(){}, set export(x){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true 1176 PASS "use strict";var export; true threw exception SyntaxError: Cannot use the reservedword 'export' as a variable name..1177 PASS (function(){"use strict";var export; true}); true threw exception SyntaxError: Cannot use the reservedword 'export' as a variable name..1178 PASS "use strict";var export = 42; export === 42 threw exception SyntaxError: Cannot use the reservedword 'export' as a variable name..1179 PASS (function(){"use strict";var export = 42; export === 42}); true threw exception SyntaxError: Cannot use the reservedword 'export' as a variable name..1180 PASS "use strict";function g(export){ "use strict"; }; true threw exception SyntaxError: Cannot use the reservedword 'export' as a variable name..1181 PASS (function(){"use strict";function g(export){ "use strict"; }; true}); true threw exception SyntaxError: Cannot use the reservedword 'export' as a variable name..1182 PASS "use strict";/export/.test(function g(export){ "use strict"; }) threw exception SyntaxError: Cannot use the reservedword 'export' as a variable name..1183 PASS (function(){"use strict";/export/.test(function g(export){ "use strict"; })}); true threw exception SyntaxError: Cannot use the reservedword 'export' as a variable name..1184 PASS "use strict";try{}catch(export){}; true threw exception SyntaxError: Cannot use the reservedword 'export' as a catch variable name..1185 PASS (function(){"use strict";try{}catch(export){}; true}); true threw exception SyntaxError: Cannot use the reservedword 'export' as a catch variable name..1186 PASS "use strict";function export(){ "use strict"; }; true threw exception SyntaxError: Cannot use the reservedword 'export' as a function name..1187 PASS (function(){"use strict";function export(){ "use strict"; }; true}); true threw exception SyntaxError: Cannot use the reservedword 'export' as a function name..1176 PASS "use strict";var export; true threw exception SyntaxError: Cannot use the keyword 'export' as a variable name.. 1177 PASS (function(){"use strict";var export; true}); true threw exception SyntaxError: Cannot use the keyword 'export' as a variable name.. 1178 PASS "use strict";var export = 42; export === 42 threw exception SyntaxError: Cannot use the keyword 'export' as a variable name.. 1179 PASS (function(){"use strict";var export = 42; export === 42}); true threw exception SyntaxError: Cannot use the keyword 'export' as a variable name.. 1180 PASS "use strict";function g(export){ "use strict"; }; true threw exception SyntaxError: Cannot use the keyword 'export' as a variable name.. 1181 PASS (function(){"use strict";function g(export){ "use strict"; }; true}); true threw exception SyntaxError: Cannot use the keyword 'export' as a variable name.. 1182 PASS "use strict";/export/.test(function g(export){ "use strict"; }) threw exception SyntaxError: Cannot use the keyword 'export' as a variable name.. 1183 PASS (function(){"use strict";/export/.test(function g(export){ "use strict"; })}); true threw exception SyntaxError: Cannot use the keyword 'export' as a variable name.. 1184 PASS "use strict";try{}catch(export){}; true threw exception SyntaxError: Cannot use the keyword 'export' as a catch variable name.. 1185 PASS (function(){"use strict";try{}catch(export){}; true}); true threw exception SyntaxError: Cannot use the keyword 'export' as a catch variable name.. 1186 PASS "use strict";function export(){ "use strict"; }; true threw exception SyntaxError: Cannot use the keyword 'export' as a function name.. 1187 PASS (function(){"use strict";function export(){ "use strict"; }; true}); true threw exception SyntaxError: Cannot use the keyword 'export' as a function name.. 1188 1188 PASS "use strict";({ "export": 42 }.export === 42) is true 1189 1189 PASS (function(){"use strict";({ "export": 42 }.export === 42)}); true is true … … 1228 1228 PASS "use strict";({ get extends(){}, set extends(x){}, parsedOkay: 42 }.parsedOkay === 42) is true 1229 1229 PASS (function(){"use strict";({ get extends(){}, set extends(x){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true 1230 PASS var import; true threw exception SyntaxError: Cannot use the reservedword 'import' as a variable name..1231 PASS (function(){var import; true}); true threw exception SyntaxError: Cannot use the reservedword 'import' as a variable name..1232 PASS var import = 42; import === 42 threw exception SyntaxError: Cannot use the reservedword 'import' as a variable name..1233 PASS (function(){var import = 42; import === 42}); true threw exception SyntaxError: Cannot use the reservedword 'import' as a variable name..1234 PASS function g(import){ }; true threw exception SyntaxError: Cannot use the reservedword 'import' as a variable name..1235 PASS (function(){function g(import){ }; true}); true threw exception SyntaxError: Cannot use the reservedword 'import' as a variable name..1236 PASS /import/.test(function g(import){ }) threw exception SyntaxError: Cannot use the reservedword 'import' as a variable name..1237 PASS (function(){/import/.test(function g(import){ })}); true threw exception SyntaxError: Cannot use the reservedword 'import' as a variable name..1238 PASS try{}catch(import){}; true threw exception SyntaxError: Cannot use the reservedword 'import' as a catch variable name..1239 PASS (function(){try{}catch(import){}; true}); true threw exception SyntaxError: Cannot use the reservedword 'import' as a catch variable name..1240 PASS function import(){ }; true threw exception SyntaxError: Cannot use the reservedword 'import' as a function name..1241 PASS (function(){function import(){ }; true}); true threw exception SyntaxError: Cannot use the reservedword 'import' as a function name..1230 PASS var import; true threw exception SyntaxError: Cannot use the keyword 'import' as a variable name.. 1231 PASS (function(){var import; true}); true threw exception SyntaxError: Cannot use the keyword 'import' as a variable name.. 1232 PASS var import = 42; import === 42 threw exception SyntaxError: Cannot use the keyword 'import' as a variable name.. 1233 PASS (function(){var import = 42; import === 42}); true threw exception SyntaxError: Cannot use the keyword 'import' as a variable name.. 1234 PASS function g(import){ }; true threw exception SyntaxError: Cannot use the keyword 'import' as a variable name.. 1235 PASS (function(){function g(import){ }; true}); true threw exception SyntaxError: Cannot use the keyword 'import' as a variable name.. 1236 PASS /import/.test(function g(import){ }) threw exception SyntaxError: Cannot use the keyword 'import' as a variable name.. 1237 PASS (function(){/import/.test(function g(import){ })}); true threw exception SyntaxError: Cannot use the keyword 'import' as a variable name.. 1238 PASS try{}catch(import){}; true threw exception SyntaxError: Cannot use the keyword 'import' as a catch variable name.. 1239 PASS (function(){try{}catch(import){}; true}); true threw exception SyntaxError: Cannot use the keyword 'import' as a catch variable name.. 1240 PASS function import(){ }; true threw exception SyntaxError: Cannot use the keyword 'import' as a function name.. 1241 PASS (function(){function import(){ }; true}); true threw exception SyntaxError: Cannot use the keyword 'import' as a function name.. 1242 1242 PASS ({ "import": 42 }.import === 42) is true 1243 1243 PASS (function(){({ "import": 42 }.import === 42)}); true is true … … 1246 1246 PASS ({ get import(){}, set import(x){}, parsedOkay: 42 }.parsedOkay === 42) is true 1247 1247 PASS (function(){({ get import(){}, set import(x){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true 1248 PASS "use strict";var import; true threw exception SyntaxError: Cannot use the reservedword 'import' as a variable name..1249 PASS (function(){"use strict";var import; true}); true threw exception SyntaxError: Cannot use the reservedword 'import' as a variable name..1250 PASS "use strict";var import = 42; import === 42 threw exception SyntaxError: Cannot use the reservedword 'import' as a variable name..1251 PASS (function(){"use strict";var import = 42; import === 42}); true threw exception SyntaxError: Cannot use the reservedword 'import' as a variable name..1252 PASS "use strict";function g(import){ "use strict"; }; true threw exception SyntaxError: Cannot use the reservedword 'import' as a variable name..1253 PASS (function(){"use strict";function g(import){ "use strict"; }; true}); true threw exception SyntaxError: Cannot use the reservedword 'import' as a variable name..1254 PASS "use strict";/import/.test(function g(import){ "use strict"; }) threw exception SyntaxError: Cannot use the reservedword 'import' as a variable name..1255 PASS (function(){"use strict";/import/.test(function g(import){ "use strict"; })}); true threw exception SyntaxError: Cannot use the reservedword 'import' as a variable name..1256 PASS "use strict";try{}catch(import){}; true threw exception SyntaxError: Cannot use the reservedword 'import' as a catch variable name..1257 PASS (function(){"use strict";try{}catch(import){}; true}); true threw exception SyntaxError: Cannot use the reservedword 'import' as a catch variable name..1258 PASS "use strict";function import(){ "use strict"; }; true threw exception SyntaxError: Cannot use the reservedword 'import' as a function name..1259 PASS (function(){"use strict";function import(){ "use strict"; }; true}); true threw exception SyntaxError: Cannot use the reservedword 'import' as a function name..1248 PASS "use strict";var import; true threw exception SyntaxError: Cannot use the keyword 'import' as a variable name.. 1249 PASS (function(){"use strict";var import; true}); true threw exception SyntaxError: Cannot use the keyword 'import' as a variable name.. 1250 PASS "use strict";var import = 42; import === 42 threw exception SyntaxError: Cannot use the keyword 'import' as a variable name.. 1251 PASS (function(){"use strict";var import = 42; import === 42}); true threw exception SyntaxError: Cannot use the keyword 'import' as a variable name.. 1252 PASS "use strict";function g(import){ "use strict"; }; true threw exception SyntaxError: Cannot use the keyword 'import' as a variable name.. 1253 PASS (function(){"use strict";function g(import){ "use strict"; }; true}); true threw exception SyntaxError: Cannot use the keyword 'import' as a variable name.. 1254 PASS "use strict";/import/.test(function g(import){ "use strict"; }) threw exception SyntaxError: Cannot use the keyword 'import' as a variable name.. 1255 PASS (function(){"use strict";/import/.test(function g(import){ "use strict"; })}); true threw exception SyntaxError: Cannot use the keyword 'import' as a variable name.. 1256 PASS "use strict";try{}catch(import){}; true threw exception SyntaxError: Cannot use the keyword 'import' as a catch variable name.. 1257 PASS (function(){"use strict";try{}catch(import){}; true}); true threw exception SyntaxError: Cannot use the keyword 'import' as a catch variable name.. 1258 PASS "use strict";function import(){ "use strict"; }; true threw exception SyntaxError: Cannot use the keyword 'import' as a function name.. 1259 PASS (function(){"use strict";function import(){ "use strict"; }; true}); true threw exception SyntaxError: Cannot use the keyword 'import' as a function name.. 1260 1260 PASS "use strict";({ "import": 42 }.import === 42) is true 1261 1261 PASS (function(){"use strict";({ "import": 42 }.import === 42)}); true is true -
TabularUnified trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.5_Tokens/7.5.3_Future_Reserved_Words/S7.5.3_A1.10-expected.txt ¶
r158014 r187890 1 CONSOLE MESSAGE: line 76: SyntaxError: Unexpected use of reservedword 'export'1 CONSOLE MESSAGE: line 76: SyntaxError: Unexpected keyword 'export' 2 2 S7.5.3_A1.10 3 3 -
TabularUnified trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.5_Tokens/7.5.3_Future_Reserved_Words/S7.5.3_A1.16-expected.txt ¶
r158014 r187890 1 CONSOLE MESSAGE: line 76: SyntaxError: Unexpected use of reservedword 'import'1 CONSOLE MESSAGE: line 76: SyntaxError: Unexpected keyword 'import' 2 2 S7.5.3_A1.16 3 3 -
TabularUnified trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.5_Tokens/7.5.3_Future_Reserved_Words/S7.5.3_A1.27-expected.txt ¶
r181618 r187890 1 CONSOLE MESSAGE: line 76: SyntaxError: Cannot reference super.1 CONSOLE MESSAGE: line 76: SyntaxError: super is only valid inside functions. 2 2 S7.5.3_A1.27 3 3 -
TabularUnified trunk/Source/JavaScriptCore/ChangeLog ¶
r187819 r187890 1 2015-08-04 Yusuke Suzuki <utatane.tea@gmail.com> 2 3 [ES6] Support Module Syntax 4 https://bugs.webkit.org/show_bug.cgi?id=147422 5 6 Reviewed by Saam Barati. 7 8 This patch introduces ES6 Modules syntax parsing part. 9 In this patch, ASTBuilder just produces the corresponding nodes to the ES6 Modules syntax, 10 and this patch does not include the code generator part. 11 12 Modules require 2 phase parsing. In the first pass, we just analyze the dependent modules 13 and do not execute the body or construct the AST. And after analyzing all the dependent 14 modules, we will parse the dependent modules next. 15 After all analyzing part is done, we will start the second pass. In the second pass, we 16 will parse the module, produce the AST, and execute the body. 17 If we don't do so, we need to create all the ASTs in the module's dependent graph at first 18 because the given module can be executed after the all dependent modules are executed. It 19 means that we need to hold so many parser arenas. To avoid this, the first pass only extracts 20 the dependent modules' information. 21 22 In this patch, we don't add this analyzing part yet. This patch only implements the second pass. 23 This patch aims at just implementing the syntax parsing functionality correctly. 24 After this patch is landed, we will create the ModuleDependencyAnalyzer that inherits SyntaxChecker 25 to collect the dependent modules fast[1]. 26 27 To test the parsing, we added the "checkModuleSyntax" function into jsc shell. 28 By using this, we can parse the given string as the module. 29 30 [1]: https://bugs.webkit.org/show_bug.cgi?id=147353 31 32 * bytecompiler/NodesCodegen.cpp: 33 (JSC::ModuleProgramNode::emitBytecode): 34 (JSC::ImportDeclarationNode::emitBytecode): 35 (JSC::ExportAllDeclarationNode::emitBytecode): 36 (JSC::ExportDefaultDeclarationNode::emitBytecode): 37 (JSC::ExportLocalDeclarationNode::emitBytecode): 38 (JSC::ExportNamedDeclarationNode::emitBytecode): 39 * jsc.cpp: 40 (GlobalObject::finishCreation): 41 (functionCheckModuleSyntax): 42 * parser/ASTBuilder.h: 43 (JSC::ASTBuilder::createModuleSpecifier): 44 (JSC::ASTBuilder::createImportSpecifier): 45 (JSC::ASTBuilder::createImportSpecifierList): 46 (JSC::ASTBuilder::appendImportSpecifier): 47 (JSC::ASTBuilder::createImportDeclaration): 48 (JSC::ASTBuilder::createExportAllDeclaration): 49 (JSC::ASTBuilder::createExportDefaultDeclaration): 50 (JSC::ASTBuilder::createExportLocalDeclaration): 51 (JSC::ASTBuilder::createExportNamedDeclaration): 52 (JSC::ASTBuilder::createExportSpecifier): 53 (JSC::ASTBuilder::createExportSpecifierList): 54 (JSC::ASTBuilder::appendExportSpecifier): 55 * parser/Keywords.table: 56 * parser/NodeConstructors.h: 57 (JSC::ModuleSpecifierNode::ModuleSpecifierNode): 58 (JSC::ImportSpecifierNode::ImportSpecifierNode): 59 (JSC::ImportDeclarationNode::ImportDeclarationNode): 60 (JSC::ExportAllDeclarationNode::ExportAllDeclarationNode): 61 (JSC::ExportDefaultDeclarationNode::ExportDefaultDeclarationNode): 62 (JSC::ExportLocalDeclarationNode::ExportLocalDeclarationNode): 63 (JSC::ExportNamedDeclarationNode::ExportNamedDeclarationNode): 64 (JSC::ExportSpecifierNode::ExportSpecifierNode): 65 * parser/Nodes.cpp: 66 (JSC::ModuleProgramNode::ModuleProgramNode): 67 * parser/Nodes.h: 68 (JSC::ModuleProgramNode::startColumn): 69 (JSC::ModuleProgramNode::endColumn): 70 (JSC::ModuleSpecifierNode::moduleName): 71 (JSC::ImportSpecifierNode::importedName): 72 (JSC::ImportSpecifierNode::localName): 73 (JSC::ImportSpecifierListNode::specifiers): 74 (JSC::ImportSpecifierListNode::append): 75 (JSC::ImportDeclarationNode::specifierList): 76 (JSC::ImportDeclarationNode::moduleSpecifier): 77 (JSC::ExportAllDeclarationNode::moduleSpecifier): 78 (JSC::ExportDefaultDeclarationNode::declaration): 79 (JSC::ExportLocalDeclarationNode::declaration): 80 (JSC::ExportSpecifierNode::exportedName): 81 (JSC::ExportSpecifierNode::localName): 82 (JSC::ExportSpecifierListNode::specifiers): 83 (JSC::ExportSpecifierListNode::append): 84 (JSC::ExportNamedDeclarationNode::specifierList): 85 (JSC::ExportNamedDeclarationNode::moduleSpecifier): 86 * parser/Parser.cpp: 87 (JSC::Parser<LexerType>::Parser): 88 (JSC::Parser<LexerType>::parseInner): 89 (JSC::Parser<LexerType>::parseModuleSourceElements): 90 (JSC::Parser<LexerType>::parseVariableDeclaration): 91 (JSC::Parser<LexerType>::parseVariableDeclarationList): 92 (JSC::Parser<LexerType>::createBindingPattern): 93 (JSC::Parser<LexerType>::tryParseDestructuringPatternExpression): 94 (JSC::Parser<LexerType>::parseDestructuringPattern): 95 (JSC::Parser<LexerType>::parseForStatement): 96 (JSC::Parser<LexerType>::parseFormalParameters): 97 (JSC::Parser<LexerType>::parseFunctionParameters): 98 (JSC::Parser<LexerType>::parseFunctionDeclaration): 99 (JSC::Parser<LexerType>::parseClassDeclaration): 100 (JSC::Parser<LexerType>::parseModuleSpecifier): 101 (JSC::Parser<LexerType>::parseImportClauseItem): 102 (JSC::Parser<LexerType>::parseImportDeclaration): 103 (JSC::Parser<LexerType>::parseExportSpecifier): 104 (JSC::Parser<LexerType>::parseExportDeclaration): 105 (JSC::Parser<LexerType>::parseMemberExpression): 106 * parser/Parser.h: 107 (JSC::isIdentifierOrKeyword): 108 (JSC::ModuleScopeData::create): 109 (JSC::ModuleScopeData::exportedBindings): 110 (JSC::ModuleScopeData::exportName): 111 (JSC::ModuleScopeData::exportBinding): 112 (JSC::Scope::Scope): 113 (JSC::Scope::setIsModule): 114 (JSC::Scope::moduleScopeData): 115 (JSC::Parser::matchContextualKeyword): 116 (JSC::Parser::matchIdentifierOrKeyword): 117 (JSC::Parser::isofToken): Deleted. 118 * parser/ParserModes.h: 119 * parser/ParserTokens.h: 120 * parser/SyntaxChecker.h: 121 (JSC::SyntaxChecker::createModuleSpecifier): 122 (JSC::SyntaxChecker::createImportSpecifier): 123 (JSC::SyntaxChecker::createImportSpecifierList): 124 (JSC::SyntaxChecker::appendImportSpecifier): 125 (JSC::SyntaxChecker::createImportDeclaration): 126 (JSC::SyntaxChecker::createExportAllDeclaration): 127 (JSC::SyntaxChecker::createExportDefaultDeclaration): 128 (JSC::SyntaxChecker::createExportLocalDeclaration): 129 (JSC::SyntaxChecker::createExportNamedDeclaration): 130 (JSC::SyntaxChecker::createExportSpecifier): 131 (JSC::SyntaxChecker::createExportSpecifierList): 132 (JSC::SyntaxChecker::appendExportSpecifier): 133 * runtime/CommonIdentifiers.cpp: 134 (JSC::CommonIdentifiers::CommonIdentifiers): 135 * runtime/CommonIdentifiers.h: 136 * runtime/Completion.cpp: 137 (JSC::checkModuleSyntax): 138 * runtime/Completion.h: 139 * tests/stress/modules-syntax-error-with-names.js: Added. 140 (shouldThrow): 141 * tests/stress/modules-syntax-error.js: Added. 142 (shouldThrow): 143 (checkModuleSyntaxError.checkModuleSyntaxError.checkModuleSyntaxError): 144 * tests/stress/modules-syntax.js: Added. 145 (prototype.checkModuleSyntax): 146 (checkModuleSyntax): 147 * tests/stress/tagged-templates-syntax.js: 148 1 149 2015-08-03 Csaba Osztrogonác <ossy@webkit.org> 2 150 -
TabularUnified trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp ¶
r187524 r187890 2889 2889 } 2890 2890 2891 // ------------------------------ ModuleProgramNode -------------------- 2892 2893 void ModuleProgramNode::emitBytecode(BytecodeGenerator&, RegisterID*) 2894 { 2895 } 2896 2891 2897 // ------------------------------ EvalNode ----------------------------- 2892 2898 … … 3039 3045 } 3040 3046 #endif 3041 3047 3048 // ------------------------------ ImportDeclarationNode ----------------------- 3049 3050 void ImportDeclarationNode::emitBytecode(BytecodeGenerator&, RegisterID*) 3051 { 3052 } 3053 3054 // ------------------------------ ExportAllDeclarationNode -------------------- 3055 3056 void ExportAllDeclarationNode::emitBytecode(BytecodeGenerator&, RegisterID*) 3057 { 3058 } 3059 3060 // ------------------------------ ExportDefaultDeclarationNode ---------------- 3061 3062 void ExportDefaultDeclarationNode::emitBytecode(BytecodeGenerator&, RegisterID*) 3063 { 3064 } 3065 3066 // ------------------------------ ExportLocalDeclarationNode ------------------ 3067 3068 void ExportLocalDeclarationNode::emitBytecode(BytecodeGenerator&, RegisterID*) 3069 { 3070 } 3071 3072 // ------------------------------ ExportNamedDeclarationNode ------------------ 3073 3074 void ExportNamedDeclarationNode::emitBytecode(BytecodeGenerator&, RegisterID*) 3075 { 3076 } 3077 3042 3078 // ------------------------------ DestructuringAssignmentNode ----------------- 3043 3079 RegisterID* DestructuringAssignmentNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) -
TabularUnified trunk/Source/JavaScriptCore/jsc.cpp ¶
r187677 r187890 498 498 static EncodedJSValue JSC_HOST_CALL functionLoadWebAssembly(ExecState*); 499 499 #endif 500 #if ENABLE(ES6_MODULES) 501 static EncodedJSValue JSC_HOST_CALL functionCheckModuleSyntax(ExecState*); 502 #endif 500 503 501 504 #if ENABLE(SAMPLING_FLAGS) … … 664 667 addFunction(vm, "loadWebAssembly", functionLoadWebAssembly, 1); 665 668 #endif 669 #if ENABLE(ES6_MODULES) 670 addFunction(vm, "checkModuleSyntax", functionCheckModuleSyntax, 1); 671 #endif 666 672 667 673 JSArray* array = constructEmptyArray(globalExec(), 0); … … 1207 1213 return JSValue::encode(exec->vm().throwException(exec, createSyntaxError(exec, errorMessage))); 1208 1214 return JSValue::encode(module); 1215 } 1216 #endif 1217 1218 #if ENABLE(ES6_MODULES) 1219 EncodedJSValue JSC_HOST_CALL functionCheckModuleSyntax(ExecState* exec) 1220 { 1221 String source = exec->argument(0).toString(exec)->value(exec); 1222 1223 StopWatch stopWatch; 1224 stopWatch.start(); 1225 1226 ParserError error; 1227 bool validSyntax = checkModuleSyntax(exec->vm(), makeSource(source), error); 1228 stopWatch.stop(); 1229 1230 if (!validSyntax) 1231 exec->vm().throwException(exec, jsNontrivialString(exec, toString("SyntaxError: ", error.message(), ":", error.line()))); 1232 return JSValue::encode(jsNumber(stopWatch.getElapsedMS())); 1209 1233 } 1210 1234 #endif -
TabularUnified trunk/Source/JavaScriptCore/parser/ASTBuilder.h ¶
r187760 r187890 114 114 typedef ClassExprNode* ClassExpression; 115 115 #endif 116 typedef ModuleSpecifierNode* ModuleSpecifier; 117 typedef ImportSpecifierNode* ImportSpecifier; 118 typedef ImportSpecifierListNode* ImportSpecifierList; 119 typedef ExportSpecifierNode* ExportSpecifier; 120 typedef ExportSpecifierListNode* ExportSpecifierList; 116 121 typedef StatementNode* Statement; 117 122 typedef ClauseListNode* ClauseList; … … 615 620 return result; 616 621 } 617 622 623 ModuleSpecifierNode* createModuleSpecifier(const JSTokenLocation& location, const Identifier& moduleName) 624 { 625 return new (m_parserArena) ModuleSpecifierNode(location, moduleName); 626 } 627 628 ImportSpecifierNode* createImportSpecifier(const JSTokenLocation& location, const Identifier& importedName, const Identifier& localName) 629 { 630 return new (m_parserArena) ImportSpecifierNode(location, importedName, localName); 631 } 632 633 ImportSpecifierListNode* createImportSpecifierList() 634 { 635 return new (m_parserArena) ImportSpecifierListNode(); 636 } 637 638 void appendImportSpecifier(ImportSpecifierListNode* specifierList, ImportSpecifierNode* specifier) 639 { 640 specifierList->append(specifier); 641 } 642 643 StatementNode* createImportDeclaration(const JSTokenLocation& location, ImportSpecifierListNode* importSpecifierList, ModuleSpecifierNode* moduleSpecifier) 644 { 645 return new (m_parserArena) ImportDeclarationNode(location, importSpecifierList, moduleSpecifier); 646 } 647 648 StatementNode* createExportAllDeclaration(const JSTokenLocation& location, ModuleSpecifierNode* moduleSpecifier) 649 { 650 return new (m_parserArena) ExportAllDeclarationNode(location, moduleSpecifier); 651 } 652 653 StatementNode* createExportDefaultDeclaration(const JSTokenLocation& location, StatementNode* declaration) 654 { 655 return new (m_parserArena) ExportDefaultDeclarationNode(location, declaration); 656 } 657 658 StatementNode* createExportLocalDeclaration(const JSTokenLocation& location, StatementNode* declaration) 659 { 660 return new (m_parserArena) ExportLocalDeclarationNode(location, declaration); 661 } 662 663 StatementNode* createExportNamedDeclaration(const JSTokenLocation& location, ExportSpecifierListNode* exportSpecifierList, ModuleSpecifierNode* moduleSpecifier) 664 { 665 return new (m_parserArena) ExportNamedDeclarationNode(location, exportSpecifierList, moduleSpecifier); 666 } 667 668 ExportSpecifierNode* createExportSpecifier(const JSTokenLocation& location, const Identifier& localName, const Identifier& exportedName) 669 { 670 return new (m_parserArena) ExportSpecifierNode(location, localName, exportedName); 671 } 672 673 ExportSpecifierListNode* createExportSpecifierList() 674 { 675 return new (m_parserArena) ExportSpecifierListNode(); 676 } 677 678 void appendExportSpecifier(ExportSpecifierListNode* specifierList, ExportSpecifierNode* specifier) 679 { 680 specifierList->append(specifier); 681 } 682 618 683 void appendStatement(JSC::SourceElements* elements, JSC::StatementNode* statement) 619 684 { -
TabularUnified trunk/Source/JavaScriptCore/parser/Keywords.table ¶
r186860 r187890 42 42 # Reserved for future use. 43 43 enum RESERVED 44 export RESERVED45 import RESERVED44 export EXPORT 45 import IMPORT 46 46 47 47 # Reserved for future use in strict code. -
TabularUnified trunk/Source/JavaScriptCore/parser/NodeConstructors.h ¶
r187515 r187890 734 734 } 735 735 736 inline ModuleSpecifierNode::ModuleSpecifierNode(const JSTokenLocation& location, const Identifier& moduleName) 737 : Node(location) 738 , m_moduleName(moduleName) 739 { 740 } 741 742 inline ImportSpecifierNode::ImportSpecifierNode(const JSTokenLocation& location, const Identifier& importedName, const Identifier& localName) 743 : Node(location) 744 , m_importedName(importedName) 745 , m_localName(localName) 746 { 747 } 748 749 inline ImportDeclarationNode::ImportDeclarationNode(const JSTokenLocation& location, ImportSpecifierListNode* importSpecifierList, ModuleSpecifierNode* moduleSpecifier) 750 : StatementNode(location) 751 , m_specifierList(importSpecifierList) 752 , m_moduleSpecifier(moduleSpecifier) 753 { 754 } 755 756 inline ExportAllDeclarationNode::ExportAllDeclarationNode(const JSTokenLocation& location, ModuleSpecifierNode* moduleSpecifier) 757 : StatementNode(location) 758 , m_moduleSpecifier(moduleSpecifier) 759 { 760 } 761 762 inline ExportDefaultDeclarationNode::ExportDefaultDeclarationNode(const JSTokenLocation& location, StatementNode* declaration) 763 : StatementNode(location) 764 , m_declaration(declaration) 765 { 766 } 767 768 inline ExportLocalDeclarationNode::ExportLocalDeclarationNode(const JSTokenLocation& location, StatementNode* declaration) 769 : StatementNode(location) 770 , m_declaration(declaration) 771 { 772 } 773 774 inline ExportNamedDeclarationNode::ExportNamedDeclarationNode(const JSTokenLocation& location, ExportSpecifierListNode* exportSpecifierList, ModuleSpecifierNode* moduleSpecifier) 775 : StatementNode(location) 776 , m_specifierList(exportSpecifierList) 777 , m_moduleSpecifier(moduleSpecifier) 778 { 779 } 780 781 inline ExportSpecifierNode::ExportSpecifierNode(const JSTokenLocation& location, const Identifier& localName, const Identifier& exportedName) 782 : Node(location) 783 , m_localName(localName) 784 , m_exportedName(exportedName) 785 { 786 } 787 736 788 inline EmptyVarExpression::EmptyVarExpression(const JSTokenLocation& location, const Identifier& ident) 737 789 : ExpressionNode(location) -
TabularUnified trunk/Source/JavaScriptCore/parser/Nodes.cpp ¶
r186959 r187890 130 130 } 131 131 132 // ------------------------------ ModuleProgramNode ----------------------------- 133 134 ModuleProgramNode::ModuleProgramNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VariableEnvironment& varEnvironment, FunctionStack& funcStack, VariableEnvironment& lexicalVariables, FunctionParameters*, const SourceCode& source, CodeFeatures features, int numConstants) 135 : ScopeNode(parserArena, startLocation, endLocation, source, children, varEnvironment, funcStack, lexicalVariables, features, numConstants) 136 , m_startColumn(startColumn) 137 , m_endColumn(endColumn) 138 { 139 } 140 132 141 // ------------------------------ EvalNode ----------------------------- 133 142 -
TabularUnified trunk/Source/JavaScriptCore/parser/Nodes.h ¶
r187515 r187890 1623 1623 }; 1624 1624 1625 class ModuleProgramNode : public ScopeNode { 1626 public: 1627 ModuleProgramNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VariableEnvironment&, FunctionStack&, VariableEnvironment&, FunctionParameters*, const SourceCode&, CodeFeatures, int numConstants); 1628 1629 unsigned startColumn() const { return m_startColumn; } 1630 unsigned endColumn() const { return m_endColumn; } 1631 1632 static const bool scopeIsFunction = false; 1633 1634 private: 1635 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1636 unsigned m_startColumn; 1637 unsigned m_endColumn; 1638 }; 1639 1640 class ModuleSpecifierNode : public Node { 1641 public: 1642 ModuleSpecifierNode(const JSTokenLocation&, const Identifier& moduleName); 1643 1644 const Identifier& moduleName() { return m_moduleName; } 1645 1646 private: 1647 const Identifier& m_moduleName; 1648 }; 1649 1650 class ImportSpecifierNode : public Node { 1651 public: 1652 ImportSpecifierNode(const JSTokenLocation&, const Identifier& importedName, const Identifier& localName); 1653 1654 const Identifier& importedName() { return m_importedName; } 1655 const Identifier& localName() { return m_localName; } 1656 1657 private: 1658 const Identifier& m_importedName; 1659 const Identifier& m_localName; 1660 }; 1661 1662 class ImportSpecifierListNode : public ParserArenaDeletable { 1663 public: 1664 typedef Vector<ImportSpecifierNode*, 3> Specifiers; 1665 1666 const Specifiers& specifiers() const { return m_specifiers; } 1667 void append(ImportSpecifierNode* specifier) 1668 { 1669 m_specifiers.append(specifier); 1670 } 1671 1672 private: 1673 Specifiers m_specifiers; 1674 }; 1675 1676 class ImportDeclarationNode : public StatementNode { 1677 public: 1678 ImportDeclarationNode(const JSTokenLocation&, ImportSpecifierListNode*, ModuleSpecifierNode*); 1679 1680 ImportSpecifierListNode* specifierList() const { return m_specifierList; } 1681 ModuleSpecifierNode* moduleSpecifier() const { return m_moduleSpecifier; } 1682 1683 private: 1684 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1685 1686 ImportSpecifierListNode* m_specifierList; 1687 ModuleSpecifierNode* m_moduleSpecifier; 1688 }; 1689 1690 class ExportAllDeclarationNode : public StatementNode { 1691 public: 1692 ExportAllDeclarationNode(const JSTokenLocation&, ModuleSpecifierNode*); 1693 1694 ModuleSpecifierNode* moduleSpecifier() const { return m_moduleSpecifier; } 1695 1696 private: 1697 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1698 ModuleSpecifierNode* m_moduleSpecifier; 1699 }; 1700 1701 class ExportDefaultDeclarationNode : public StatementNode { 1702 public: 1703 ExportDefaultDeclarationNode(const JSTokenLocation&, StatementNode*); 1704 1705 const StatementNode& declaration() const { return *m_declaration; } 1706 1707 private: 1708 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1709 StatementNode* m_declaration; 1710 }; 1711 1712 class ExportLocalDeclarationNode : public StatementNode { 1713 public: 1714 ExportLocalDeclarationNode(const JSTokenLocation&, StatementNode*); 1715 1716 const StatementNode& declaration() const { return *m_declaration; } 1717 1718 private: 1719 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1720 StatementNode* m_declaration; 1721 }; 1722 1723 class ExportSpecifierNode : public Node { 1724 public: 1725 ExportSpecifierNode(const JSTokenLocation&, const Identifier& localName, const Identifier& exportedName); 1726 1727 const Identifier& exportedName() { return m_exportedName; } 1728 const Identifier& localName() { return m_localName; } 1729 1730 private: 1731 const Identifier& m_localName; 1732 const Identifier& m_exportedName; 1733 }; 1734 1735 class ExportSpecifierListNode : public ParserArenaDeletable { 1736 public: 1737 typedef Vector<ExportSpecifierNode*, 3> Specifiers; 1738 1739 const Specifiers& specifiers() const { return m_specifiers; } 1740 void append(ExportSpecifierNode* specifier) 1741 { 1742 m_specifiers.append(specifier); 1743 } 1744 1745 private: 1746 Specifiers m_specifiers; 1747 }; 1748 1749 class ExportNamedDeclarationNode : public StatementNode { 1750 public: 1751 ExportNamedDeclarationNode(const JSTokenLocation&, ExportSpecifierListNode*, ModuleSpecifierNode*); 1752 1753 ExportSpecifierListNode* specifierList() const { return m_specifierList; } 1754 ModuleSpecifierNode* moduleSpecifier() const { return m_moduleSpecifier; } 1755 1756 private: 1757 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1758 ExportSpecifierListNode* m_specifierList; 1759 ModuleSpecifierNode* m_moduleSpecifier { nullptr }; 1760 }; 1761 1625 1762 class FunctionParameters : public ParserArenaDeletable { 1626 1763 public: -
TabularUnified trunk/Source/JavaScriptCore/parser/Parser.cpp ¶
r187760 r187890 210 210 , m_defaultConstructorKind(defaultConstructorKind) 211 211 , m_thisTDZMode(thisTDZMode) 212 , m_codeType(codeType) 212 213 { 213 214 m_lexer = std::make_unique<LexerType>(vm, builtinMode); … … 221 222 if (codeType == JSParserCodeType::Function) 222 223 scope->setIsFunction(); 224 if (codeType == JSParserCodeType::Module) 225 scope->setIsModule(); 223 226 if (strictMode == JSParserStrictMode::Strict) 224 227 scope->setStrictMode(); … … 268 271 if (isArrowFunctionBodyExpression) 269 272 sourceElements = parseArrowFunctionSingleExpressionBodySourceElements(context); 273 #if ENABLE(ES6_MODULES) 274 else if (m_codeType == JSParserCodeType::Module) 275 sourceElements = parseModuleSourceElements(context); 276 #endif 270 277 else 271 278 sourceElements = parseSourceElements(context, CheckForStrictMode); … … 404 411 return sourceElements; 405 412 } 413 414 template <typename LexerType> 415 template <class TreeBuilder> TreeSourceElements Parser<LexerType>::parseModuleSourceElements(TreeBuilder& context) 416 { 417 TreeSourceElements sourceElements = context.createSourceElements(); 418 419 // FIXME: When some sort of ModuleAnalyzer TreeBuilder is landed, 420 // this SyntaxChecker will be replaced with typedef under the TreeBuilder, 421 // like TreeBuilder::ModuleStatementItemBuilder. 422 // https://bugs.webkit.org/show_bug.cgi?id=147353 423 SyntaxChecker moduleStatementItemBuilder(const_cast<VM*>(m_vm), m_lexer.get()); 424 425 while (true) { 426 if (match(IMPORT) || match(EXPORT)) { 427 TreeStatement statement = 0; 428 if (match(IMPORT)) 429 statement = parseImportDeclaration(context); 430 else 431 statement = parseExportDeclaration(context); 432 433 if (!statement) 434 break; 435 context.appendStatement(sourceElements, statement); 436 } else { 437 const Identifier* directive = 0; 438 unsigned directiveLiteralLength = 0; 439 if (!parseStatementListItem(moduleStatementItemBuilder, directive, &directiveLiteralLength)) 440 break; 441 } 442 } 443 444 propagateError(); 445 446 for (const auto& uid : currentScope()->moduleScopeData().exportedBindings()) 447 semanticFailIfFalse(currentScope()->hasDeclaredVariable(uid) || currentScope()->hasLexicallyDeclaredVariable(uid), "Exported binding '", uid.get(), "' needs to refer to a top-level declared variable"); 448 449 return sourceElements; 450 } 451 406 452 template <typename LexerType> 407 453 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseStatementListItem(TreeBuilder& context, const Identifier*& directive, unsigned* directiveLiteralLength) … … 452 498 453 499 template <typename LexerType> 454 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseVariableDeclaration(TreeBuilder& context, DeclarationType declarationType )500 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseVariableDeclaration(TreeBuilder& context, DeclarationType declarationType, ExportType exportType) 455 501 { 456 502 ASSERT(match(VAR) || match(LET) || match(CONSTTOKEN)); … … 463 509 JSTextPosition scratch3; 464 510 bool scratchBool; 465 TreeExpression variableDecls = parseVariableDeclarationList(context, scratch, scratch1, scratch2, scratch3, scratch3, scratch3, VarDeclarationContext, declarationType, scratchBool);511 TreeExpression variableDecls = parseVariableDeclarationList(context, scratch, scratch1, scratch2, scratch3, scratch3, scratch3, VarDeclarationContext, declarationType, exportType, scratchBool); 466 512 propagateError(); 467 513 failIfFalse(autoSemiColon(), "Expected ';' after variable declaration"); … … 518 564 519 565 template <typename LexerType> 520 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseVariableDeclarationList(TreeBuilder& context, int& declarations, TreeDestructuringPattern& lastPattern, TreeExpression& lastInitializer, JSTextPosition& identStart, JSTextPosition& initStart, JSTextPosition& initEnd, VarDeclarationListContext declarationListContext, DeclarationType declarationType, bool& forLoopConstDoesNotHaveInitializer)566 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseVariableDeclarationList(TreeBuilder& context, int& declarations, TreeDestructuringPattern& lastPattern, TreeExpression& lastInitializer, JSTextPosition& identStart, JSTextPosition& initStart, JSTextPosition& initEnd, VarDeclarationListContext declarationListContext, DeclarationType declarationType, ExportType exportType, bool& forLoopConstDoesNotHaveInitializer) 521 567 { 522 568 ASSERT(declarationType == DeclarationType::LetDeclaration || declarationType == DeclarationType::VarDeclaration || declarationType == DeclarationType::ConstDeclaration); … … 556 602 } 557 603 } 604 semanticFailIfTrue(exportType == ExportType::Exported && !currentScope()->moduleScopeData().exportName(*name), "Cannot export a duplicate name '", name->impl(), "'"); 605 558 606 if (hasInitializer) { 559 607 JSTextPosition varDivot = tokenStartPosition() + 1; … … 577 625 } else { 578 626 lastIdent = 0; 579 auto pattern = parseDestructuringPattern(context, destructuringKindFromDeclarationType(declarationType), nullptr, nullptr, assignmentContext);627 auto pattern = parseDestructuringPattern(context, destructuringKindFromDeclarationType(declarationType), exportType, nullptr, nullptr, assignmentContext); 580 628 failIfFalse(pattern, "Cannot parse this destructuring pattern"); 581 629 hasInitializer = match(EQUAL); … … 605 653 606 654 template <typename LexerType> 607 template <class TreeBuilder> TreeDestructuringPattern Parser<LexerType>::createBindingPattern(TreeBuilder& context, DestructuringKind kind, const Identifier& name, int depth, JSToken token, AssignmentContext bindingContext, const Identifier** duplicateIdentifier)655 template <class TreeBuilder> TreeDestructuringPattern Parser<LexerType>::createBindingPattern(TreeBuilder& context, DestructuringKind kind, ExportType exportType, const Identifier& name, int depth, JSToken token, AssignmentContext bindingContext, const Identifier** duplicateIdentifier) 608 656 { 609 657 ASSERT(!name.isNull()); … … 657 705 } 658 706 } 707 708 semanticFailIfTrue(exportType == ExportType::Exported && !currentScope()->moduleScopeData().exportName(name), "Cannot export a duplicate name '", name.impl(), "'"); 659 709 return context.createBindingLocation(token.m_location, name, token.m_startPosition, token.m_endPosition, bindingContext); 660 710 } … … 692 742 template <class TreeBuilder> TreeDestructuringPattern Parser<LexerType>::tryParseDestructuringPatternExpression(TreeBuilder& context, AssignmentContext bindingContext) 693 743 { 694 return parseDestructuringPattern(context, DestructureToExpressions, nullptr, nullptr, bindingContext);695 } 696 697 template <typename LexerType> 698 template <class TreeBuilder> TreeDestructuringPattern Parser<LexerType>::parseDestructuringPattern(TreeBuilder& context, DestructuringKind kind, const Identifier** duplicateIdentifier, bool* hasDestructuringPattern, AssignmentContext bindingContext, int depth)744 return parseDestructuringPattern(context, DestructureToExpressions, ExportType::NotExported, nullptr, nullptr, bindingContext); 745 } 746 747 template <typename LexerType> 748 template <class TreeBuilder> TreeDestructuringPattern Parser<LexerType>::parseDestructuringPattern(TreeBuilder& context, DestructuringKind kind, ExportType exportType, const Identifier** duplicateIdentifier, bool* hasDestructuringPattern, AssignmentContext bindingContext, int depth) 699 749 { 700 750 failIfStackOverflow(); … … 725 775 JSTokenLocation location = m_token.m_location; 726 776 next(); 727 auto innerPattern = parseDestructuringPattern(context, kind, duplicateIdentifier, hasDestructuringPattern, bindingContext, depth + 1);777 auto innerPattern = parseDestructuringPattern(context, kind, exportType, duplicateIdentifier, hasDestructuringPattern, bindingContext, depth + 1); 728 778 if (kind == DestructureToExpressions && !innerPattern) 729 779 return 0; … … 738 788 739 789 JSTokenLocation location = m_token.m_location; 740 auto innerPattern = parseDestructuringPattern(context, kind, duplicateIdentifier, hasDestructuringPattern, bindingContext, depth + 1);790 auto innerPattern = parseDestructuringPattern(context, kind, exportType, duplicateIdentifier, hasDestructuringPattern, bindingContext, depth + 1); 741 791 if (kind == DestructureToExpressions && !innerPattern) 742 792 return 0; … … 775 825 next(); 776 826 if (consume(COLON)) 777 innerPattern = parseDestructuringPattern(context, kind, duplicateIdentifier, hasDestructuringPattern, bindingContext, depth + 1);827 innerPattern = parseDestructuringPattern(context, kind, exportType, duplicateIdentifier, hasDestructuringPattern, bindingContext, depth + 1); 778 828 else 779 innerPattern = createBindingPattern(context, kind, *propertyName, depth + 1, identifierToken, bindingContext, duplicateIdentifier);829 innerPattern = createBindingPattern(context, kind, exportType, *propertyName, depth + 1, identifierToken, bindingContext, duplicateIdentifier); 780 830 } else { 781 831 JSTokenType tokenType = m_token.m_type; … … 808 858 failWithMessage("Expected a ':' prior to a named destructuring property"); 809 859 } 810 innerPattern = parseDestructuringPattern(context, kind, duplicateIdentifier, hasDestructuringPattern, bindingContext, depth + 1);860 innerPattern = parseDestructuringPattern(context, kind, exportType, duplicateIdentifier, hasDestructuringPattern, bindingContext, depth + 1); 811 861 } 812 862 if (kind == DestructureToExpressions && !innerPattern) … … 833 883 } 834 884 failIfTrue(match(LET) && (kind == DestructureToLet || kind == DestructureToConst), "Can't use 'let' as an identifier name for a LexicalDeclaration"); 835 pattern = createBindingPattern(context, kind, *m_token.m_data.ident, depth, m_token, bindingContext, duplicateIdentifier);885 pattern = createBindingPattern(context, kind, exportType, *m_token.m_data.ident, depth, m_token, bindingContext, duplicateIdentifier); 836 886 next(); 837 887 break; … … 914 964 else 915 965 RELEASE_ASSERT_NOT_REACHED(); 916 decls = parseVariableDeclarationList(context, declarations, forInTarget, forInInitializer, declsStart, initStart, initEnd, ForLoopContext, declarationType, forLoopConstDoesNotHaveInitializer);966 decls = parseVariableDeclarationList(context, declarations, forInTarget, forInInitializer, declsStart, initStart, initEnd, ForLoopContext, declarationType, ExportType::NotExported, forLoopConstDoesNotHaveInitializer); 917 967 m_allowsIn = true; 918 968 propagateError(); … … 1458 1508 const Identifier* duplicateParameter = nullptr; 1459 1509 bool hasDestructuringPattern = false; 1460 auto parameter = parseDestructuringPattern(context, DestructureToParameters, &duplicateParameter, &hasDestructuringPattern);1510 auto parameter = parseDestructuringPattern(context, DestructureToParameters, ExportType::NotExported, &duplicateParameter, &hasDestructuringPattern); 1461 1511 failIfFalse(parameter, "Cannot parse parameter pattern"); 1462 1512 auto defaultValue = parseDefaultValueForDestructuringPattern(context); … … 1466 1516 parameterCount++; 1467 1517 while (consume(COMMA)) { 1468 parameter = parseDestructuringPattern(context, DestructureToParameters, &duplicateParameter, &hasDestructuringPattern);1518 parameter = parseDestructuringPattern(context, DestructureToParameters, ExportType::NotExported, &duplicateParameter, &hasDestructuringPattern); 1469 1519 failIfFalse(parameter, "Cannot parse parameter pattern"); 1470 1520 defaultValue = parseDefaultValueForDestructuringPattern(context); … … 1547 1597 } else { 1548 1598 functionInfo.parameterCount = 1; 1549 auto parameter = parseDestructuringPattern(context, DestructureToParameters );1599 auto parameter = parseDestructuringPattern(context, DestructureToParameters, ExportType::NotExported); 1550 1600 failIfFalse(parameter, "Cannot parse parameter pattern"); 1551 1601 context.appendParameter(parameterList, parameter, 0); … … 1567 1617 failIfTrue(match(CLOSEPAREN), "setter functions must have one parameter"); 1568 1618 const Identifier* duplicateParameter = nullptr; 1569 auto parameter = parseDestructuringPattern(context, DestructureToParameters, &duplicateParameter);1619 auto parameter = parseDestructuringPattern(context, DestructureToParameters, ExportType::NotExported, &duplicateParameter); 1570 1620 failIfFalse(parameter, "setter functions must have one parameter"); 1571 1621 auto defaultValue = parseDefaultValueForDestructuringPattern(context); … … 1796 1846 1797 1847 template <typename LexerType> 1798 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseFunctionDeclaration(TreeBuilder& context )1848 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseFunctionDeclaration(TreeBuilder& context, ExportType exportType) 1799 1849 { 1800 1850 ASSERT(match(FUNCTION)); … … 1807 1857 failIfFalse(functionInfo.name, "Function statements must have a name"); 1808 1858 failIfTrueIfStrict(declareVariable(functionInfo.name) & DeclarationResult::InvalidStrictMode, "Cannot declare a function named '", functionInfo.name->impl(), "' in strict mode"); 1859 semanticFailIfTrue(exportType == ExportType::Exported && !currentScope()->moduleScopeData().exportName(*functionInfo.name), "Cannot export a duplicate function name: '", functionInfo.name->impl(), "'"); 1809 1860 return context.createFuncDeclStatement(location, functionInfo); 1810 1861 } … … 1812 1863 #if ENABLE(ES6_CLASS_SYNTAX) 1813 1864 template <typename LexerType> 1814 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseClassDeclaration(TreeBuilder& context )1865 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseClassDeclaration(TreeBuilder& context, ExportType exportType) 1815 1866 { 1816 1867 ASSERT(match(CLASSTOKEN)); … … 1826 1877 if (declarationResult & DeclarationResult::InvalidDuplicateDeclaration) 1827 1878 internalFailWithMessage(false, "Cannot declare a class twice: '", info.className->impl(), "'"); 1879 semanticFailIfTrue(exportType == ExportType::Exported && !currentScope()->moduleScopeData().exportName(*info.className), "Cannot export a duplicate class name: '", info.className->impl(), "'"); 1828 1880 1829 1881 JSTextPosition classEnd = lastTokenEndPosition(); … … 2147 2199 2148 2200 return context.createIfStatement(ifLocation, condition, trueBlock, statementStack.last(), start, end); 2201 } 2202 2203 template <typename LexerType> 2204 template <class TreeBuilder> typename TreeBuilder::ModuleSpecifier Parser<LexerType>::parseModuleSpecifier(TreeBuilder& context) 2205 { 2206 // ModuleSpecifier represents the module name imported by the script. 2207 // http://www.ecma-international.org/ecma-262/6.0/#sec-imports 2208 // http://www.ecma-international.org/ecma-262/6.0/#sec-exports 2209 JSTokenLocation specifierLocation(tokenLocation()); 2210 failIfFalse(match(STRING), "Imported modules names must be string literals"); 2211 const Identifier* moduleName = m_token.m_data.ident; 2212 next(); 2213 return context.createModuleSpecifier(specifierLocation, *moduleName); 2214 } 2215 2216 template <typename LexerType> 2217 template <class TreeBuilder> typename TreeBuilder::ImportSpecifier Parser<LexerType>::parseImportClauseItem(TreeBuilder& context, ImportSpecifierType specifierType) 2218 { 2219 // Produced node is the item of the ImportClause. 2220 // That is the ImportSpecifier, ImportedDefaultBinding or NameSpaceImport. 2221 // http://www.ecma-international.org/ecma-262/6.0/#sec-imports 2222 JSTokenLocation specifierLocation(tokenLocation()); 2223 JSToken localNameToken; 2224 const Identifier* importedName = nullptr; 2225 const Identifier* localName = nullptr; 2226 2227 switch (specifierType) { 2228 case ImportSpecifierType::NamespaceImport: { 2229 // NameSpaceImport : 2230 // * as ImportedBinding 2231 // e.g. 2232 // * as namespace 2233 ASSERT(match(TIMES)); 2234 importedName = &m_vm->propertyNames->timesIdentifier; 2235 next(); 2236 2237 failIfFalse(matchContextualKeyword(m_vm->propertyNames->as), "Expected 'as' before imported binding name"); 2238 next(); 2239 2240 matchOrFail(IDENT, "Expected a variable name for the import declaration"); 2241 localNameToken = m_token; 2242 localName = m_token.m_data.ident; 2243 next(); 2244 break; 2245 } 2246 2247 case ImportSpecifierType::NamedImport: { 2248 // ImportSpecifier : 2249 // ImportedBinding 2250 // IdentifierName as ImportedBinding 2251 // e.g. 2252 // A 2253 // A as B 2254 ASSERT(matchIdentifierOrKeyword()); 2255 localNameToken = m_token; 2256 localName = m_token.m_data.ident; 2257 importedName = localName; 2258 next(); 2259 2260 if (matchContextualKeyword(m_vm->propertyNames->as)) { 2261 next(); 2262 matchOrFail(IDENT, "Expected a variable name for the import declaration"); 2263 localNameToken = m_token; 2264 localName = m_token.m_data.ident; 2265 next(); 2266 } 2267 break; 2268 } 2269 2270 case ImportSpecifierType::DefaultImport: { 2271 // ImportedDefaultBinding : 2272 // ImportedBinding 2273 ASSERT(match(IDENT)); 2274 localNameToken = m_token; 2275 localName = m_token.m_data.ident; 2276 importedName = &m_vm->propertyNames->defaultKeyword; 2277 next(); 2278 break; 2279 } 2280 } 2281 2282 semanticFailIfTrue(localNameToken.m_type & KeywordTokenFlag, "Cannot use keyword as imported binding name"); 2283 DeclarationResultMask declarationResult = declareVariable(localName, DeclarationType::ConstDeclaration); 2284 if (declarationResult != DeclarationResult::Valid) { 2285 failIfTrueIfStrict(declarationResult & DeclarationResult::InvalidStrictMode, "Cannot declare an imported binding named ", localName->impl(), " in strict mode"); 2286 if (declarationResult & DeclarationResult::InvalidDuplicateDeclaration) 2287 internalFailWithMessage(false, "Cannot declare an imported binding name twice: '", localName->impl(), "'"); 2288 } 2289 2290 return context.createImportSpecifier(specifierLocation, *importedName, *localName); 2291 } 2292 2293 template <typename LexerType> 2294 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseImportDeclaration(TreeBuilder& context) 2295 { 2296 // http://www.ecma-international.org/ecma-262/6.0/#sec-imports 2297 ASSERT(match(IMPORT)); 2298 JSTokenLocation importLocation(tokenLocation()); 2299 next(); 2300 2301 auto specifierList = context.createImportSpecifierList(); 2302 2303 if (match(STRING)) { 2304 // import ModuleSpecifier ; 2305 auto moduleSpecifier = parseModuleSpecifier(context); 2306 failIfFalse(moduleSpecifier, "Cannot parse the module name"); 2307 failIfFalse(autoSemiColon(), "Expected a ';' following a targeted import declaration"); 2308 return context.createImportDeclaration(importLocation, specifierList, moduleSpecifier); 2309 } 2310 2311 bool isFinishedParsingImport = false; 2312 if (match(IDENT)) { 2313 // ImportedDefaultBinding : 2314 // ImportedBinding 2315 auto specifier = parseImportClauseItem(context, ImportSpecifierType::DefaultImport); 2316 failIfFalse(specifier, "Cannot parse the default import"); 2317 context.appendImportSpecifier(specifierList, specifier); 2318 if (match(COMMA)) 2319 next(); 2320 else 2321 isFinishedParsingImport = true; 2322 } 2323 2324 if (!isFinishedParsingImport) { 2325 if (match(TIMES)) { 2326 // import NameSpaceImport FromClause ; 2327 auto specifier = parseImportClauseItem(context, ImportSpecifierType::NamespaceImport); 2328 failIfFalse(specifier, "Cannot parse the namespace import"); 2329 context.appendImportSpecifier(specifierList, specifier); 2330 } else if (match(OPENBRACE)) { 2331 // NamedImports : 2332 // { } 2333 // { ImportsList } 2334 // { ImportsList , } 2335 next(); 2336 2337 while (!match(CLOSEBRACE)) { 2338 failIfFalse(matchIdentifierOrKeyword(), "Expected an imported name for the import declaration"); 2339 auto specifier = parseImportClauseItem(context, ImportSpecifierType::NamedImport); 2340 failIfFalse(specifier, "Cannot parse the named import"); 2341 context.appendImportSpecifier(specifierList, specifier); 2342 if (!consume(COMMA)) 2343 break; 2344 } 2345 handleProductionOrFail(CLOSEBRACE, "}", "end", "import list"); 2346 } else 2347 failWithMessage("Expected namespace import or import list"); 2348 } 2349 2350 // FromClause : 2351 // from ModuleSpecifier 2352 2353 failIfFalse(matchContextualKeyword(m_vm->propertyNames->from), "Expected 'from' before imported module name"); 2354 next(); 2355 2356 auto moduleSpecifier = parseModuleSpecifier(context); 2357 failIfFalse(moduleSpecifier, "Cannot parse the module name"); 2358 failIfFalse(autoSemiColon(), "Expected a ';' following a targeted import declaration"); 2359 2360 return context.createImportDeclaration(importLocation, specifierList, moduleSpecifier); 2361 } 2362 2363 template <typename LexerType> 2364 template <class TreeBuilder> typename TreeBuilder::ExportSpecifier Parser<LexerType>::parseExportSpecifier(TreeBuilder& context, Vector<const Identifier*>& maybeLocalNames, bool& hasKeywordForLocalBindings) 2365 { 2366 // ExportSpecifier : 2367 // IdentifierName 2368 // IdentifierName as IdentifierName 2369 // http://www.ecma-international.org/ecma-262/6.0/#sec-exports 2370 ASSERT(matchIdentifierOrKeyword()); 2371 JSTokenLocation specifierLocation(tokenLocation()); 2372 if (m_token.m_type & KeywordTokenFlag) 2373 hasKeywordForLocalBindings = true; 2374 const Identifier* localName = m_token.m_data.ident; 2375 const Identifier* exportedName = localName; 2376 next(); 2377 2378 if (matchContextualKeyword(m_vm->propertyNames->as)) { 2379 next(); 2380 failIfFalse(matchIdentifierOrKeyword(), "Expected an exported name for the export declaration"); 2381 exportedName = m_token.m_data.ident; 2382 next(); 2383 } 2384 2385 semanticFailIfFalse(currentScope()->moduleScopeData().exportName(*exportedName), "Cannot export a duplicate name '", exportedName->impl(), "'"); 2386 maybeLocalNames.append(localName); 2387 return context.createExportSpecifier(specifierLocation, *localName, *exportedName); 2388 } 2389 2390 template <typename LexerType> 2391 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExportDeclaration(TreeBuilder& context) 2392 { 2393 // http://www.ecma-international.org/ecma-262/6.0/#sec-exports 2394 ASSERT(match(EXPORT)); 2395 JSTokenLocation exportLocation(tokenLocation()); 2396 next(); 2397 2398 switch (m_token.m_type) { 2399 case TIMES: { 2400 // export * FromClause ; 2401 next(); 2402 2403 failIfFalse(matchContextualKeyword(m_vm->propertyNames->from), "Expected 'from' before exported module name"); 2404 next(); 2405 auto moduleSpecifier = parseModuleSpecifier(context); 2406 failIfFalse(moduleSpecifier, "Cannot parse the 'from' clause"); 2407 failIfFalse(autoSemiColon(), "Expected a ';' following a targeted export declaration"); 2408 return context.createExportAllDeclaration(exportLocation, moduleSpecifier); 2409 } 2410 2411 case DEFAULT: { 2412 // export default HoistableDeclaration[Default] 2413 // export default ClassDeclaration[Default] 2414 // export default [lookahead not-in {function, class}] AssignmentExpression[In] ; 2415 2416 next(); 2417 2418 TreeStatement result = 0; 2419 bool hasName = false; 2420 bool isFunctionOrClassDeclaration = false; 2421 SavePoint savePoint = createSavePoint(); 2422 if (match(FUNCTION) 2423 #if ENABLE(ES6_CLASS_SYNTAX) 2424 || match(CLASSTOKEN) 2425 #endif 2426 ) { 2427 isFunctionOrClassDeclaration = true; 2428 next(); 2429 // FIXME: When landing ES6 generators, we need to take care of that '*' comes. 2430 hasName = match(IDENT); 2431 restoreSavePoint(savePoint); 2432 } 2433 2434 if (hasName) { 2435 if (match(FUNCTION)) 2436 result = parseFunctionDeclaration(context); 2437 #if ENABLE(ES6_CLASS_SYNTAX) 2438 else { 2439 ASSERT(match(CLASSTOKEN)); 2440 result = parseClassDeclaration(context); 2441 } 2442 #endif 2443 } else { 2444 JSTokenLocation location(tokenLocation()); 2445 JSTextPosition start = tokenStartPosition(); 2446 TreeExpression expression = parseAssignmentExpression(context); 2447 failIfFalse(expression, "Cannot parse expression"); 2448 result = context.createExprStatement(location, expression, start, tokenEndPosition()); 2449 if (!isFunctionOrClassDeclaration) 2450 failIfFalse(autoSemiColon(), "Expected a ';' following a targeted export declaration"); 2451 } 2452 failIfFalse(result, "Cannot parse the declaration"); 2453 semanticFailIfFalse(currentScope()->moduleScopeData().exportName(m_vm->propertyNames->defaultKeyword), "Cannot export 'default' name twice."); 2454 2455 return context.createExportDefaultDeclaration(exportLocation, result); 2456 } 2457 2458 case OPENBRACE: { 2459 // export ExportClause FromClause ; 2460 // export ExportClause ; 2461 // 2462 // ExportClause : 2463 // { } 2464 // { ExportsList } 2465 // { ExportsList , } 2466 // 2467 // ExportsList : 2468 // ExportSpecifier 2469 // ExportsList , ExportSpecifier 2470 2471 next(); 2472 2473 auto specifierList = context.createExportSpecifierList(); 2474 Vector<const Identifier*> maybeLocalNames; 2475 2476 bool hasKeywordForLocalBindings = false; 2477 while (!match(CLOSEBRACE)) { 2478 failIfFalse(matchIdentifierOrKeyword(), "Expected a variable name for the export declaration"); 2479 auto specifier = parseExportSpecifier(context, maybeLocalNames, hasKeywordForLocalBindings); 2480 failIfFalse(specifier, "Cannot parse the named export"); 2481 context.appendExportSpecifier(specifierList, specifier); 2482 if (!consume(COMMA)) 2483 break; 2484 } 2485 handleProductionOrFail(CLOSEBRACE, "}", "end", "export list"); 2486 2487 typename TreeBuilder::ModuleSpecifier moduleSpecifier = 0; 2488 if (matchContextualKeyword(m_vm->propertyNames->from)) { 2489 next(); 2490 moduleSpecifier = parseModuleSpecifier(context); 2491 failIfFalse(moduleSpecifier, "Cannot parse the 'from' clause"); 2492 } 2493 failIfFalse(autoSemiColon(), "Expected a ';' following a targeted export declaration"); 2494 2495 if (!moduleSpecifier) { 2496 semanticFailIfTrue(hasKeywordForLocalBindings, "Cannot use keyword as exported variable name"); 2497 // Since this export declaration does not have module specifier part, it exports the local bindings. 2498 // While the export declaration with module specifier does not have any effect on the current module's scope, 2499 // the export named declaration without module specifier references the the local binding names. 2500 // For example, 2501 // export { A, B, C as D } from "mod" 2502 // does not have effect on the current module's scope. But, 2503 // export { A, B, C as D } 2504 // will reference the current module's bindings. 2505 for (const Identifier* localName : maybeLocalNames) { 2506 currentScope()->useVariable(localName, m_vm->propertyNames->eval == *localName); 2507 currentScope()->moduleScopeData().exportBinding(*localName); 2508 } 2509 } 2510 2511 return context.createExportNamedDeclaration(exportLocation, specifierList, moduleSpecifier); 2512 } 2513 2514 default: { 2515 // export VariableStatement 2516 // export Declaration 2517 TreeStatement result = 0; 2518 switch (m_token.m_type) { 2519 case VAR: 2520 result = parseVariableDeclaration(context, DeclarationType::VarDeclaration, ExportType::Exported); 2521 break; 2522 2523 case CONSTTOKEN: 2524 result = parseVariableDeclaration(context, DeclarationType::ConstDeclaration, ExportType::Exported); 2525 break; 2526 2527 case LET: 2528 result = parseVariableDeclaration(context, DeclarationType::LetDeclaration, ExportType::Exported); 2529 break; 2530 2531 case FUNCTION: 2532 result = parseFunctionDeclaration(context, ExportType::Exported); 2533 break; 2534 2535 #if ENABLE(ES6_CLASS_SYNTAX) 2536 case CLASSTOKEN: 2537 result = parseClassDeclaration(context, ExportType::Exported); 2538 break; 2539 #endif 2540 2541 default: 2542 failWithMessage("Expected either a declaration or a variable statement"); 2543 break; 2544 } 2545 failIfFalse(result, "Cannot parse the declaration"); 2546 return context.createExportLocalDeclaration(exportLocation, result); 2547 } 2548 } 2549 2550 RELEASE_ASSERT_NOT_REACHED(); 2551 return 0; 2149 2552 } 2150 2553 … … 2927 3330 2928 3331 if (baseIsSuper) { 3332 semanticFailIfFalse(currentScope()->isFunction(), "super is only valid inside functions"); 2929 3333 base = context.createSuperExpr(location); 2930 3334 next(); -
TabularUnified trunk/Source/JavaScriptCore/parser/Parser.h ¶
r187351 r187890 128 128 return isEval(vm, ident) || isArguments(vm, ident); 129 129 } 130 ALWAYS_INLINE static bool isIdentifierOrKeyword(const JSToken& token) 131 { 132 return token.m_type == IDENT || token.m_type & KeywordTokenFlag; 133 } 134 135 class ModuleScopeData : public RefCounted<ModuleScopeData> { 136 public: 137 static Ref<ModuleScopeData> create() { return adoptRef(*new ModuleScopeData); } 138 139 const IdentifierSet& exportedBindings() const { return m_exportedBindings; } 140 141 bool exportName(const Identifier& exportedName) 142 { 143 return m_exportedNames.add(exportedName.impl()).isNewEntry; 144 } 145 146 void exportBinding(const Identifier& localName) 147 { 148 m_exportedBindings.add(localName.impl()); 149 } 150 151 private: 152 IdentifierSet m_exportedNames { }; 153 IdentifierSet m_exportedBindings { }; 154 }; 130 155 131 156 struct Scope { … … 165 190 , m_loopDepth(rhs.m_loopDepth) 166 191 , m_switchDepth(rhs.m_switchDepth) 192 , m_moduleScopeData(rhs.m_moduleScopeData) 167 193 { 168 194 if (rhs.m_labels) { … … 216 242 } 217 243 244 void setIsModule() 245 { 246 m_moduleScopeData = ModuleScopeData::create(); 247 } 248 218 249 bool isFunction() const { return m_isFunction; } 219 250 bool isFunctionBoundary() const { return m_isFunctionBoundary; } … … 235 266 236 267 return m_lexicalVariables; 268 } 269 270 ModuleScopeData& moduleScopeData() const 271 { 272 ASSERT(m_moduleScopeData); 273 return *m_moduleScopeData; 237 274 } 238 275 … … 533 570 IdentifierSet m_closedVariableCandidates; 534 571 IdentifierSet m_writtenVariables; 572 RefPtr<ModuleScopeData> m_moduleScopeData { }; 535 573 }; 536 574 … … 848 886 } 849 887 850 ALWAYS_INLINE bool isofToken() 851 { 852 return m_token.m_type == IDENT && *m_token.m_data.ident == m_vm->propertyNames->of; 888 ALWAYS_INLINE bool matchContextualKeyword(const Identifier& identifier) 889 { 890 return m_token.m_type == IDENT && *m_token.m_data.ident == identifier; 891 } 892 893 ALWAYS_INLINE bool matchIdentifierOrKeyword() 894 { 895 return isIdentifierOrKeyword(m_token); 853 896 } 854 897 … … 1008 1051 template <class TreeBuilder> TreeStatement parseStatementListItem(TreeBuilder&, const Identifier*& directive, unsigned* directiveLiteralLength); 1009 1052 template <class TreeBuilder> TreeStatement parseStatement(TreeBuilder&, const Identifier*& directive, unsigned* directiveLiteralLength = 0); 1053 enum class ExportType { Exported, NotExported }; 1010 1054 #if ENABLE(ES6_CLASS_SYNTAX) 1011 template <class TreeBuilder> TreeStatement parseClassDeclaration(TreeBuilder& );1055 template <class TreeBuilder> TreeStatement parseClassDeclaration(TreeBuilder&, ExportType = ExportType::NotExported); 1012 1056 #endif 1013 template <class TreeBuilder> TreeStatement parseFunctionDeclaration(TreeBuilder& );1014 template <class TreeBuilder> TreeStatement parseVariableDeclaration(TreeBuilder&, DeclarationType );1057 template <class TreeBuilder> TreeStatement parseFunctionDeclaration(TreeBuilder&, ExportType = ExportType::NotExported); 1058 template <class TreeBuilder> TreeStatement parseVariableDeclaration(TreeBuilder&, DeclarationType, ExportType = ExportType::NotExported); 1015 1059 template <class TreeBuilder> TreeStatement parseDoWhileStatement(TreeBuilder&); 1016 1060 template <class TreeBuilder> TreeStatement parseWhileStatement(TreeBuilder&); … … 1048 1092 template <class TreeBuilder> ALWAYS_INLINE bool parseFormalParameters(TreeBuilder&, TreeFormalParameterList, unsigned&); 1049 1093 enum VarDeclarationListContext { ForLoopContext, VarDeclarationContext }; 1050 template <class TreeBuilder> TreeExpression parseVariableDeclarationList(TreeBuilder&, int& declarations, TreeDestructuringPattern& lastPattern, TreeExpression& lastInitializer, JSTextPosition& identStart, JSTextPosition& initStart, JSTextPosition& initEnd, VarDeclarationListContext, DeclarationType, bool& forLoopConstDoesNotHaveInitializer);1094 template <class TreeBuilder> TreeExpression parseVariableDeclarationList(TreeBuilder&, int& declarations, TreeDestructuringPattern& lastPattern, TreeExpression& lastInitializer, JSTextPosition& identStart, JSTextPosition& initStart, JSTextPosition& initEnd, VarDeclarationListContext, DeclarationType, ExportType, bool& forLoopConstDoesNotHaveInitializer); 1051 1095 template <class TreeBuilder> TreeSourceElements parseArrowFunctionSingleExpressionBodySourceElements(TreeBuilder&); 1052 1096 template <class TreeBuilder> TreeExpression parseArrowFunctionExpression(TreeBuilder&); 1053 template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern createBindingPattern(TreeBuilder&, DestructuringKind, const Identifier&, int depth, JSToken, AssignmentContext, const Identifier** duplicateIdentifier);1054 template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern parseDestructuringPattern(TreeBuilder&, DestructuringKind, const Identifier** duplicateIdentifier = nullptr, bool* hasDestructuringPattern = nullptr, AssignmentContext = AssignmentContext::DeclarationStatement, int depth = 0);1097 template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern createBindingPattern(TreeBuilder&, DestructuringKind, ExportType, const Identifier&, int depth, JSToken, AssignmentContext, const Identifier** duplicateIdentifier); 1098 template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern parseDestructuringPattern(TreeBuilder&, DestructuringKind, ExportType, const Identifier** duplicateIdentifier = nullptr, bool* hasDestructuringPattern = nullptr, AssignmentContext = AssignmentContext::DeclarationStatement, int depth = 0); 1055 1099 template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern tryParseDestructuringPatternExpression(TreeBuilder&, AssignmentContext); 1056 1100 template <class TreeBuilder> NEVER_INLINE TreeExpression parseDefaultValueForDestructuringPattern(TreeBuilder&); 1101 template <class TreeBuilder> TreeSourceElements parseModuleSourceElements(TreeBuilder&); 1102 enum class ImportSpecifierType { NamespaceImport, NamedImport, DefaultImport }; 1103 template <class TreeBuilder> typename TreeBuilder::ImportSpecifier parseImportClauseItem(TreeBuilder&, ImportSpecifierType); 1104 template <class TreeBuilder> typename TreeBuilder::ModuleSpecifier parseModuleSpecifier(TreeBuilder&); 1105 template <class TreeBuilder> TreeStatement parseImportDeclaration(TreeBuilder&); 1106 template <class TreeBuilder> typename TreeBuilder::ExportSpecifier parseExportSpecifier(TreeBuilder& context, Vector<const Identifier*>& maybeLocalNames, bool& hasKeywordForLocalBindings); 1107 template <class TreeBuilder> TreeStatement parseExportDeclaration(TreeBuilder&); 1057 1108 1058 1109 template <class TreeBuilder> NEVER_INLINE bool parseFunctionInfo(TreeBuilder&, FunctionRequirements, FunctionParseMode, bool nameIsInContainingScope, ConstructorKind, SuperBinding, int functionKeywordStart, ParserFunctionInfo<TreeBuilder>&, FunctionParseType); … … 1182 1233 CodeFeatures m_features; 1183 1234 int m_numConstants; 1235 JSParserCodeType m_codeType; 1184 1236 1185 1237 struct DepthManager { -
TabularUnified trunk/Source/JavaScriptCore/parser/ParserModes.h ¶
r186959 r187890 34 34 enum class JSParserStrictMode { NotStrict, Strict }; 35 35 enum class JSParserBuiltinMode { NotBuiltin, Builtin }; 36 enum class JSParserCodeType { Program, Function };36 enum class JSParserCodeType { Program, Function, Module }; 37 37 38 38 enum class ConstructorKind { None, Base, Derived }; -
TabularUnified trunk/Source/JavaScriptCore/parser/ParserTokens.h ¶
r187763 r187890 77 77 DEBUGGER, 78 78 ELSE, 79 IMPORT, 80 EXPORT, 79 81 #if ENABLE(ES6_CLASS_SYNTAX) 80 82 CLASSTOKEN, -
TabularUnified trunk/Source/JavaScriptCore/parser/SyntaxChecker.h ¶
r187760 r187890 84 84 TemplateStringResult, TemplateStringListResult, 85 85 TemplateExpressionListResult, TemplateExpr, 86 TaggedTemplateExpr 86 TaggedTemplateExpr, 87 ModuleSpecifierResult, 88 ImportSpecifierResult, ImportSpecifierListResult, 89 ExportSpecifierResult, ExportSpecifierListResult 87 90 }; 88 91 typedef int ExpressionType; … … 125 128 typedef int ClassExpression; 126 129 #endif 130 typedef int ModuleSpecifier; 131 typedef int ImportSpecifier; 132 typedef int ImportSpecifierList; 133 typedef int ExportSpecifier; 134 typedef int ExportSpecifierList; 127 135 typedef int Statement; 128 136 typedef int ClauseList; … … 252 260 int createDebugger(const JSTokenLocation&, int, int) { return StatementResult; } 253 261 int createConstStatement(const JSTokenLocation&, int, int, int) { return StatementResult; } 262 int createModuleSpecifier(const JSTokenLocation&, const Identifier&) { return ModuleSpecifierResult; } 263 ImportSpecifier createImportSpecifier(const JSTokenLocation&, const Identifier&, const Identifier&) { return ImportSpecifierResult; } 264 ImportSpecifierList createImportSpecifierList() { return ImportSpecifierListResult; } 265 void appendImportSpecifier(ImportSpecifierList, ImportSpecifier) { } 266 int createImportDeclaration(const JSTokenLocation&, ImportSpecifierList, ModuleSpecifier) { return StatementResult; } 267 int createExportAllDeclaration(const JSTokenLocation&, ModuleSpecifier) { return StatementResult; } 268 int createExportDefaultDeclaration(const JSTokenLocation&, int) { return StatementResult; } 269 int createExportLocalDeclaration(const JSTokenLocation&, int) { return StatementResult; } 270 int createExportNamedDeclaration(const JSTokenLocation&, ExportSpecifierList, ModuleSpecifier) { return StatementResult; } 271 ExportSpecifier createExportSpecifier(const JSTokenLocation&, const Identifier&, const Identifier&) { return ExportSpecifierResult; } 272 ExportSpecifierList createExportSpecifierList() { return ExportSpecifierListResult; } 273 void appendExportSpecifier(ExportSpecifierList, ExportSpecifier) { } 274 254 275 int appendConstDecl(const JSTokenLocation&, int, const Identifier*, int) { return StatementResult; } 255 276 Property createGetterOrSetterProperty(const JSTokenLocation&, PropertyNode::Type type, bool strict, const Identifier* name, const ParserFunctionInfo<SyntaxChecker>&, SuperBinding) -
TabularUnified trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.cpp ¶
r184828 r187890 40 40 , thisIdentifier(Identifier::fromString(vm, "this")) 41 41 , useStrictIdentifier(Identifier::fromString(vm, "use strict")) 42 , timesIdentifier(Identifier::fromString(vm, "*")) 42 43 , m_builtinNames(new BuiltinNames(vm, this)) 43 44 JSC_COMMON_IDENTIFIERS_EACH_KEYWORD(INITIALIZE_KEYWORD) -
TabularUnified trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h ¶
r187575 r187890 73 73 macro(anonymous) \ 74 74 macro(arguments) \ 75 macro(as) \ 75 76 macro(assign) \ 76 77 macro(back) \ … … 113 114 macro(forEach) \ 114 115 macro(forward) \ 116 macro(from) \ 115 117 macro(fromCharCode) \ 116 118 macro(get) \ … … 320 322 const Identifier thisIdentifier; 321 323 const Identifier useStrictIdentifier; 324 const Identifier timesIdentifier; 322 325 private: 323 326 std::unique_ptr<BuiltinNames> m_builtinNames; -
TabularUnified trunk/Source/JavaScriptCore/runtime/Completion.cpp ¶
r186959 r187890 62 62 } 63 63 64 bool checkModuleSyntax(VM& vm, const SourceCode& source, ParserError& error) 65 { 66 JSLockHolder lock(vm); 67 RELEASE_ASSERT(vm.atomicStringTable() == wtfThreadData().atomicStringTable()); 68 return !!parse<ModuleProgramNode>( 69 &vm, source, Identifier(), JSParserBuiltinMode::NotBuiltin, 70 JSParserStrictMode::Strict, JSParserCodeType::Module, error); 71 } 72 64 73 JSValue evaluate(ExecState* exec, const SourceCode& source, JSValue thisValue, NakedPtr<Exception>& returnedException) 65 74 { -
TabularUnified trunk/Source/JavaScriptCore/runtime/Completion.h ¶
r185608 r187890 38 38 JS_EXPORT_PRIVATE bool checkSyntax(VM&, const SourceCode&, ParserError&); 39 39 JS_EXPORT_PRIVATE bool checkSyntax(ExecState*, const SourceCode&, JSValue* exception = 0); 40 JS_EXPORT_PRIVATE bool checkModuleSyntax(VM&, const SourceCode&, ParserError&); 40 41 JS_EXPORT_PRIVATE JSValue evaluate(ExecState*, const SourceCode&, JSValue thisValue, NakedPtr<Exception>& returnedException); 41 42 inline JSValue evaluate(ExecState* exec, const SourceCode& sourceCode, JSValue thisValue = JSValue()) -
TabularUnified trunk/Source/JavaScriptCore/tests/stress/tagged-templates-syntax.js ¶
r184337 r187890 67 67 testSyntax("(class extends Hello { constructor() { super()`${tag}${tag}` } })"); 68 68 69 testSyntaxError("super`Hello${tag}`", "SyntaxError: Cannot use super as tag for tagged templates.");69 testSyntaxError("super`Hello${tag}`", "SyntaxError: super is only valid inside functions."); 70 70 testSyntaxError("(class { say() { super`Hello${tag}` } })", "SyntaxError: Cannot use super as tag for tagged templates.");
Note:
See TracChangeset
for help on using the changeset viewer.