in AjaxMinDll/JavaScript/jsparser.cs [2453:2621]
private AstNode ParseExport()
{
// we know we're parsing an ES6 export
ParsedVersion = ScriptVersion.EcmaScript6;
var exportNode = new ExportNode(m_currentToken.Clone())
{
KeywordContext = m_currentToken.Clone(),
};
GetNextToken();
if (m_currentToken.IsOne(JSToken.Var, JSToken.Const, JSToken.Let, JSToken.Function, JSToken.Class))
{
// export var/const/let/funcdecl/classdecl
var declaration = ParseStatement(true, true);
if (declaration != null)
{
exportNode.Append(declaration);
}
else
{
// this shouldn't happen -- we already had the right token, so why didn't it parse???
// we probably already output another error, but throw a syntax error here, just in case.
ReportError(JSError.SyntaxError);
}
}
else if (m_currentToken.Is(JSToken.Default))
{
// export default assignmentexpression ;
exportNode.IsDefault = true;
exportNode.DefaultContext = m_currentToken.Clone();
exportNode.Context.UpdateWith(m_currentToken);
GetNextToken();
var expression = ParseExpression(true);
if (expression != null)
{
exportNode.Append(expression);
}
else
{
ReportError(JSError.ExpressionExpected);
}
ExpectSemicolon(exportNode);
}
else
{
if (m_currentToken.Is(JSToken.Identifier) || JSKeyword.CanBeIdentifier(m_currentToken.Token) != null)
{
// export identifier ;
var lookup = new Lookup(m_currentToken.Clone())
{
Name = m_scanner.Identifier
};
exportNode.Append(lookup);
GetNextToken();
}
else if (m_currentToken.Is(JSToken.Multiply))
{
// export * (from "module")?
exportNode.OpenContext = m_currentToken.Clone();
exportNode.UpdateWith(exportNode.OpenContext);
GetNextToken();
}
else if (m_currentToken.Is(JSToken.LeftCurly))
{
// export { specifier (, specifier)* ,? } (from "module")?
exportNode.OpenContext = m_currentToken.Clone();
exportNode.UpdateWith(exportNode.OpenContext);
do
{
GetNextToken();
if (m_currentToken.IsNot(JSToken.RightCurly))
{
string identifier = null;
if (m_currentToken.Is(JSToken.Identifier) || (identifier = JSKeyword.CanBeIdentifier(m_currentToken.Token)) != null)
{
var specifierContext = m_currentToken.Clone();
var lookup = new Lookup(m_currentToken.Clone())
{
Name = identifier ?? m_scanner.Identifier
};
GetNextToken();
Context asContext = null;
Context nameContext = null;
string externalName = null;
if (m_currentToken.Is("as"))
{
asContext = m_currentToken.Clone();
specifierContext.UpdateWith(asContext);
GetNextToken();
externalName = m_scanner.Identifier;
if (externalName != null)
{
nameContext = m_currentToken.Clone();
specifierContext.UpdateWith(nameContext);
GetNextToken();
}
else
{
ReportError(JSError.NoIdentifier);
}
}
var specifier = new ImportExportSpecifier(specifierContext)
{
LocalIdentifier = lookup,
AsContext = asContext,
ExternalName = externalName,
NameContext = nameContext
};
exportNode.Append(specifier);
if (m_currentToken.Is(JSToken.Comma))
{
specifier.TerminatingContext = m_currentToken.Clone();
}
}
else
{
ReportError(JSError.NoIdentifier);
}
}
}
while (m_currentToken.Is(JSToken.Comma));
if (m_currentToken.Is(JSToken.RightCurly))
{
exportNode.CloseContext = m_currentToken.Clone();
exportNode.UpdateWith(exportNode.CloseContext);
GetNextToken();
}
else
{
ReportError(JSError.NoRightCurly);
}
}
else
{
ReportError(JSError.NoSpecifierSet);
}
if (m_currentToken.Is("from"))
{
// re-exporting from another module.
exportNode.FromContext = m_currentToken.Clone();
exportNode.UpdateWith(exportNode.FromContext);
GetNextToken();
if (m_currentToken.Is(JSToken.StringLiteral))
{
exportNode.ModuleContext = m_currentToken.Clone();
exportNode.UpdateWith(exportNode.ModuleContext);
exportNode.ModuleName = m_scanner.StringLiteralValue;
GetNextToken();
}
else
{
ReportError(JSError.NoStringLiteral);
}
}
ExpectSemicolon(exportNode);
}
return exportNode;
}