@@ -335,10 +335,10 @@ void Parser::Error(HRESULT hr, ParseNodePtr pnode)
335
335
}
336
336
}
337
337
338
- void Parser::Error (HRESULT hr, charcount_t ichMin, charcount_t ichLim)
338
+ void Parser::Error (HRESULT hr, charcount_t ichMin, charcount_t ichLim, LPCWSTR stringOne, LPCWSTR stringTwo )
339
339
{
340
340
this ->GetScanner ()->SetErrorPosition (ichMin, ichLim);
341
- Error (hr);
341
+ Error (hr, stringOne, stringTwo );
342
342
}
343
343
344
344
void Parser::IdentifierExpectedError (const Token& token)
@@ -2350,6 +2350,7 @@ void Parser::ParseNamedImportOrExportClause(ModuleImportOrExportEntryList* impor
2350
2350
2351
2351
IdentPtr identifierName = m_token.GetIdentifier (this ->GetHashTbl ());
2352
2352
IdentPtr identifierAs = identifierName;
2353
+ charcount_t offsetForError = this ->GetScanner ()->IchMinTok ();
2353
2354
2354
2355
this ->GetScanner ()->Scan ();
2355
2356
@@ -2392,19 +2393,16 @@ void Parser::ParseNamedImportOrExportClause(ModuleImportOrExportEntryList* impor
2392
2393
this ->GetScanner ()->Scan ();
2393
2394
}
2394
2395
2395
- if (buildAST)
2396
+ if (isExportClause)
2397
+ {
2398
+ identifierName->SetIsModuleExport ();
2399
+ AddModuleImportOrExportEntry (importOrExportEntryList, nullptr , identifierName, identifierAs, nullptr , offsetForError);
2400
+ }
2401
+ else if (buildAST)
2396
2402
{
2397
2403
// The name we will use 'as' this import/export is a binding identifier in import statements.
2398
- if (!isExportClause)
2399
- {
2400
- CreateModuleImportDeclNode (identifierAs);
2401
- AddModuleImportOrExportEntry (importOrExportEntryList, identifierName, identifierAs, nullptr , nullptr );
2402
- }
2403
- else
2404
- {
2405
- identifierName->SetIsModuleExport ();
2406
- AddModuleImportOrExportEntry (importOrExportEntryList, nullptr , identifierName, identifierAs, nullptr );
2407
- }
2404
+ CreateModuleImportDeclNode (identifierAs);
2405
+ AddModuleImportOrExportEntry (importOrExportEntryList, identifierName, identifierAs, nullptr , nullptr );
2408
2406
}
2409
2407
}
2410
2408
@@ -2417,6 +2415,23 @@ IdentPtrList* Parser::GetRequestedModulesList()
2417
2415
return m_currentNodeProg->AsParseNodeModule ()->requestedModules ;
2418
2416
}
2419
2417
2418
+ void Parser::VerifyModuleLocalExportEntries ()
2419
+ {
2420
+ ModuleImportOrExportEntryList* localExportRecordList = GetModuleLocalExportEntryList ();
2421
+ if (localExportRecordList != nullptr )
2422
+ {
2423
+ localExportRecordList->Map ([=](ModuleImportOrExportEntry exportEntry) {
2424
+ if (exportEntry.pidRefStack !=nullptr )
2425
+ {
2426
+ if (exportEntry.pidRefStack ->GetSym () == nullptr )
2427
+ {
2428
+ Error (ERRUndeclaredExportName, exportEntry.offset , exportEntry.localName ->Cch (), exportEntry.localName ->Psz ());
2429
+ }
2430
+ }
2431
+ });
2432
+ }
2433
+ }
2434
+
2420
2435
ModuleImportOrExportEntryList* Parser::GetModuleImportEntryList ()
2421
2436
{
2422
2437
return m_currentNodeProg->AsParseNodeModule ()->importEntries ;
@@ -2504,14 +2519,16 @@ ModuleImportOrExportEntry* Parser::AddModuleImportOrExportEntry(ModuleImportOrEx
2504
2519
return importOrExportEntry;
2505
2520
}
2506
2521
2507
- ModuleImportOrExportEntry* Parser::AddModuleImportOrExportEntry (ModuleImportOrExportEntryList* importOrExportEntryList, IdentPtr importName, IdentPtr localName, IdentPtr exportName, IdentPtr moduleRequest)
2522
+ ModuleImportOrExportEntry* Parser::AddModuleImportOrExportEntry (ModuleImportOrExportEntryList* importOrExportEntryList, IdentPtr importName, IdentPtr localName, IdentPtr exportName, IdentPtr moduleRequest, charcount_t offsetForError )
2508
2523
{
2509
2524
ModuleImportOrExportEntry* importOrExportEntry = Anew (&m_nodeAllocator, ModuleImportOrExportEntry);
2510
2525
2511
2526
importOrExportEntry->importName = importName;
2512
2527
importOrExportEntry->localName = localName;
2513
2528
importOrExportEntry->exportName = exportName;
2514
2529
importOrExportEntry->moduleRequest = moduleRequest;
2530
+ importOrExportEntry->pidRefStack = offsetForError == 0 ? nullptr : PushPidRef (localName);
2531
+ importOrExportEntry->offset = offsetForError;
2515
2532
2516
2533
return AddModuleImportOrExportEntry (importOrExportEntryList, importOrExportEntry);
2517
2534
}
@@ -12002,6 +12019,13 @@ ParseNodeProg * Parser::Parse(LPCUTF8 pszSrc, size_t offset, size_t length, char
12002
12019
{
12003
12020
JS_ETW (EventWriteJSCRIPT_PARSE_METHOD_STOP (m_sourceContextInfo->dwHostSourceContext , GetScriptContext (), pnodeProg->functionId , *m_pCurrentAstSize, false , Js::Constants::GlobalFunction));
12004
12021
}
12022
+
12023
+ if (isModuleSource)
12024
+ {
12025
+ // verify that any local module exports are defined
12026
+ VerifyModuleLocalExportEntries ();
12027
+ }
12028
+
12005
12029
return pnodeProg;
12006
12030
}
12007
12031
0 commit comments