Changeset 179371 in webkit for trunk/Source/JavaScriptCore/parser/Parser.cpp
- Timestamp:
- Jan 29, 2015, 2:59:19 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/parser/Parser.cpp
r179159 r179371 1151 1151 result = parseConstDeclaration(context); 1152 1152 break; 1153 #if ENABLE(ES6_CLASS_SYNTAX) 1154 case CLASSTOKEN: 1155 failIfFalse(m_statementDepth == 1, "Class declaration is not allowed in a lexically nested statement"); 1156 result = parseClassDeclaration(context); 1157 break; 1158 #endif 1153 1159 case FUNCTION: 1154 1160 failIfFalseIfStrict(m_statementDepth == 1, "Strict mode does not allow function declarations in a lexically nested statement"); … … 1268 1274 case FunctionMode: 1269 1275 return "function"; 1276 #if ENABLE(ES6_CLASS_SYNTAX) 1277 case MethodMode: 1278 return "method"; 1279 #endif 1270 1280 } 1271 1281 RELEASE_ASSERT_NOT_REACHED(); … … 1404 1414 return context.createFuncDeclStatement(location, info, functionKeywordStart); 1405 1415 } 1416 1417 #if ENABLE(ES6_CLASS_SYNTAX) 1418 template <typename LexerType> 1419 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseClassDeclaration(TreeBuilder& context) 1420 { 1421 ASSERT(match(CLASSTOKEN)); 1422 JSTokenLocation location(tokenLocation()); 1423 JSTextPosition classStart = tokenStartPosition(); 1424 unsigned classStartLine = tokenLine(); 1425 1426 TreeClassExpression classExpr = parseClass(context, FunctionNeedsName); 1427 failIfFalse(classExpr, "Failed to parse class"); 1428 1429 JSTextPosition classEnd = lastTokenEndPosition(); 1430 unsigned classEndLine = tokenLine(); 1431 1432 return context.createClassDeclStatement(location, classExpr, classStart, classEnd, classStartLine, classEndLine); 1433 } 1434 1435 template <typename LexerType> 1436 template <class TreeBuilder> TreeClassExpression Parser<LexerType>::parseClass(TreeBuilder& context, FunctionRequirements requirements) 1437 { 1438 ASSERT(match(CLASSTOKEN)); 1439 JSTokenLocation location(tokenLocation()); 1440 next(); 1441 1442 AutoPopScopeRef classScope(this, pushScope()); 1443 classScope->setStrictMode(); 1444 1445 const Identifier* className = nullptr; 1446 if (match(IDENT)) { 1447 className = m_token.m_data.ident; 1448 next(); 1449 failIfFalse(classScope->declareVariable(className), "'", className->impl(), "' is not a valid class name"); 1450 } else if (requirements == FunctionNeedsName) { 1451 semanticFailureDueToKeyword("class name"); 1452 failDueToUnexpectedToken(); 1453 } else 1454 className = &m_vm->propertyNames->nullIdentifier; 1455 ASSERT(className); 1456 1457 TreeExpression parentClass = 0; 1458 if (consume(EXTENDS)) { 1459 parentClass = parsePrimaryExpression(context); 1460 failIfFalse(parentClass, "Cannot parse the parent class name"); 1461 failWithMessage("Inheritance is not supported yet"); 1462 } 1463 1464 consumeOrFailWithFlags(OPENBRACE, TreeBuilder::DontBuildStrings, "Expected opening '{' at the start of a class body"); 1465 1466 TreeExpression constructor = 0; 1467 TreePropertyList staticMethods = 0; 1468 TreePropertyList instanceMethods = 0; 1469 TreePropertyList instanceMethodsTail = 0; 1470 TreePropertyList staticMethodsTail = 0; 1471 while (!match(CLOSEBRACE)) { 1472 if (match(SEMICOLON)) 1473 next(); 1474 1475 JSTokenLocation methodLocation(tokenLocation()); 1476 unsigned methodStart = tokenStart(); 1477 1478 bool isStaticMethod = match(STATICTOKEN); 1479 if (isStaticMethod) 1480 next(); 1481 1482 matchOrFail(IDENT, "Expected an indentifier"); 1483 1484 const CommonIdentifiers& propertyNames = *m_vm->propertyNames; 1485 const Identifier& ident = *m_token.m_data.ident; 1486 bool isGetter = ident == propertyNames.get; 1487 bool isSetter = ident == propertyNames.set; 1488 1489 TreeProperty property; 1490 const bool alwaysStrictInsideClass = true; 1491 if (isGetter || isSetter) { 1492 semanticFailIfTrue(isStaticMethod, "Cannot declare a static", stringForFunctionMode(isGetter ? GetterMode : SetterMode)); 1493 nextExpectIdentifier(LexerFlagsIgnoreReservedWords); 1494 property = parseGetterSetter(context, alwaysStrictInsideClass, isGetter ? PropertyNode::Getter : PropertyNode::Setter, methodStart); 1495 failIfFalse(property, "Cannot parse this method"); 1496 } else { 1497 ParserFunctionInfo<TreeBuilder> methodInfo; 1498 failIfFalse((parseFunctionInfo(context, FunctionNeedsName, FunctionMode, false, methodInfo)), "Cannot parse this method"); 1499 failIfFalse(methodInfo.name, "method must have a name"); 1500 failIfFalse(declareVariable(methodInfo.name), "Cannot declare a method named '", methodInfo.name->impl(), "'"); 1501 1502 bool isConstructor = !isStaticMethod && *methodInfo.name == propertyNames.constructor; 1503 if (isConstructor) 1504 methodInfo.name = className; 1505 1506 TreeExpression method = context.createFunctionExpr(methodLocation, methodInfo, methodStart); 1507 if (isConstructor) { 1508 semanticFailIfTrue(constructor, "Cannot declare multiple constructors in a single class"); 1509 constructor = method; 1510 continue; 1511 } 1512 1513 // FIXME: Syntax error when super() is called 1514 semanticFailIfTrue(isStaticMethod && *methodInfo.name == propertyNames.prototype, 1515 "Cannot declare a static method named 'prototype'"); 1516 property = context.createProperty(methodInfo.name, method, PropertyNode::Constant, alwaysStrictInsideClass); 1517 } 1518 1519 TreePropertyList& tail = isStaticMethod ? staticMethodsTail : instanceMethodsTail; 1520 if (tail) 1521 tail = context.createPropertyList(methodLocation, property, tail); 1522 else { 1523 tail = context.createPropertyList(methodLocation, property); 1524 if (isStaticMethod) 1525 staticMethods = tail; 1526 else 1527 instanceMethods = tail; 1528 } 1529 } 1530 1531 // FIXME: Create a Miranda function instead. 1532 semanticFailIfFalse(constructor, "Class declaration without a constructor is not supported yet"); 1533 1534 consumeOrFail(CLOSEBRACE, "Expected a closing '}' after a class body"); 1535 1536 return context.createClassExpr(location, *className, constructor, parentClass, instanceMethods, staticMethods); 1537 } 1538 #endif 1406 1539 1407 1540 struct LabelInfo { … … 1803 1936 else 1804 1937 failWithMessage("Expected a ':' following the property name '", ident->impl(), "'"); 1805 const Identifier* stringPropertyName = 0; 1806 double numericPropertyName = 0; 1807 if (m_token.m_type == IDENT || m_token.m_type == STRING) 1808 stringPropertyName = m_token.m_data.ident; 1809 else if (m_token.m_type == NUMBER) 1810 numericPropertyName = m_token.m_data.doubleValue; 1811 else 1812 failDueToUnexpectedToken(); 1813 JSTokenLocation location(tokenLocation()); 1814 next(); 1815 ParserFunctionInfo<TreeBuilder> info; 1816 if (type == PropertyNode::Getter) { 1817 failIfFalse(match(OPENPAREN), "Expected a parameter list for getter definition"); 1818 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, GetterMode, false, info)), "Cannot parse getter definition"); 1819 } else { 1820 failIfFalse(match(OPENPAREN), "Expected a parameter list for setter definition"); 1821 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, SetterMode, false, info)), "Cannot parse setter definition"); 1822 } 1823 if (stringPropertyName) 1824 return context.createGetterOrSetterProperty(location, type, complete, stringPropertyName, info, getterOrSetterStartOffset); 1825 return context.createGetterOrSetterProperty(const_cast<VM*>(m_vm), m_parserArena, location, type, complete, numericPropertyName, info, getterOrSetterStartOffset); 1938 return parseGetterSetter(context, complete, type, getterOrSetterStartOffset); 1826 1939 } 1827 1940 case NUMBER: { … … 1850 1963 goto namedProperty; 1851 1964 } 1965 } 1966 1967 template <typename LexerType> 1968 template <class TreeBuilder> TreeProperty Parser<LexerType>::parseGetterSetter(TreeBuilder& context, bool strict, PropertyNode::Type type, unsigned getterOrSetterStartOffset) 1969 { 1970 const Identifier* stringPropertyName = 0; 1971 double numericPropertyName = 0; 1972 if (m_token.m_type == IDENT || m_token.m_type == STRING) 1973 stringPropertyName = m_token.m_data.ident; 1974 else if (m_token.m_type == NUMBER) 1975 numericPropertyName = m_token.m_data.doubleValue; 1976 else 1977 failDueToUnexpectedToken(); 1978 JSTokenLocation location(tokenLocation()); 1979 next(); 1980 ParserFunctionInfo<TreeBuilder> info; 1981 if (type == PropertyNode::Getter) { 1982 failIfFalse(match(OPENPAREN), "Expected a parameter list for getter definition"); 1983 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, GetterMode, false, info)), "Cannot parse getter definition"); 1984 } else { 1985 failIfFalse(match(OPENPAREN), "Expected a parameter list for setter definition"); 1986 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, SetterMode, false, info)), "Cannot parse setter definition"); 1987 } 1988 if (stringPropertyName) 1989 return context.createGetterOrSetterProperty(location, type, strict, stringPropertyName, info, getterOrSetterStartOffset); 1990 return context.createGetterOrSetterProperty(const_cast<VM*>(m_vm), m_parserArena, location, type, strict, numericPropertyName, info, getterOrSetterStartOffset); 1852 1991 } 1853 1992 … … 2037 2176 return context.createFunctionExpr(location, info, functionKeywordStart); 2038 2177 } 2178 #if ENABLE(ES6_CLASS_SYNTAX) 2179 case CLASSTOKEN: 2180 return parseClass(context, FunctionNoRequirements); 2181 #endif 2039 2182 case OPENBRACE: 2040 2183 if (strictMode())
Note:
See TracChangeset
for help on using the changeset viewer.