in lib/Parser/JSParserImpl-flow.cpp [705:881]
Optional<ESTree::Node *> JSParserImpl::parseDeclareExportFlow(
SMLoc start,
AllowDeclareExportType allowDeclareExportType) {
assert(check(TokenKind::rw_export));
advance(JSLexer::GrammarContext::Type);
SMLoc declareStart = tok_->getStartLoc();
if (checkAndEat(TokenKind::rw_default, JSLexer::GrammarContext::Type)) {
declareStart = tok_->getStartLoc();
if (check(TokenKind::rw_function)) {
auto optFunc = parseDeclareFunctionFlow(declareStart);
if (!optFunc)
return None;
return setLocation(
start,
*optFunc,
new (context_) ESTree::DeclareExportDeclarationNode(
*optFunc, {}, nullptr, true));
}
if (check(TokenKind::rw_class)) {
auto optClass = parseDeclareClassFlow(declareStart);
if (!optClass)
return None;
return setLocation(
start,
*optClass,
new (context_) ESTree::DeclareExportDeclarationNode(
*optClass, {}, nullptr, true));
}
auto optType = parseTypeAnnotationFlow();
if (!optType)
return None;
if (!eatSemi())
return None;
return setLocation(
start,
getPrevTokenEndLoc(),
new (context_)
ESTree::DeclareExportDeclarationNode(*optType, {}, nullptr, true));
}
if (check(TokenKind::rw_function)) {
auto optFunc = parseDeclareFunctionFlow(declareStart);
if (!optFunc)
return None;
return setLocation(
start,
*optFunc,
new (context_)
ESTree::DeclareExportDeclarationNode(*optFunc, {}, nullptr, false));
}
if (check(TokenKind::rw_class)) {
auto optClass = parseDeclareClassFlow(declareStart);
if (!optClass)
return None;
return setLocation(
start,
*optClass,
new (context_) ESTree::DeclareExportDeclarationNode(
*optClass, {}, nullptr, false));
}
if (check(TokenKind::rw_var)) {
SMLoc varStart = advance(JSLexer::GrammarContext::Type).Start;
auto optIdent = parseBindingIdentifier(Param{});
if (!optIdent) {
errorExpected(
TokenKind::identifier,
"in var declaration",
"start of declaration",
start);
return None;
}
if (!eatSemi())
return None;
SMLoc end = getPrevTokenEndLoc();
return setLocation(
start,
end,
new (context_) ESTree::DeclareExportDeclarationNode(
setLocation(
varStart,
end,
new (context_) ESTree::DeclareVariableNode(*optIdent)),
{},
nullptr,
false));
}
if (checkAndEat(opaqueIdent_, JSLexer::GrammarContext::Type)) {
if (!check(typeIdent_)) {
error(tok_->getStartLoc(), "'type' required in opaque type declaration");
return None;
}
advance(JSLexer::GrammarContext::Type);
auto optType =
parseTypeAliasFlow(declareStart, TypeAliasKind::DeclareOpaque);
if (!optType)
return None;
return setLocation(
start,
*optType,
new (context_)
ESTree::DeclareExportDeclarationNode(*optType, {}, nullptr, false));
}
if (allowDeclareExportType == AllowDeclareExportType::Yes &&
check(typeIdent_)) {
advance(JSLexer::GrammarContext::Type);
auto optType = parseTypeAliasFlow(declareStart, TypeAliasKind::None);
if (!optType)
return None;
return setLocation(
start,
*optType,
new (context_)
ESTree::DeclareExportDeclarationNode(*optType, {}, nullptr, false));
}
if (checkN(TokenKind::rw_interface, interfaceIdent_)) {
auto optInterface = parseInterfaceDeclarationFlow();
if (!optInterface)
return None;
return setLocation(
start,
*optInterface,
new (context_) ESTree::DeclareExportDeclarationNode(
*optInterface, {}, nullptr, false));
}
if (checkAndEat(TokenKind::star, JSLexer::GrammarContext::Type)) {
// declare export * from 'foo';
// ^
if (!check(fromIdent_)) {
error(
tok_->getStartLoc(), "expected 'from' clause in export declaration");
return None;
}
auto optSource = parseFromClause();
if (!optSource)
return None;
if (!eatSemi())
return None;
return setLocation(
start,
getPrevTokenEndLoc(),
new (context_) ESTree::DeclareExportAllDeclarationNode(*optSource));
}
if (!need(
TokenKind::l_brace, "in export specifier", "start of declare", start))
return None;
ESTree::NodeList specifiers{};
llvh::SmallVector<SMRange, 2> invalids{};
if (!parseExportClause(specifiers, invalids))
return None;
ESTree::Node *source = nullptr;
if (check(fromIdent_)) {
auto optSource = parseFromClause();
if (!optSource)
return None;
source = *optSource;
}
if (!eatSemi())
return None;
return setLocation(
start,
getPrevTokenEndLoc(),
new (context_) ESTree::DeclareExportDeclarationNode(
nullptr, std::move(specifiers), source, false));
}