Ejemplo n.º 1
0
        public static BlockStatement CreateBlockStatement(List <IExpression> statements, Token token)
        {
            BlockStatement result = CreateNode <BlockStatement>(token);

            foreach (IExpression statement in statements)
            {
                result.Append(statement);
            }

            return(result);
        }
Ejemplo n.º 2
0
        public override void Visit(BlockStatement node)
        {
            if (node != null)
            {
                // there really is no point in nesting blocks that don't have any special scopes
                // attached to them. Unnest any now, before we start combining var statements.
                UnnestBlocks(node);

                // if we get here, we are going to want to optimize the curly-braces to eliminate
                // unneeded ones in all blocks except try/catch/finally. So make sure we reset the
                // force-braces properties for all blocks whose parent isn't a try-statement.
                node.ForceBraces = node.Parent is TryStatement;

                if (m_combineAdjacentVars)
                {
                    // look at the statements in the block.
                    // if there are multiple var statements adjacent to each other, combine them.
                    // walk BACKWARDS down the list because we'll be removing items when we encounter
                    // multiple vars, etc.
                    // we also don't need to check the first one, since there is nothing before it.
                    for (int ndx = node.Count - 1; ndx > 0; --ndx)
                    {
                        var previousDeclaration = node[ndx - 1] as Declaration;
                        if (previousDeclaration != null)
                        {
                            if (previousDeclaration.StatementToken == DeclarationType(node[ndx]))
                            {
                                // add the items in this VAR to the end of the previous
                                previousDeclaration.Append(node[ndx]);

                                // delete this item from the block
                                node.RemoveAt(ndx);
                            }
                        }
                        else
                        {
                            // if this node and hte previous node are both export declaration statements of the same type...
                            var previousExport = node[ndx - 1] as ExportStatement;
                            if (previousExport != null && previousExport.Count == 1 && previousExport.ModuleName.IsNullOrWhiteSpace())
                            {
                                var declarationType = DeclarationType(previousExport[0]);
                                if (declarationType != JSToken.None)
                                {
                                    var thisExport = node[ndx] as ExportStatement;
                                    if (thisExport != null && thisExport.Count == 1 && thisExport.ModuleName.IsNullOrWhiteSpace() &&
                                        declarationType == DeclarationType(thisExport[0]))
                                    {
                                        // merge our specifiers into the previous declaration's specifiers
                                        // and remove this statement from the block
                                        ((Declaration)previousExport[0]).Append(thisExport[0]);
                                        node.RemoveAt(ndx);
                                    }
                                }
                            }
                        }
                    }
                }

                if (node.IsModule)
                {
                    // walk backwards until we find the last non-comment statement
                    var ndxLast = node.Count - 1;
                    while (ndxLast >= 0 && node[ndxLast] is ImportantComment)
                    {
                        --ndxLast;
                    }

                    // if the last non-comment statement isn't the first....
                    if (ndxLast > 0)
                    {
                        // check to see if the last statement is already a target export
                        var finalExport = IfTargetExport(node[ndxLast]);
                        var startIndex  = node.Count - (finalExport == null ? 1 : 2);

                        // we're going to keep track of any export declarations we may have because
                        // we'll only move them if it makes sense.
                        var exportDeclarations = new List <ExportStatement>();

                        // walk backwards from the last to the first looking for export statements
                        // with no 'from' clause (those would be re-export statements) and specifiers
                        // as children (we don't want to count the export declaration statements yet.
                        for (var ndx = startIndex; ndx >= 0; --ndx)
                        {
                            // we are only interested in exports nodes that DON'T have a module name.
                            // those are re-exports, and we just want to leave them alone for now.
                            var exportNode = node[ndx] as ExportStatement;
                            if (exportNode != null && exportNode.ModuleName.IsNullOrWhiteSpace())
                            {
                                if (IfTargetExport(exportNode) != null)
                                {
                                    if (exportNode != finalExport)
                                    {
                                        // we have a target export statement
                                        if (finalExport != null)
                                        {
                                            // if we already have a final export, then we just need to prepend our specifiers to
                                            // the existing export's specifiers and delete this one
                                            finalExport.Insert(0, exportNode);
                                            node.RemoveAt(ndx);
                                        }
                                        else
                                        {
                                            // we don't already have a final export, so just move this one to the end
                                            node.RemoveAt(ndx);
                                            node.Append(exportNode);
                                            finalExport = exportNode;
                                        }
                                    }
                                }
                                else if (exportNode.Count == 1)
                                {
                                    // it's not a target export node (one with specifiers), and it's not a re-export,
                                    // and it has only one child -- must be an export declaration statement. Save it for later.
                                    exportDeclarations.Add(exportNode);
                                }
                            }
                        }

                        // if we found any export declarations
                        if (exportDeclarations.Count > 0)
                        {
                            // we need to see if it's worth it to remove the export keyword from the declaration and
                            // add a new specifier to an existing export statement, or create a new one.
                        }
                    }
                }

                // recurse down the tree after we've combined the adjacent var statements
                base.Visit(node);
            }
        }