Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(223)

Side by Side Diff: src/parser.cc

Issue 882893002: Implement ParseExportDeclaration per latest ES6 spec draft (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: git cl formatted except for test data arrays Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/parser.h ('k') | test/cctest/test-parsing.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/ast.h" 8 #include "src/ast.h"
9 #include "src/bailout-reason.h" 9 #include "src/bailout-reason.h"
10 #include "src/base/platform/platform.h" 10 #include "src/base/platform/platform.h"
(...skipping 1252 matching lines...) Expand 10 before | Expand all | Expand 10 after
1263 } 1263 }
1264 1264
1265 interface->MakeModule(ok); 1265 interface->MakeModule(ok);
1266 DCHECK(*ok); 1266 DCHECK(*ok);
1267 interface->Freeze(ok); 1267 interface->Freeze(ok);
1268 DCHECK(*ok); 1268 DCHECK(*ok);
1269 return factory()->NewModuleLiteral(body, interface, pos); 1269 return factory()->NewModuleLiteral(body, interface, pos);
1270 } 1270 }
1271 1271
1272 1272
1273 Module* Parser::ParseModuleUrl(bool* ok) { 1273 Module* Parser::ParseModuleSpecifier(bool* ok) {
1274 // Module: 1274 // Module:
1275 // String 1275 // String
1276 1276
1277 int pos = peek_position(); 1277 int pos = peek_position();
1278 Expect(Token::STRING, CHECK_OK); 1278 Expect(Token::STRING, CHECK_OK);
1279 const AstRawString* symbol = GetSymbol(scanner()); 1279 const AstRawString* symbol = GetSymbol(scanner());
1280 1280
1281 // TODO(ES6): Request JS resource from environment... 1281 // TODO(ES6): Request JS resource from environment...
1282 1282
1283 #ifdef DEBUG 1283 #ifdef DEBUG
1284 if (FLAG_print_interface_details) PrintF("# Url "); 1284 if (FLAG_print_interface_details) PrintF("# Url ");
1285 #endif 1285 #endif
1286 1286
1287 // Create an empty literal as long as the feature isn't finished. 1287 // Create an empty literal as long as the feature isn't finished.
1288 USE(symbol); 1288 USE(symbol);
1289 Scope* scope = NewScope(scope_, MODULE_SCOPE); 1289 Scope* scope = NewScope(scope_, MODULE_SCOPE);
1290 Block* body = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); 1290 Block* body = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
1291 body->set_scope(scope); 1291 body->set_scope(scope);
1292 Interface* interface = scope->interface(); 1292 Interface* interface = scope->interface();
1293 Module* result = factory()->NewModuleLiteral(body, interface, pos); 1293 Module* result = factory()->NewModuleLiteral(body, interface, pos);
1294 interface->Freeze(ok); 1294 interface->Freeze(ok);
1295 DCHECK(*ok); 1295 DCHECK(*ok);
1296 interface->Unify(scope->interface(), zone(), ok); 1296 interface->Unify(scope->interface(), zone(), ok);
1297 DCHECK(*ok); 1297 DCHECK(*ok);
1298 return result; 1298 return result;
1299 } 1299 }
1300 1300
1301 1301
1302 void* Parser::ParseModuleDeclarationClause(ZoneList<const AstRawString*>* names,
1303 bool* ok) {
1304 // Handles both imports and exports:
1305 //
1306 // ImportOrExportClause :
1307 // '{' '}'
1308 // '{' ImportOrExportsList '}'
1309 // '{' ImportOrExportsList ',' '}'
1310 //
1311 // ImportOrExportsList :
1312 // ImportOrExportSpecifier
1313 // ImportOrExportsList ',' ImportOrExportSpecifier
1314 //
1315 // ImportOrExportSpecifier :
1316 // IdentifierName
1317 // IdentifierName 'as' IdentifierName
1318
1319 Expect(Token::LBRACE, CHECK_OK);
1320
1321 while (peek() != Token::RBRACE) {
1322 const AstRawString* name = ParseIdentifierName(CHECK_OK);
1323 names->Add(name, zone());
1324 const AstRawString* export_name = NULL;
1325 if (CheckContextualKeyword(CStrVector("as"))) {
1326 export_name = ParseIdentifierName(CHECK_OK);
1327 }
1328 // TODO(ES6): Return the export_name as well as the name.
1329 USE(export_name);
1330 if (peek() == Token::RBRACE) break;
1331 Expect(Token::COMMA, CHECK_OK);
1332 }
1333
1334 Expect(Token::RBRACE, CHECK_OK);
1335
1336 return 0;
1337 }
1338
1339
1302 Statement* Parser::ParseImportDeclaration(bool* ok) { 1340 Statement* Parser::ParseImportDeclaration(bool* ok) {
1303 // ImportDeclaration: 1341 // ImportDeclaration:
1304 // 'import' IdentifierName (',' IdentifierName)* 'from' ModuleUrl ';' 1342 // 'import' IdentifierName (',' IdentifierName)* 'from' ModuleUrl ';'
1305 // 1343 //
1306 // TODO(ES6): implement current syntax 1344 // TODO(ES6): implement current syntax
1307 1345
1308 int pos = peek_position(); 1346 int pos = peek_position();
1309 Expect(Token::IMPORT, CHECK_OK); 1347 Expect(Token::IMPORT, CHECK_OK);
1310 ZoneList<const AstRawString*> names(1, zone()); 1348 ZoneList<const AstRawString*> names(1, zone());
1311 1349
1312 const AstRawString* name = ParseIdentifierName(CHECK_OK); 1350 const AstRawString* name = ParseIdentifierName(CHECK_OK);
1313 names.Add(name, zone()); 1351 names.Add(name, zone());
1314 while (peek() == Token::COMMA) { 1352 while (peek() == Token::COMMA) {
1315 Consume(Token::COMMA); 1353 Consume(Token::COMMA);
1316 name = ParseIdentifierName(CHECK_OK); 1354 name = ParseIdentifierName(CHECK_OK);
1317 names.Add(name, zone()); 1355 names.Add(name, zone());
1318 } 1356 }
1319 1357
1320 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); 1358 ExpectContextualKeyword(CStrVector("from"), CHECK_OK);
1321 Module* module = ParseModuleUrl(CHECK_OK); 1359 Module* module = ParseModuleSpecifier(CHECK_OK);
1322 ExpectSemicolon(CHECK_OK); 1360 ExpectSemicolon(CHECK_OK);
1323 1361
1324 // TODO(ES6): Do something with ParseModuleUrl's return value. 1362 // TODO(ES6): Do something with ParseModuleSpecifier's return value.
1325 USE(module); 1363 USE(module);
1326 1364
1327 for (int i = 0; i < names.length(); ++i) { 1365 for (int i = 0; i < names.length(); ++i) {
1328 // TODO(ES6): Add an appropriate declaration for each name 1366 // TODO(ES6): Add an appropriate declaration for each name
1329 } 1367 }
1330 1368
1331 return factory()->NewEmptyStatement(pos); 1369 return factory()->NewEmptyStatement(pos);
1332 } 1370 }
1333 1371
1334 1372
1373 Statement* Parser::ParseExportDefault(bool* ok) {
1374 // Supports the following productions, starting after the 'default' token:
1375 // 'export' 'default' FunctionDeclaration
1376 // 'export' 'default' ClassDeclaration
1377 // 'export' 'default' AssignmentExpression[In] ';'
1378
1379 Statement* result = NULL;
1380 switch (peek()) {
1381 case Token::FUNCTION:
1382 // TODO(ES6): Support parsing anonymous function declarations here.
1383 result = ParseFunctionDeclaration(NULL, CHECK_OK);
1384 break;
1385
1386 case Token::CLASS:
1387 // TODO(ES6): Support parsing anonymous class declarations here.
1388 result = ParseClassDeclaration(NULL, CHECK_OK);
1389 break;
1390
1391 default: {
1392 int pos = peek_position();
1393 Expression* expr = ParseAssignmentExpression(true, CHECK_OK);
1394 ExpectSemicolon(CHECK_OK);
1395 result = factory()->NewExpressionStatement(expr, pos);
1396 break;
1397 }
1398 }
1399
1400 // TODO(ES6): Add default export to scope_->interface()
1401
1402 return result;
1403 }
1404
1405
1335 Statement* Parser::ParseExportDeclaration(bool* ok) { 1406 Statement* Parser::ParseExportDeclaration(bool* ok) {
1336 // ExportDeclaration: 1407 // ExportDeclaration:
1337 // 'export' Identifier (',' Identifier)* ';' 1408 // 'export' '*' 'from' ModuleSpecifier ';'
1338 // 'export' VariableDeclaration 1409 // 'export' ExportClause ('from' ModuleSpecifier)? ';'
1339 // 'export' FunctionDeclaration 1410 // 'export' VariableStatement
1340 // 'export' GeneratorDeclaration 1411 // 'export' Declaration
1341 // 'export' ModuleDeclaration 1412 // 'export' 'default' ... (handled in ParseExportDefault)
1342 //
1343 // TODO(ES6): implement current syntax
1344 1413
1414 int pos = peek_position();
1345 Expect(Token::EXPORT, CHECK_OK); 1415 Expect(Token::EXPORT, CHECK_OK);
1346 1416
1347 Statement* result = NULL; 1417 Statement* result = NULL;
1348 ZoneList<const AstRawString*> names(1, zone()); 1418 ZoneList<const AstRawString*> names(1, zone());
1419 bool is_export_from = false;
1349 switch (peek()) { 1420 switch (peek()) {
1350 case Token::IDENTIFIER: { 1421 case Token::DEFAULT:
1351 int pos = position(); 1422 Consume(Token::DEFAULT);
1352 const AstRawString* name = 1423 return ParseExportDefault(ok);
1353 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); 1424
1354 names.Add(name, zone()); 1425 case Token::MUL: {
1355 while (peek() == Token::COMMA) { 1426 Consume(Token::MUL);
1356 Consume(Token::COMMA); 1427 ExpectContextualKeyword(CStrVector("from"), CHECK_OK);
1357 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); 1428 Module* module = ParseModuleSpecifier(CHECK_OK);
1358 names.Add(name, zone()); 1429 ExpectSemicolon(CHECK_OK);
1430 // TODO(ES6): Do something with the return value
1431 // of ParseModuleSpecifier.
1432 USE(module);
1433 is_export_from = true;
1434 result = factory()->NewEmptyStatement(pos);
1435 break;
1436 }
1437
1438 case Token::LBRACE:
1439 ParseModuleDeclarationClause(&names, CHECK_OK);
1440 if (CheckContextualKeyword(CStrVector("from"))) {
1441 Module* module = ParseModuleSpecifier(CHECK_OK);
1442 // TODO(ES6): Do something with the return value
1443 // of ParseModuleSpecifier.
1444 USE(module);
1445 is_export_from = true;
1359 } 1446 }
1360 ExpectSemicolon(CHECK_OK); 1447 ExpectSemicolon(CHECK_OK);
1361 result = factory()->NewEmptyStatement(pos); 1448 result = factory()->NewEmptyStatement(pos);
1362 break; 1449 break;
1363 }
1364 1450
1365 case Token::FUNCTION: 1451 case Token::FUNCTION:
1366 result = ParseFunctionDeclaration(&names, CHECK_OK); 1452 result = ParseFunctionDeclaration(&names, CHECK_OK);
1367 break; 1453 break;
1368 1454
1369 case Token::CLASS: 1455 case Token::CLASS:
1370 result = ParseClassDeclaration(&names, CHECK_OK); 1456 result = ParseClassDeclaration(&names, CHECK_OK);
1371 break; 1457 break;
1372 1458
1373 case Token::VAR: 1459 case Token::VAR:
(...skipping 14 matching lines...) Expand all
1388 if (var == NULL) { 1474 if (var == NULL) {
1389 // TODO(sigurds) This is an export that has no definition yet, 1475 // TODO(sigurds) This is an export that has no definition yet,
1390 // not clear what to do in this case. 1476 // not clear what to do in this case.
1391 continue; 1477 continue;
1392 } 1478 }
1393 if (!IsImmutableVariableMode(var->mode())) { 1479 if (!IsImmutableVariableMode(var->mode())) {
1394 var->set_maybe_assigned(); 1480 var->set_maybe_assigned();
1395 } 1481 }
1396 } 1482 }
1397 1483
1398 // Extract declared names into export declarations and interface. 1484 // TODO(ES6): Handle 'export from' once imports are properly implemented.
1399 Interface* interface = scope_->interface(); 1485 // For now we just drop such exports on the floor.
1400 for (int i = 0; i < names.length(); ++i) { 1486 if (!is_export_from) {
1487 // Extract declared names into export declarations and interface.
1488 Interface* interface = scope_->interface();
1489 for (int i = 0; i < names.length(); ++i) {
1401 #ifdef DEBUG 1490 #ifdef DEBUG
1402 if (FLAG_print_interface_details) 1491 if (FLAG_print_interface_details)
1403 PrintF("# Export %.*s ", names[i]->length(), names[i]->raw_data()); 1492 PrintF("# Export %.*s ", names[i]->length(), names[i]->raw_data());
1404 #endif 1493 #endif
1405 Interface* inner = Interface::NewUnknown(zone()); 1494 Interface* inner = Interface::NewUnknown(zone());
1406 interface->Add(names[i], inner, zone(), CHECK_OK); 1495 interface->Add(names[i], inner, zone(), CHECK_OK);
1407 if (!*ok) 1496 if (!*ok) return NULL;
1408 return NULL; 1497 VariableProxy* proxy = NewUnresolved(names[i], LET, inner);
1409 VariableProxy* proxy = NewUnresolved(names[i], LET, inner); 1498 USE(proxy);
1410 USE(proxy); 1499 // TODO(rossberg): Rethink whether we actually need to store export
1411 // TODO(rossberg): Rethink whether we actually need to store export 1500 // declarations (for compilation?).
1412 // declarations (for compilation?). 1501 // ExportDeclaration* declaration =
1413 // ExportDeclaration* declaration = 1502 // factory()->NewExportDeclaration(proxy, scope_, position);
1414 // factory()->NewExportDeclaration(proxy, scope_, position); 1503 // scope_->AddDeclaration(declaration);
1415 // scope_->AddDeclaration(declaration); 1504 }
1416 } 1505 }
1417 1506
1418 DCHECK(result != NULL); 1507 DCHECK(result != NULL);
1419 return result; 1508 return result;
1420 } 1509 }
1421 1510
1422 1511
1423 Statement* Parser::ParseStatement(ZoneList<const AstRawString*>* labels, 1512 Statement* Parser::ParseStatement(ZoneList<const AstRawString*>* labels,
1424 bool* ok) { 1513 bool* ok) {
1425 // Statement :: 1514 // Statement ::
(...skipping 3717 matching lines...) Expand 10 before | Expand all | Expand 10 after
5143 } else { 5232 } else {
5144 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data()); 5233 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data());
5145 running_hash = StringHasher::ComputeRunningHash(running_hash, data, 5234 running_hash = StringHasher::ComputeRunningHash(running_hash, data,
5146 raw_string->length()); 5235 raw_string->length());
5147 } 5236 }
5148 } 5237 }
5149 5238
5150 return running_hash; 5239 return running_hash;
5151 } 5240 }
5152 } } // namespace v8::internal 5241 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | test/cctest/test-parsing.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698