Changeset 187890 in webkit for trunk/Source/JavaScriptCore/parser/Parser.cpp
- Timestamp:
- Aug 4, 2015, 2:26:49 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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();
Note:
See TracChangeset
for help on using the changeset viewer.