Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Source/JavaScriptCore/parser/NodesAnalyzeModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,9 @@ bool ImportDeclarationNode::analyzeModule(ModuleAnalyzer& analyzer)
m_moduleName->moduleName(),
specifier->importedName(),
specifier->localName(),
#if USE(BUN_JSC_ADDITIONS)
static_cast<unsigned>(std::max(0, specifier->startOffset())),
#endif
});
}
return true;
Expand Down
3 changes: 3 additions & 0 deletions Source/JavaScriptCore/runtime/AbstractModuleRecord.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ class AbstractModuleRecord : public JSInternalFieldObjectImpl<2> {
Identifier moduleRequest;
Identifier importName;
Identifier localName;
#if USE(BUN_JSC_ADDITIONS)
unsigned sourceOffset { 0 };
#endif
};

using OrderedIdentifierSet = OrderedHashSet<RefPtr<UniquedStringImpl>, IdentifierRepHash>;
Expand Down
63 changes: 55 additions & 8 deletions Source/JavaScriptCore/runtime/CyclicModuleRecord.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,53 @@ void CyclicModuleRecord::initializeEnvironment(JSGlobalObject* globalObject, Ref
ASSERT(jsModule);
#endif

#if USE(BUN_JSC_ADDITIONS)
auto throwLinkSyntaxError = [&](String&& message, unsigned sourceOffset = 0) {
JSObject* error = createSyntaxError(globalObject, message);
auto attrs = static_cast<unsigned>(PropertyAttribute::DontEnum);
unsigned line = 0;
unsigned column = 0;
String sourceURL;
if (jsModule && jsModule->sourceCode().provider()) {
auto& sourceCode = jsModule->sourceCode();
sourceURL = sourceCode.provider()->sourceURL();
if (sourceOffset) {
StringView source = sourceCode.provider()->source();
unsigned end = std::min<unsigned>(sourceOffset, source.length());
unsigned lineStart = 0;
line = sourceCode.firstLine().oneBasedInt();
for (unsigned i = 0; i < end; ++i) {
auto c = source[i];
if (c == '\r' || c == '\n' || c == 0x2028 || c == 0x2029) {
++line;
if (c == '\r' && i + 1 < end && source[i + 1] == '\n')
++i;
lineStart = i + 1;
}
}
Comment thread
robobun marked this conversation as resolved.
column = end - lineStart + 1;
}
}
if (sourceURL.isEmpty())
sourceURL = moduleKey().string();
if (auto* errorInstance = dynamicDowncast<ErrorInstance>(error)) {
if (!sourceURL.isEmpty())
errorInstance->setSourceURL(sourceURL);
if (line) {
errorInstance->setLine(line);
errorInstance->setColumn(column);
}
}
if (!sourceURL.isEmpty())
error->putDirect(vm, vm.propertyNames->sourceURL, jsString(vm, WTF::move(sourceURL)), attrs);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@robobun don't set both here. just set the one.

if (line) {
error->putDirect(vm, vm.propertyNames->line, jsNumber(line), attrs);
error->putDirect(vm, vm.propertyNames->column, jsNumber(column), attrs);
}
throwException(globalObject, scope, error);
};
#endif

ModuleProgramExecutable* moduleProgramExecutable = nullptr;
JSModuleEnvironment* env = nullptr;

Expand All @@ -106,23 +153,23 @@ void CyclicModuleRecord::initializeEnvironment(JSGlobalObject* globalObject, Ref
case Resolution::Type::NotFound:
#if USE(BUN_JSC_ADDITIONS)
if (m_isTypeScript) break;
throwSyntaxError(globalObject, scope, makeString("export '"_s, StringView(e.exportName.impl()), "' not found in '"_s, StringView(e.moduleName.impl()), "'"_s));
throwLinkSyntaxError(makeString("export '"_s, StringView(e.exportName.impl()), "' not found in '"_s, StringView(e.moduleName.impl()), "'"_s));
#else
throwSyntaxError(globalObject, scope, makeString("Indirectly exported binding name '"_s, StringView(e.exportName.impl()), "' is not found."_s));
#endif
return;

case Resolution::Type::Ambiguous:
#if USE(BUN_JSC_ADDITIONS)
throwSyntaxError(globalObject, scope, makeString("Cannot export '"_s, StringView(e.exportName.impl()), "' multiple times in '"_s, StringView(e.moduleName.impl()), "'"_s));
throwLinkSyntaxError(makeString("Cannot export '"_s, StringView(e.exportName.impl()), "' multiple times in '"_s, StringView(e.moduleName.impl()), "'"_s));
#else
throwSyntaxError(globalObject, scope, makeString("Indirectly exported binding name '"_s, StringView(e.exportName.impl()), "' cannot be resolved due to ambiguous multiple bindings."_s));
#endif
return;

case Resolution::Type::Error:
#if USE(BUN_JSC_ADDITIONS)
throwSyntaxError(globalObject, scope, "export default cannot be used with export *"_s);
throwLinkSyntaxError("export default cannot be used with export *"_s);
#else
throwSyntaxError(globalObject, scope, "Indirectly exported binding name 'default' cannot be resolved by star export entries."_s);
#endif
Expand Down Expand Up @@ -209,19 +256,19 @@ void CyclicModuleRecord::initializeEnvironment(JSGlobalObject* globalObject, Ref
Resolution otherResolution = importedModule->resolveExport(globalObject, vm.propertyNames->defaultKeyword);
RETURN_IF_EXCEPTION(scope, void());
if (otherResolution.type == Resolution::Type::Resolved && otherResolution.localName == in.localName) {
throwSyntaxError(globalObject, scope, makeString("Export named '"_s, in.importName.string(), "' not found in module '"_s, importedModule->moduleKey().string(), "'. Did you mean to import default?"_s));
throwLinkSyntaxError(makeString("Export named '"_s, in.importName.string(), "' not found in module '"_s, importedModule->moduleKey().string(), "'. Did you mean to import default?"_s), in.sourceOffset);
return;
}
}
throwSyntaxError(globalObject, scope, makeString("Export named '"_s, in.importName.string(), "' not found in module '"_s, importedModule->moduleKey().string(), "'."_s));
throwLinkSyntaxError(makeString("Export named '"_s, in.importName.string(), "' not found in module '"_s, importedModule->moduleKey().string(), "'."_s), in.sourceOffset);
#else
throwSyntaxError(globalObject, scope, makeString("Importing binding name '"_s, StringView(in.importName.impl()), "' is not found."_s));
#endif
return;

case Resolution::Type::Ambiguous:
#if USE(BUN_JSC_ADDITIONS)
throwSyntaxError(globalObject, scope, makeString("Export named '"_s, in.importName.string(), "' cannot be resolved due to ambiguous multiple bindings in module '"_s, importedModule->moduleKey().string(), "'."_s));
throwLinkSyntaxError(makeString("Export named '"_s, in.importName.string(), "' cannot be resolved due to ambiguous multiple bindings in module '"_s, importedModule->moduleKey().string(), "'."_s), in.sourceOffset);
#else
throwSyntaxError(globalObject, scope, makeString("Importing binding name '"_s, StringView(in.importName.impl()), "' cannot be resolved due to ambiguous multiple bindings."_s));
#endif
Expand All @@ -233,11 +280,11 @@ void CyclicModuleRecord::initializeEnvironment(JSGlobalObject* globalObject, Ref
Resolution otherResolution = importedModule->resolveExport(globalObject, in.localName);
RETURN_IF_EXCEPTION(scope, void());
if (otherResolution.type == Resolution::Type::Resolved) {
throwSyntaxError(globalObject, scope, makeString("module '"_s, importedModule->moduleKey().string(), "' does not have an export named 'default'. Did you mean '"_s, String(in.localName.impl()), "'?"_s));
throwLinkSyntaxError(makeString("module '"_s, importedModule->moduleKey().string(), "' does not have an export named 'default'. Did you mean '"_s, String(in.localName.impl()), "'?"_s), in.sourceOffset);
return;
}
}
throwSyntaxError(globalObject, scope, makeString("Missing 'default' export in module '"_s, importedModule->moduleKey().string(), "'."_s));
throwLinkSyntaxError(makeString("Missing 'default' export in module '"_s, importedModule->moduleKey().string(), "'."_s), in.sourceOffset);
#else
throwSyntaxError(globalObject, scope, "Importing binding name 'default' cannot be resolved by star export entries."_s);
#endif
Expand Down
Loading