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

Side by Side Diff: src/parser.cc

Issue 881623002: Begin modernization of --harmony-modules (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 11 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
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 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 DCHECK(info_->cached_data() != NULL); 258 DCHECK(info_->cached_data() != NULL);
259 if (compile_options() == ScriptCompiler::kConsumeParserCache) { 259 if (compile_options() == ScriptCompiler::kConsumeParserCache) {
260 cached_parse_data_ = ParseData::FromCachedData(*info_->cached_data()); 260 cached_parse_data_ = ParseData::FromCachedData(*info_->cached_data());
261 } 261 }
262 } 262 }
263 } 263 }
264 264
265 265
266 Scope* Parser::NewScope(Scope* parent, ScopeType scope_type) { 266 Scope* Parser::NewScope(Scope* parent, ScopeType scope_type) {
267 DCHECK(ast_value_factory()); 267 DCHECK(ast_value_factory());
268 DCHECK(scope_type != MODULE_SCOPE || allow_harmony_modules());
268 Scope* result = new (zone()) 269 Scope* result = new (zone())
269 Scope(isolate(), zone(), parent, scope_type, ast_value_factory()); 270 Scope(isolate(), zone(), parent, scope_type, ast_value_factory());
270 result->Initialize(); 271 result->Initialize();
271 return result; 272 return result;
272 } 273 }
273 274
274 275
275 FunctionLiteral* Parser::DefaultConstructor(bool call_super, Scope* scope, 276 FunctionLiteral* Parser::DefaultConstructor(bool call_super, Scope* scope,
276 int pos, int end_pos) { 277 int pos, int end_pos) {
277 int materialized_literal_count = -1; 278 int materialized_literal_count = -1;
(...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after
927 928
928 // Enters 'scope'. 929 // Enters 'scope'.
929 AstNodeFactory function_factory(ast_value_factory()); 930 AstNodeFactory function_factory(ast_value_factory());
930 FunctionState function_state(&function_state_, &scope_, *scope, 931 FunctionState function_state(&function_state_, &scope_, *scope,
931 &function_factory); 932 &function_factory);
932 933
933 scope_->SetStrictMode(info->strict_mode()); 934 scope_->SetStrictMode(info->strict_mode());
934 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); 935 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone());
935 bool ok = true; 936 bool ok = true;
936 int beg_pos = scanner()->location().beg_pos; 937 int beg_pos = scanner()->location().beg_pos;
937 ParseSourceElements(body, Token::EOS, info->is_eval(), true, eval_scope, 938 if (info->is_module()) {
938 &ok); 939 DCHECK(allow_harmony_modules());
940 Module* module = ParseModule(&ok);
941 if (ok) {
942 // TODO(adamk): Do something with returned Module
943 CHECK(module);
944 body->Add(factory()->NewEmptyStatement(RelocInfo::kNoPosition), zone());
945 }
946 } else {
947 ParseStatementList(body, Token::EOS, info->is_eval(), eval_scope, &ok);
948 }
939 949
940 if (ok && strict_mode() == STRICT) { 950 if (ok && strict_mode() == STRICT) {
941 CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); 951 CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok);
942 } 952 }
943 953
944 if (ok && allow_harmony_scoping() && strict_mode() == STRICT) { 954 if (ok && allow_harmony_scoping() && strict_mode() == STRICT) {
945 CheckConflictingVarDeclarations(scope_, &ok); 955 CheckConflictingVarDeclarations(scope_, &ok);
946 } 956 }
947 957
948 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { 958 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) {
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
1073 DCHECK(target_stack_ == NULL); 1083 DCHECK(target_stack_ == NULL);
1074 1084
1075 if (result != NULL) { 1085 if (result != NULL) {
1076 Handle<String> inferred_name(shared_info->inferred_name()); 1086 Handle<String> inferred_name(shared_info->inferred_name());
1077 result->set_inferred_name(inferred_name); 1087 result->set_inferred_name(inferred_name);
1078 } 1088 }
1079 return result; 1089 return result;
1080 } 1090 }
1081 1091
1082 1092
1083 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, 1093 void* Parser::ParseStatementList(ZoneList<Statement*>* body, int end_token,
1084 int end_token, bool is_eval, bool is_global, 1094 bool is_eval, Scope** eval_scope, bool* ok) {
1085 Scope** eval_scope, bool* ok) { 1095 // StatementList ::
1086 // SourceElements :: 1096 // (StatementListItem)* <end_token>
1087 // (ModuleElement)* <end_token>
1088 1097
1089 // Allocate a target stack to use for this set of source 1098 // Allocate a target stack to use for this set of source
1090 // elements. This way, all scripts and functions get their own 1099 // elements. This way, all scripts and functions get their own
1091 // target stack thus avoiding illegal breaks and continues across 1100 // target stack thus avoiding illegal breaks and continues across
1092 // functions. 1101 // functions.
1093 TargetScope scope(&this->target_stack_); 1102 TargetScope scope(&this->target_stack_);
1094 1103
1095 DCHECK(processor != NULL); 1104 DCHECK(body != NULL);
1096 bool directive_prologue = true; // Parsing directive prologue. 1105 bool directive_prologue = true; // Parsing directive prologue.
1097 1106
1098 while (peek() != end_token) { 1107 while (peek() != end_token) {
1099 if (directive_prologue && peek() != Token::STRING) { 1108 if (directive_prologue && peek() != Token::STRING) {
1100 directive_prologue = false; 1109 directive_prologue = false;
1101 } 1110 }
1102 1111
1103 Scanner::Location token_loc = scanner()->peek_location(); 1112 Scanner::Location token_loc = scanner()->peek_location();
1104 Statement* stat; 1113 Statement* stat = ParseStatementListItem(CHECK_OK);
1105 if (is_global && !is_eval) {
1106 stat = ParseModuleElement(NULL, CHECK_OK);
1107 } else {
1108 stat = ParseBlockElement(NULL, CHECK_OK);
1109 }
1110 if (stat == NULL || stat->IsEmpty()) { 1114 if (stat == NULL || stat->IsEmpty()) {
1111 directive_prologue = false; // End of directive prologue. 1115 directive_prologue = false; // End of directive prologue.
1112 continue; 1116 continue;
1113 } 1117 }
1114 1118
1115 if (directive_prologue) { 1119 if (directive_prologue) {
1116 // A shot at a directive. 1120 // A shot at a directive.
1117 ExpressionStatement* e_stat; 1121 ExpressionStatement* e_stat;
1118 Literal* literal; 1122 Literal* literal;
1119 // Still processing directive prologue? 1123 // Still processing directive prologue?
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1155 // incremented after parsing is done. 1159 // incremented after parsing is done.
1156 ++use_counts_[v8::Isolate::kUseAsm]; 1160 ++use_counts_[v8::Isolate::kUseAsm];
1157 scope_->SetAsmModule(); 1161 scope_->SetAsmModule();
1158 } 1162 }
1159 } else { 1163 } else {
1160 // End of the directive prologue. 1164 // End of the directive prologue.
1161 directive_prologue = false; 1165 directive_prologue = false;
1162 } 1166 }
1163 } 1167 }
1164 1168
1165 processor->Add(stat, zone()); 1169 body->Add(stat, zone());
1166 } 1170 }
1167 1171
1168 return 0; 1172 return 0;
1169 } 1173 }
1170 1174
1171 1175
1172 Statement* Parser::ParseModuleElement(ZoneList<const AstRawString*>* labels, 1176 Statement* Parser::ParseStatementListItem(bool* ok) {
1173 bool* ok) { 1177 // (Ecma 262 6th Edition, 13.1):
1174 // (Ecma 262 5th Edition, clause 14): 1178 // StatementListItem:
1175 // SourceElement:
1176 // Statement 1179 // Statement
1177 // FunctionDeclaration 1180 // Declaration
1178 //
1179 // In harmony mode we allow additionally the following productions
1180 // ModuleElement:
1181 // LetDeclaration
1182 // ConstDeclaration
1183 // ModuleDeclaration
1184 // ImportDeclaration
1185 // ExportDeclaration
1186 // GeneratorDeclaration
1187 1181
1188 switch (peek()) { 1182 switch (peek()) {
1189 case Token::FUNCTION: 1183 case Token::FUNCTION:
1190 return ParseFunctionDeclaration(NULL, ok); 1184 return ParseFunctionDeclaration(NULL, ok);
1191 case Token::CLASS: 1185 case Token::CLASS:
1192 return ParseClassDeclaration(NULL, ok); 1186 return ParseClassDeclaration(NULL, ok);
1187 case Token::CONST:
1188 case Token::VAR:
1189 return ParseVariableStatement(kStatementListItem, NULL, ok);
1190 case Token::LET:
1191 DCHECK(allow_harmony_scoping());
1192 if (strict_mode() == STRICT) {
1193 return ParseVariableStatement(kStatementListItem, NULL, ok);
1194 }
1195 // Fall through.
1196 default:
1197 return ParseStatement(NULL, ok);
1198 }
1199 }
1200
1201
1202 Statement* Parser::ParseModuleItem(bool* ok) {
1203 // (Ecma 262 6th Edition, 15.2):
1204 // ModuleItem :
1205 // ImportDeclaration
1206 // ExportDeclaration
1207 // StatementListItem
1208
1209 switch (peek()) {
1193 case Token::IMPORT: 1210 case Token::IMPORT:
1194 return ParseImportDeclaration(ok); 1211 return ParseImportDeclaration(ok);
1195 case Token::EXPORT: 1212 case Token::EXPORT:
1196 return ParseExportDeclaration(ok); 1213 return ParseExportDeclaration(ok);
1197 case Token::CONST: 1214 default:
1198 return ParseVariableStatement(kModuleElement, NULL, ok); 1215 return ParseStatementListItem(ok);
1199 case Token::LET:
1200 DCHECK(allow_harmony_scoping());
1201 if (strict_mode() == STRICT) {
1202 return ParseVariableStatement(kModuleElement, NULL, ok);
1203 }
1204 // Fall through.
1205 default: {
1206 Statement* stmt = ParseStatement(labels, CHECK_OK);
1207 // Handle 'module' as a context-sensitive keyword.
1208 if (FLAG_harmony_modules &&
1209 peek() == Token::IDENTIFIER &&
1210 !scanner()->HasAnyLineTerminatorBeforeNext() &&
1211 stmt != NULL) {
1212 ExpressionStatement* estmt = stmt->AsExpressionStatement();
1213 if (estmt != NULL && estmt->expression()->AsVariableProxy() != NULL &&
1214 estmt->expression()->AsVariableProxy()->raw_name() ==
1215 ast_value_factory()->module_string() &&
1216 !scanner()->literal_contains_escapes()) {
1217 return ParseModuleDeclaration(NULL, ok);
1218 }
1219 }
1220 return stmt;
1221 }
1222 } 1216 }
1223 } 1217 }
1224 1218
1225 1219
1226 Statement* Parser::ParseModuleDeclaration(ZoneList<const AstRawString*>* names,
1227 bool* ok) {
1228 // ModuleDeclaration:
1229 // 'module' Identifier Module
1230
1231 int pos = peek_position();
1232 const AstRawString* name =
1233 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
1234
1235 #ifdef DEBUG
1236 if (FLAG_print_interface_details)
1237 PrintF("# Module %.*s ", name->length(), name->raw_data());
1238 #endif
1239
1240 Module* module = ParseModule(CHECK_OK);
1241 VariableProxy* proxy = NewUnresolved(name, MODULE, module->interface());
1242 Declaration* declaration =
1243 factory()->NewModuleDeclaration(proxy, module, scope_, pos);
1244 Declare(declaration, true, CHECK_OK);
1245
1246 #ifdef DEBUG
1247 if (FLAG_print_interface_details)
1248 PrintF("# Module %.*s ", name->length(), name->raw_data());
1249 if (FLAG_print_interfaces) {
1250 PrintF("module %.*s: ", name->length(), name->raw_data());
1251 module->interface()->Print();
1252 }
1253 #endif
1254
1255 if (names) names->Add(name, zone());
1256 if (module->body() == NULL)
1257 return factory()->NewEmptyStatement(pos);
1258 else
1259 return factory()->NewModuleStatement(proxy, module->body(), pos);
1260 }
1261
1262
1263 Module* Parser::ParseModule(bool* ok) { 1220 Module* Parser::ParseModule(bool* ok) {
1264 // Module: 1221 // (Ecma 262 6th Edition, 15.2):
1265 // '{' ModuleElement '}' 1222 // Module :
1266 // '=' ModulePath ';' 1223 // ModuleBody?
1267 // 'at' String ';' 1224 //
1268 1225 // ModuleBody :
1269 switch (peek()) { 1226 // ModuleItem*
1270 case Token::LBRACE:
1271 return ParseModuleLiteral(ok);
1272
1273 case Token::ASSIGN: {
1274 Expect(Token::ASSIGN, CHECK_OK);
1275 Module* result = ParseModulePath(CHECK_OK);
1276 ExpectSemicolon(CHECK_OK);
1277 return result;
1278 }
1279
1280 default: {
1281 ExpectContextualKeyword(CStrVector("at"), CHECK_OK);
1282 Module* result = ParseModuleUrl(CHECK_OK);
1283 ExpectSemicolon(CHECK_OK);
1284 return result;
1285 }
1286 }
1287 }
1288
1289
1290 Module* Parser::ParseModuleLiteral(bool* ok) {
1291 // Module:
1292 // '{' ModuleElement '}'
1293 1227
1294 int pos = peek_position(); 1228 int pos = peek_position();
1295 // Construct block expecting 16 statements. 1229 // Construct block expecting 16 statements.
1296 Block* body = factory()->NewBlock(NULL, 16, false, RelocInfo::kNoPosition); 1230 Block* body = factory()->NewBlock(NULL, 16, false, RelocInfo::kNoPosition);
1297 #ifdef DEBUG 1231 #ifdef DEBUG
1298 if (FLAG_print_interface_details) PrintF("# Literal "); 1232 if (FLAG_print_interface_details) PrintF("# Literal ");
1299 #endif 1233 #endif
1300 Scope* scope = NewScope(scope_, MODULE_SCOPE); 1234 Scope* scope = NewScope(scope_, MODULE_SCOPE);
1301 1235
1302 Expect(Token::LBRACE, CHECK_OK);
1303 scope->set_start_position(scanner()->location().beg_pos); 1236 scope->set_start_position(scanner()->location().beg_pos);
1304 scope->SetStrictMode(STRICT); 1237 scope->SetStrictMode(STRICT);
1305 1238
1306 { 1239 {
1307 BlockState block_state(&scope_, scope); 1240 BlockState block_state(&scope_, scope);
1308 Target target(&this->target_stack_, body); 1241 Target target(&this->target_stack_, body);
1309 1242
1310 while (peek() != Token::RBRACE) { 1243 while (peek() != Token::EOS) {
1311 Statement* stat = ParseModuleElement(NULL, CHECK_OK); 1244 Statement* stat = ParseModuleItem(CHECK_OK);
1312 if (stat && !stat->IsEmpty()) { 1245 if (stat && !stat->IsEmpty()) {
1313 body->AddStatement(stat, zone()); 1246 body->AddStatement(stat, zone());
1314 } 1247 }
1315 } 1248 }
1316 } 1249 }
1317 1250
1318 Expect(Token::RBRACE, CHECK_OK);
1319 scope->set_end_position(scanner()->location().end_pos); 1251 scope->set_end_position(scanner()->location().end_pos);
1320 body->set_scope(scope); 1252 body->set_scope(scope);
1321 1253
1322 // Check that all exports are bound. 1254 // Check that all exports are bound.
1323 Interface* interface = scope->interface(); 1255 Interface* interface = scope->interface();
1324 for (Interface::Iterator it = interface->iterator(); 1256 for (Interface::Iterator it = interface->iterator();
1325 !it.done(); it.Advance()) { 1257 !it.done(); it.Advance()) {
1326 if (scope->LookupLocal(it.name()) == NULL) { 1258 if (scope->LookupLocal(it.name()) == NULL) {
1327 ParserTraits::ReportMessage("module_export_undefined", it.name()); 1259 ParserTraits::ReportMessage("module_export_undefined", it.name());
1328 *ok = false; 1260 *ok = false;
1329 return NULL; 1261 return NULL;
1330 } 1262 }
1331 } 1263 }
1332 1264
1333 interface->MakeModule(ok); 1265 interface->MakeModule(ok);
1334 DCHECK(*ok); 1266 DCHECK(*ok);
1335 interface->Freeze(ok); 1267 interface->Freeze(ok);
1336 DCHECK(*ok); 1268 DCHECK(*ok);
1337 return factory()->NewModuleLiteral(body, interface, pos); 1269 return factory()->NewModuleLiteral(body, interface, pos);
1338 } 1270 }
1339 1271
1340 1272
1341 Module* Parser::ParseModulePath(bool* ok) {
1342 // ModulePath:
1343 // Identifier
1344 // ModulePath '.' Identifier
1345
1346 int pos = peek_position();
1347 Module* result = ParseModuleVariable(CHECK_OK);
1348 while (Check(Token::PERIOD)) {
1349 const AstRawString* name = ParseIdentifierName(CHECK_OK);
1350 #ifdef DEBUG
1351 if (FLAG_print_interface_details)
1352 PrintF("# Path .%.*s ", name->length(), name->raw_data());
1353 #endif
1354 Module* member = factory()->NewModulePath(result, name, pos);
1355 result->interface()->Add(name, member->interface(), zone(), ok);
1356 if (!*ok) {
1357 #ifdef DEBUG
1358 if (FLAG_print_interfaces) {
1359 PrintF("PATH TYPE ERROR at '%.*s'\n", name->length(), name->raw_data());
1360 PrintF("result: ");
1361 result->interface()->Print();
1362 PrintF("member: ");
1363 member->interface()->Print();
1364 }
1365 #endif
1366 ParserTraits::ReportMessage("invalid_module_path", name);
1367 return NULL;
1368 }
1369 result = member;
1370 }
1371
1372 return result;
1373 }
1374
1375
1376 Module* Parser::ParseModuleVariable(bool* ok) { 1273 Module* Parser::ParseModuleVariable(bool* ok) {
rossberg 2015/01/27 20:00:56 Is this still used?
adamk 2015/01/27 20:11:02 No, it's not. I thought it might be useful for "im
1377 // ModulePath: 1274 // ModulePath:
1378 // Identifier 1275 // Identifier
1379 1276
1380 int pos = peek_position(); 1277 int pos = peek_position();
1381 const AstRawString* name = 1278 const AstRawString* name =
1382 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); 1279 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
1383 #ifdef DEBUG 1280 #ifdef DEBUG
1384 if (FLAG_print_interface_details) 1281 if (FLAG_print_interface_details)
1385 PrintF("# Module variable %.*s ", name->length(), name->raw_data()); 1282 PrintF("# Module variable %.*s ", name->length(), name->raw_data());
1386 #endif 1283 #endif
(...skipping 27 matching lines...) Expand all
1414 Interface* interface = scope->interface(); 1311 Interface* interface = scope->interface();
1415 Module* result = factory()->NewModuleLiteral(body, interface, pos); 1312 Module* result = factory()->NewModuleLiteral(body, interface, pos);
1416 interface->Freeze(ok); 1313 interface->Freeze(ok);
1417 DCHECK(*ok); 1314 DCHECK(*ok);
1418 interface->Unify(scope->interface(), zone(), ok); 1315 interface->Unify(scope->interface(), zone(), ok);
1419 DCHECK(*ok); 1316 DCHECK(*ok);
1420 return result; 1317 return result;
1421 } 1318 }
1422 1319
1423 1320
1424 Module* Parser::ParseModuleSpecifier(bool* ok) { 1321 Statement* Parser::ParseImportDeclaration(bool* ok) {
1425 // ModuleSpecifier:
1426 // String
1427 // ModulePath
1428
1429 if (peek() == Token::STRING) {
1430 return ParseModuleUrl(ok);
1431 } else {
1432 return ParseModulePath(ok);
1433 }
1434 }
1435
1436
1437 Block* Parser::ParseImportDeclaration(bool* ok) {
1438 // ImportDeclaration: 1322 // ImportDeclaration:
1439 // 'import' IdentifierName (',' IdentifierName)* 'from' ModuleSpecifier ';' 1323 // 'import' IdentifierName (',' IdentifierName)* 'from' ModuleUrl ';'
1440 // 1324 //
1441 // TODO(ES6): implement destructuring ImportSpecifiers 1325 // TODO(ES6): implement current syntax
1442 1326
1443 int pos = peek_position(); 1327 int pos = peek_position();
1444 Expect(Token::IMPORT, CHECK_OK); 1328 Expect(Token::IMPORT, CHECK_OK);
1445 ZoneList<const AstRawString*> names(1, zone()); 1329 ZoneList<const AstRawString*> names(1, zone());
1446 1330
1447 const AstRawString* name = ParseIdentifierName(CHECK_OK); 1331 const AstRawString* name = ParseIdentifierName(CHECK_OK);
1448 names.Add(name, zone()); 1332 names.Add(name, zone());
1449 while (peek() == Token::COMMA) { 1333 while (peek() == Token::COMMA) {
1450 Consume(Token::COMMA); 1334 Consume(Token::COMMA);
1451 name = ParseIdentifierName(CHECK_OK); 1335 name = ParseIdentifierName(CHECK_OK);
1452 names.Add(name, zone()); 1336 names.Add(name, zone());
1453 } 1337 }
1454 1338
1455 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); 1339 ExpectContextualKeyword(CStrVector("from"), CHECK_OK);
1456 Module* module = ParseModuleSpecifier(CHECK_OK); 1340 Module* module = ParseModuleUrl(CHECK_OK);
arv (Not doing code reviews) 2015/01/27 01:17:17 This is fine for now but this should not return a
adamk 2015/01/27 01:58:37 Yeah, the API probably just needs to match ParseSt
1457 ExpectSemicolon(CHECK_OK); 1341 ExpectSemicolon(CHECK_OK);
1458 1342
1459 // Generate a separate declaration for each identifier. 1343 // TODO(ES6): Do something with ParseModuleUrl's return value.
1460 // TODO(ES6): once we implement destructuring, make that one declaration. 1344 USE(module);
1461 Block* block = factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition); 1345
1462 for (int i = 0; i < names.length(); ++i) { 1346 for (int i = 0; i < names.length(); ++i) {
1463 #ifdef DEBUG 1347 // TODO(ES6): Add a let declaration for each name
rossberg 2015/01/27 20:00:55 Nit: misleading comment, as imports cannot be let-
adamk 2015/01/27 20:11:02 Fair enough, s/let/appropriate/
1464 if (FLAG_print_interface_details)
1465 PrintF("# Import %.*s ", name->length(), name->raw_data());
1466 #endif
1467 Interface* interface = Interface::NewUnknown(zone());
1468 module->interface()->Add(names[i], interface, zone(), ok);
1469 if (!*ok) {
1470 #ifdef DEBUG
1471 if (FLAG_print_interfaces) {
1472 PrintF("IMPORT TYPE ERROR at '%.*s'\n", name->length(),
1473 name->raw_data());
1474 PrintF("module: ");
1475 module->interface()->Print();
1476 }
1477 #endif
1478 ParserTraits::ReportMessage("invalid_module_path", name);
1479 return NULL;
1480 }
1481 VariableProxy* proxy = NewUnresolved(names[i], LET, interface);
1482 Declaration* declaration =
1483 factory()->NewImportDeclaration(proxy, module, scope_, pos);
1484 Declare(declaration, true, CHECK_OK);
1485 } 1348 }
1486 1349
1487 return block; 1350 return factory()->NewEmptyStatement(pos);
1488 } 1351 }
1489 1352
1490 1353
1491 Statement* Parser::ParseExportDeclaration(bool* ok) { 1354 Statement* Parser::ParseExportDeclaration(bool* ok) {
1492 // ExportDeclaration: 1355 // ExportDeclaration:
1493 // 'export' Identifier (',' Identifier)* ';' 1356 // 'export' Identifier (',' Identifier)* ';'
1494 // 'export' VariableDeclaration 1357 // 'export' VariableDeclaration
1495 // 'export' FunctionDeclaration 1358 // 'export' FunctionDeclaration
1496 // 'export' GeneratorDeclaration 1359 // 'export' GeneratorDeclaration
1497 // 'export' ModuleDeclaration 1360 // 'export' ModuleDeclaration
1498 // 1361 //
1499 // TODO(ES6): implement structuring ExportSpecifiers 1362 // TODO(ES6): implement current syntax
1500 1363
1501 Expect(Token::EXPORT, CHECK_OK); 1364 Expect(Token::EXPORT, CHECK_OK);
1502 1365
1503 Statement* result = NULL; 1366 Statement* result = NULL;
1504 ZoneList<const AstRawString*> names(1, zone()); 1367 ZoneList<const AstRawString*> names(1, zone());
1505 switch (peek()) { 1368 switch (peek()) {
1506 case Token::IDENTIFIER: { 1369 case Token::IDENTIFIER: {
1507 int pos = position(); 1370 int pos = position();
1508 const AstRawString* name = 1371 const AstRawString* name =
1509 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); 1372 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
1510 // Handle 'module' as a context-sensitive keyword. 1373 names.Add(name, zone());
1511 if (name != ast_value_factory()->module_string()) { 1374 while (peek() == Token::COMMA) {
1375 Consume(Token::COMMA);
1376 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
1512 names.Add(name, zone()); 1377 names.Add(name, zone());
1513 while (peek() == Token::COMMA) {
1514 Consume(Token::COMMA);
1515 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
1516 names.Add(name, zone());
1517 }
1518 ExpectSemicolon(CHECK_OK);
1519 result = factory()->NewEmptyStatement(pos);
1520 } else {
1521 result = ParseModuleDeclaration(&names, CHECK_OK);
1522 } 1378 }
1379 ExpectSemicolon(CHECK_OK);
1380 result = factory()->NewEmptyStatement(pos);
1523 break; 1381 break;
1524 } 1382 }
1525 1383
1526 case Token::FUNCTION: 1384 case Token::FUNCTION:
1527 result = ParseFunctionDeclaration(&names, CHECK_OK); 1385 result = ParseFunctionDeclaration(&names, CHECK_OK);
1528 break; 1386 break;
1529 1387
1530 case Token::CLASS: 1388 case Token::CLASS:
1531 result = ParseClassDeclaration(&names, CHECK_OK); 1389 result = ParseClassDeclaration(&names, CHECK_OK);
1532 break; 1390 break;
1533 1391
1534 case Token::VAR: 1392 case Token::VAR:
1535 case Token::LET: 1393 case Token::LET:
1536 case Token::CONST: 1394 case Token::CONST:
1537 result = ParseVariableStatement(kModuleElement, &names, CHECK_OK); 1395 result = ParseVariableStatement(kStatementListItem, &names, CHECK_OK);
1538 break; 1396 break;
1539 1397
1540 default: 1398 default:
1541 *ok = false; 1399 *ok = false;
1542 ReportUnexpectedToken(scanner()->current_token()); 1400 ReportUnexpectedToken(scanner()->current_token());
1543 return NULL; 1401 return NULL;
1544 } 1402 }
1545 1403
1546 // Every export of a module may be assigned. 1404 // Every export of a module may be assigned.
1547 for (int i = 0; i < names.length(); ++i) { 1405 for (int i = 0; i < names.length(); ++i) {
(...skipping 26 matching lines...) Expand all
1574 // ExportDeclaration* declaration = 1432 // ExportDeclaration* declaration =
1575 // factory()->NewExportDeclaration(proxy, scope_, position); 1433 // factory()->NewExportDeclaration(proxy, scope_, position);
1576 // scope_->AddDeclaration(declaration); 1434 // scope_->AddDeclaration(declaration);
1577 } 1435 }
1578 1436
1579 DCHECK(result != NULL); 1437 DCHECK(result != NULL);
1580 return result; 1438 return result;
1581 } 1439 }
1582 1440
1583 1441
1584 Statement* Parser::ParseBlockElement(ZoneList<const AstRawString*>* labels,
1585 bool* ok) {
1586 // (Ecma 262 5th Edition, clause 14):
1587 // SourceElement:
1588 // Statement
1589 // FunctionDeclaration
1590 //
1591 // In harmony mode we allow additionally the following productions
1592 // BlockElement (aka SourceElement):
1593 // LetDeclaration
1594 // ConstDeclaration
1595 // GeneratorDeclaration
1596 // ClassDeclaration
1597
1598 switch (peek()) {
1599 case Token::FUNCTION:
1600 return ParseFunctionDeclaration(NULL, ok);
1601 case Token::CLASS:
1602 return ParseClassDeclaration(NULL, ok);
1603 case Token::CONST:
1604 return ParseVariableStatement(kModuleElement, NULL, ok);
1605 case Token::LET:
1606 DCHECK(allow_harmony_scoping());
1607 if (strict_mode() == STRICT) {
1608 return ParseVariableStatement(kModuleElement, NULL, ok);
1609 }
1610 // Fall through.
1611 default:
1612 return ParseStatement(labels, ok);
1613 }
1614 }
1615
1616
1617 Statement* Parser::ParseStatement(ZoneList<const AstRawString*>* labels, 1442 Statement* Parser::ParseStatement(ZoneList<const AstRawString*>* labels,
1618 bool* ok) { 1443 bool* ok) {
1619 // Statement :: 1444 // Statement ::
1620 // Block 1445 // Block
1621 // VariableStatement 1446 // VariableStatement
1622 // EmptyStatement 1447 // EmptyStatement
1623 // ExpressionStatement 1448 // ExpressionStatement
1624 // IfStatement 1449 // IfStatement
1625 // IterationStatement 1450 // IterationStatement
1626 // ContinueStatement 1451 // ContinueStatement
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after
2060 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); 1885 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition);
2061 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE); 1886 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
2062 1887
2063 // Parse the statements and collect escaping labels. 1888 // Parse the statements and collect escaping labels.
2064 Expect(Token::LBRACE, CHECK_OK); 1889 Expect(Token::LBRACE, CHECK_OK);
2065 block_scope->set_start_position(scanner()->location().beg_pos); 1890 block_scope->set_start_position(scanner()->location().beg_pos);
2066 { BlockState block_state(&scope_, block_scope); 1891 { BlockState block_state(&scope_, block_scope);
2067 Target target(&this->target_stack_, body); 1892 Target target(&this->target_stack_, body);
2068 1893
2069 while (peek() != Token::RBRACE) { 1894 while (peek() != Token::RBRACE) {
2070 Statement* stat = ParseBlockElement(NULL, CHECK_OK); 1895 Statement* stat = ParseStatementListItem(CHECK_OK);
2071 if (stat && !stat->IsEmpty()) { 1896 if (stat && !stat->IsEmpty()) {
2072 body->AddStatement(stat, zone()); 1897 body->AddStatement(stat, zone());
2073 } 1898 }
2074 } 1899 }
2075 } 1900 }
2076 Expect(Token::RBRACE, CHECK_OK); 1901 Expect(Token::RBRACE, CHECK_OK);
2077 block_scope->set_end_position(scanner()->location().end_pos); 1902 block_scope->set_end_position(scanner()->location().end_pos);
2078 block_scope = block_scope->FinalizeBlockScope(); 1903 block_scope = block_scope->FinalizeBlockScope();
2079 body->set_scope(block_scope); 1904 body->set_scope(block_scope);
2080 return body; 1905 return body;
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after
2475 // no line-terminator between the two words. 2300 // no line-terminator between the two words.
2476 if (extension_ != NULL && peek() == Token::FUNCTION && 2301 if (extension_ != NULL && peek() == Token::FUNCTION &&
2477 !scanner()->HasAnyLineTerminatorBeforeNext() && expr != NULL && 2302 !scanner()->HasAnyLineTerminatorBeforeNext() && expr != NULL &&
2478 expr->AsVariableProxy() != NULL && 2303 expr->AsVariableProxy() != NULL &&
2479 expr->AsVariableProxy()->raw_name() == 2304 expr->AsVariableProxy()->raw_name() ==
2480 ast_value_factory()->native_string() && 2305 ast_value_factory()->native_string() &&
2481 !scanner()->literal_contains_escapes()) { 2306 !scanner()->literal_contains_escapes()) {
2482 return ParseNativeDeclaration(ok); 2307 return ParseNativeDeclaration(ok);
2483 } 2308 }
2484 2309
2485 // Parsed expression statement, or the context-sensitive 'module' keyword. 2310 // Parsed expression statement, followed by semicolon.
2486 // Only expect semicolon in the former case.
2487 // Also detect attempts at 'let' declarations in sloppy mode. 2311 // Also detect attempts at 'let' declarations in sloppy mode.
rossberg 2015/01/27 20:00:56 Nit: remove the "also"
adamk 2015/01/27 20:11:02 Done.
2488 if (!FLAG_harmony_modules || peek() != Token::IDENTIFIER || 2312 if (peek() == Token::IDENTIFIER && expr->AsVariableProxy() != NULL &&
2489 scanner()->HasAnyLineTerminatorBeforeNext() || 2313 expr->AsVariableProxy()->raw_name() ==
2490 expr->AsVariableProxy() == NULL || 2314 ast_value_factory()->let_string()) {
2491 expr->AsVariableProxy()->raw_name() != 2315 ReportMessage("sloppy_lexical", NULL);
2492 ast_value_factory()->module_string() || 2316 *ok = false;
2493 scanner()->literal_contains_escapes()) { 2317 return NULL;
2494 if (peek() == Token::IDENTIFIER && expr->AsVariableProxy() != NULL &&
2495 expr->AsVariableProxy()->raw_name() ==
2496 ast_value_factory()->let_string()) {
2497 ReportMessage("sloppy_lexical", NULL);
2498 *ok = false;
2499 return NULL;
2500 }
2501 ExpectSemicolon(CHECK_OK);
2502 } 2318 }
2319 ExpectSemicolon(CHECK_OK);
2503 return factory()->NewExpressionStatement(expr, pos); 2320 return factory()->NewExpressionStatement(expr, pos);
2504 } 2321 }
2505 2322
2506 2323
2507 IfStatement* Parser::ParseIfStatement(ZoneList<const AstRawString*>* labels, 2324 IfStatement* Parser::ParseIfStatement(ZoneList<const AstRawString*>* labels,
2508 bool* ok) { 2325 bool* ok) {
2509 // IfStatement :: 2326 // IfStatement ::
2510 // 'if' '(' Expression ')' Statement ('else' Statement)? 2327 // 'if' '(' Expression ')' Statement ('else' Statement)?
2511 2328
2512 int pos = peek_position(); 2329 int pos = peek_position();
(...skipping 1393 matching lines...) Expand 10 before | Expand all | Expand 10 after
3906 Assignment* assignment = factory()->NewAssignment( 3723 Assignment* assignment = factory()->NewAssignment(
3907 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition); 3724 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition);
3908 VariableProxy* get_proxy = factory()->NewVariableProxy( 3725 VariableProxy* get_proxy = factory()->NewVariableProxy(
3909 function_state_->generator_object_variable()); 3726 function_state_->generator_object_variable());
3910 Yield* yield = factory()->NewYield( 3727 Yield* yield = factory()->NewYield(
3911 get_proxy, assignment, Yield::kInitial, RelocInfo::kNoPosition); 3728 get_proxy, assignment, Yield::kInitial, RelocInfo::kNoPosition);
3912 body->Add(factory()->NewExpressionStatement( 3729 body->Add(factory()->NewExpressionStatement(
3913 yield, RelocInfo::kNoPosition), zone()); 3730 yield, RelocInfo::kNoPosition), zone());
3914 } 3731 }
3915 3732
3916 ParseSourceElements(body, Token::RBRACE, false, false, NULL, CHECK_OK); 3733 ParseStatementList(body, Token::RBRACE, false, NULL, CHECK_OK);
3917 3734
3918 if (is_generator) { 3735 if (is_generator) {
3919 VariableProxy* get_proxy = factory()->NewVariableProxy( 3736 VariableProxy* get_proxy = factory()->NewVariableProxy(
3920 function_state_->generator_object_variable()); 3737 function_state_->generator_object_variable());
3921 Expression* undefined = 3738 Expression* undefined =
3922 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition); 3739 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition);
3923 Yield* yield = factory()->NewYield(get_proxy, undefined, Yield::kFinal, 3740 Yield* yield = factory()->NewYield(get_proxy, undefined, Yield::kFinal,
3924 RelocInfo::kNoPosition); 3741 RelocInfo::kNoPosition);
3925 body->Add(factory()->NewExpressionStatement( 3742 body->Add(factory()->NewExpressionStatement(
3926 yield, RelocInfo::kNoPosition), zone()); 3743 yield, RelocInfo::kNoPosition), zone());
(...skipping 1418 matching lines...) Expand 10 before | Expand all | Expand 10 after
5345 } else { 5162 } else {
5346 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data()); 5163 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data());
5347 running_hash = StringHasher::ComputeRunningHash(running_hash, data, 5164 running_hash = StringHasher::ComputeRunningHash(running_hash, data,
5348 raw_string->length()); 5165 raw_string->length());
5349 } 5166 }
5350 } 5167 }
5351 5168
5352 return running_hash; 5169 return running_hash;
5353 } 5170 }
5354 } } // namespace v8::internal 5171 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/scopes.cc » ('j') | test/cctest/test-parsing.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698