private AstNode ParseExport()

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;
        }