예제 #1
0
파일: AstVar.cs 프로젝트: Bobris/Njsast
    public override AstNode ShallowClone()
    {
        var res = new AstVar(Source, Start, End);

        res.Definitions.AddRange(Definitions.AsReadOnlySpan());
        return(res);
    }
예제 #2
0
 public VariableDefinition(AstBlock parentBlock, AstNode parent, AstVar astVar, AstVarDef astVarDef, bool canMoveInitialization, int originalIndexInVar)
 {
     ParentBlock           = parentBlock;
     Parent                = parent;
     AstVar                = astVar;
     CanMoveInitialization = canMoveInitialization;
     OriginalIndexInVar    = originalIndexInVar;
     AstVarDef             = astVarDef;
 }
예제 #3
0
 /// If there is global variable named `global`, then define it as `window`, because we are bundling for browser
 static void IfNeededPolyfillGlobal(AstToplevel topLevelAst)
 {
     if (topLevelAst.Globals !.ContainsKey("global"))
     {
         var astVar = new AstVar(topLevelAst);
         astVar.Definitions.Add(new AstVarDef(new AstSymbolVar("global"), new AstSymbolRef("window")));
         topLevelAst.Body.Insert(0) = astVar;
     }
 }
예제 #4
0
        AstNode ParseForStatement(Position nodeStart)
        {
            Next();
            EnterLexicalScope();
            Expect(TokenType.ParenL);
            if (Type == TokenType.Semi)
            {
                return(ParseFor(nodeStart, null));
            }
            var isLet = IsLet();

            if (Type == TokenType.Var || Type == TokenType.Const || isLet)
            {
                var startLoc = Start;
                var kind     = isLet ? VariableKind.Let : ToVariableKind((string)Value);
                Next();
                var declarations = new StructList <AstVarDef>();
                ParseVar(ref declarations, true, kind);
                AstDefinitions init;
                if (kind == VariableKind.Let)
                {
                    init = new AstLet(this, startLoc, _lastTokEnd, ref declarations);
                }
                else if (kind == VariableKind.Const)
                {
                    init = new AstConst(this, startLoc, _lastTokEnd, ref declarations);
                }
                else
                {
                    init = new AstVar(this, startLoc, _lastTokEnd, ref declarations);
                }

                if ((Type == TokenType.In || Options.EcmaVersion >= 6 && IsContextual("of")) &&
                    init.Definitions.Count == 1 &&
                    !(kind != VariableKind.Var && init.Definitions[0].Value != null))
                {
                    return(ParseForIn(nodeStart, init));
                }
                return(ParseFor(nodeStart, init));
            }
            else
            {
                var refDestructuringErrors = new DestructuringErrors();
                var init = ParseExpression(true, refDestructuringErrors);
                if (Type == TokenType.In || Options.EcmaVersion >= 6 && IsContextual("of"))
                {
                    init = ToAssignable(init);
                    CheckLVal(init, false, null);
                    CheckPatternErrors(refDestructuringErrors, true);
                    return(ParseForIn(nodeStart, init));
                }

                CheckExpressionErrors(refDestructuringErrors, true);
                return(ParseFor(nodeStart, init));
            }
        }
예제 #5
0
            protected override AstNode?After(AstNode node, bool inList)
            {
                if (node is AstToplevel toplevel && _shadowedWindow)
                {
                    var newVar = new AstVar(toplevel);
                    var name   = new AstSymbolVar("global");
                    newVar.Definitions.Add(new AstVarDef(toplevel, name, new AstSymbolRef("window")));
                    toplevel.Body.Insert(0) = newVar;
                }

                return(node);
            }
예제 #6
0
파일: Statement.cs 프로젝트: Bobris/Njsast
    // Disambiguating between a `for` and a `for`/`in` or `for`/`of`
    // loop is non-trivial. Basically, we have to parse the init `var`
    // statement or expression, disallowing the `in` operator (see
    // the second parameter to `parseExpression`), and then check
    // whether the next token is `in` or `of`. When there is no init
    // part (semicolon immediately after the opening parenthesis), it
    // is a regular `for` loop.
    AstIterationStatement ParseForStatement(Position nodeStart)
    {
        Next();
        var isAwait = EatContextual("await");

        EnterLexicalScope();
        Expect(TokenType.ParenL);
        if (Type == TokenType.Semi)
        {
            return(ParseFor(nodeStart, null, isAwait));
        }

        var isLet = IsLet();

        if (Type is TokenType.Var or TokenType.Const || isLet)
        {
            var startLoc = Start;
            var kind     = isLet ? VariableKind.Let : ToVariableKind((string)GetValue());
            Next();
            var declarations = new StructList <AstVarDef>();
            ParseVar(ref declarations, true, kind);
            AstDefinitions init;
            if (kind == VariableKind.Let)
            {
                init = new AstLet(SourceFile, startLoc, _lastTokEnd, ref declarations);
            }
            else if (kind == VariableKind.Const)
            {
                init = new AstConst(SourceFile, startLoc, _lastTokEnd, ref declarations);
            }
            else
            {
                init = new AstVar(SourceFile, startLoc, _lastTokEnd, ref declarations);
            }

            if ((Type == TokenType.In || IsContextual("of")) &&
                init.Definitions.Count == 1 &&
                !(kind != VariableKind.Var && init.Definitions[0].Value != null))
            {
                return(ParseForIn(nodeStart, init, isAwait));
            }
            return(ParseFor(nodeStart, init, isAwait));
        }
예제 #7
0
            protected override AstNode?Before(AstNode node, bool inList)
            {
                if (node.IsSymbolDef().IsGlobalSymbol() is {} symbolName)
                {
                    if (symbolName == "global")
                    {
                        foreach (var parent in Parents())
                        {
                            if (parent is AstScope scope)
                            {
                                if (scope.Variables !.ContainsKey("window") || scope.Functions !.ContainsKey("window"))
                                {
                                    _shadowedWindow = true;
                                    return(null);
                                }
                            }
                        }

                        return(new AstSymbolRef(node, "window"));
                    }
                }

                if (node is AstSimpleStatement simpleStatement && simpleStatement.Body is AstAssign assigment &&
                    assigment.Operator == Operator.Assignment)
                {
                    if (assigment.Left is AstDot dot && dot.PropertyAsString == "exports" &&
                        dot.Expression.IsSymbolDef().IsGlobalSymbol() == "module")
                    {
                        var res    = new AstVar(node);
                        var newVar = new AstSymbolVar(assigment.Left, _varName);
                        ResultingSymbol = newVar;
                        res.Definitions.Add(new AstVarDef(assigment.Left, newVar, assigment.Right));
                        return(Transform(res));
                    }
                }

                return(null);
            }
예제 #8
0
        public void Run()
        {
            var stopwatch = Stopwatch.StartNew();

            foreach (var(splitName, mainFileList) in PartToMainFilesMap)
            {
                foreach (var mainFile in mainFileList)
                {
                    if (_cache.TryGetValue(mainFile, out var sourceFile))
                    {
                        MarkRequiredAs(sourceFile, splitName);
                        continue;
                    }

                    Check(mainFile, splitName);
                }

                _splitMap[splitName] = new SplitInfo(splitName)
                {
                    ShortName = _ctx.GenerateBundleName(splitName), PropName = "ERROR", IsMainSplit = true
                };
            }

            stopwatch.Stop();
            _ctx.ReportTime("Parse", stopwatch.Elapsed);
            foreach (var(_, sourceFile) in _cache)
            {
                foreach (var(file, path) in sourceFile.NeedsImports)
                {
                    _cache.TryGetValue(file, out var targetFile);
                    targetFile !.CreateWholeExport(path);
                }
            }

            var lazySplitCounter = 0;

            foreach (var f in _order)
            {
                var fullBundleName = f.PartOfBundle !;
                if (!_splitMap.TryGetValue(fullBundleName, out var split))
                {
                    var shortenedBundleName = _ctx.GenerateBundleName(fullBundleName);
                    split = new SplitInfo(fullBundleName)
                    {
                        ShortName = shortenedBundleName,
                        PropName  = BundlerHelpers.NumberToIdent(lazySplitCounter++)
                    };
                    _splitMap[fullBundleName] = split;
                }

                foreach (var dependency in f.PlainJsDependencies)
                {
                    split.PlainJsDependencies.Add(dependency);
                }
            }

            if (lazySplitCounter > 0)
            {
                DetectBundleExportsImports(ref lazySplitCounter);
            }

            foreach (var(splitName, splitInfo) in _splitMap)
            {
                var topLevelAst = Parser.Parse(_ctx.JsHeaders(splitName, lazySplitCounter > 0));
                if (GlobalDefines != null && GlobalDefines.Count > 0)
                {
                    topLevelAst.Body.Add(Helpers.EmitVarDefines(GlobalDefines));
                }
                topLevelAst.FigureOutScope();
                foreach (var jsDependency in splitInfo.PlainJsDependencies)
                {
                    var content = _ctx.ReadContent(jsDependency);
                    var jsAst   = Parser.Parse(content.Item1 !);
                    content.Item2?.ResolveInAst(jsAst);
                    jsAst.FigureOutScope();
                    BundlerHelpers.SimplifyJavaScriptDependency(jsAst);
                    _currentFileIdent = BundlerHelpers.FileNameToIdent(jsDependency);
                    BundlerHelpers.AppendToplevelWithRename(topLevelAst, jsAst, _currentFileIdent);
                }

                foreach (var sourceFile in _order)
                {
                    if (sourceFile.PartOfBundle != splitName)
                    {
                        continue;
                    }
                    foreach (var keyValuePair in sourceFile.Ast.Globals !)
                    {
                        topLevelAst.Globals !.TryAdd(keyValuePair.Key, keyValuePair.Value);
                        topLevelAst.NonRootSymbolNames?.Add(keyValuePair.Key);
                    }
                }

                AddExternallyImportedFromOtherBundles(topLevelAst, splitInfo);
                foreach (var sourceFile in _order)
                {
                    if (sourceFile.PartOfBundle != splitName)
                    {
                        continue;
                    }
                    _currentSourceFile = sourceFile;
                    _currentFileIdent  = BundlerHelpers.FileNameToIdent(sourceFile.Name);
                    BundlerHelpers.AppendToplevelWithRename(topLevelAst, sourceFile.Ast, _currentFileIdent
                                                            , BeforeAdd);
                }

                IfNeededPolyfillGlobal(topLevelAst);

                AddExportsFromLazyBundle(splitInfo, topLevelAst);

                BundlerHelpers.WrapByIIFE(topLevelAst);
                if (lazySplitCounter > 0 && PartToMainFilesMap.ContainsKey(splitName))
                {
                    var astVar = new AstVar(topLevelAst);
                    astVar.Definitions.Add(new AstVarDef(new AstSymbolVar("__bbb"), new AstObject()));
                    topLevelAst.Body.Insert(0) = astVar;
                }

                if (CompressOptions != null)
                {
                    stopwatch = Stopwatch.StartNew();
                    topLevelAst.FigureOutScope();
                    topLevelAst = topLevelAst.Compress(CompressOptions, new ScopeOptions
                    {
                        TopLevel       = false,
                        BeforeMangling = IgnoreEvalInTwoScopes
                    });
                    stopwatch.Stop();
                    _ctx.ReportTime("Compress", stopwatch.Elapsed);
                }

                if (Mangle)
                {
                    stopwatch = Stopwatch.StartNew();
                    topLevelAst.Mangle(new ScopeOptions
                    {
                        FrequencyCounting = MangleWithFrequencyCounting,
                        TopLevel          = false,
                        BeforeMangling    = IgnoreEvalInTwoScopes
                    }, OutputOptions);
                    stopwatch.Stop();
                    _ctx.ReportTime("Mangle", stopwatch.Elapsed);
                }

                _ctx.ModifyBundle(splitInfo.ShortName !, topLevelAst);

                if (GenerateSourceMap)
                {
                    stopwatch = Stopwatch.StartNew();
                    var builder = new SourceMapBuilder();
                    topLevelAst.PrintToBuilder(builder, OutputOptions);
                    stopwatch.Stop();
                    _ctx.ReportTime("Print", stopwatch.Elapsed);
                    _ctx.WriteBundle(splitInfo.ShortName !, builder);
                }
                else
                {
                    stopwatch = Stopwatch.StartNew();
                    var content = topLevelAst.PrintToString(OutputOptions);
                    stopwatch.Stop();
                    _ctx.ReportTime("Print", stopwatch.Elapsed);
                    _ctx.WriteBundle(splitInfo.ShortName !, content);
                }
            }
        }
예제 #9
0
        public void Run()
        {
            foreach (var(splitName, mainFileList) in PartToMainFilesMap)
            {
                foreach (var mainFile in mainFileList)
                {
                    if (_cache.TryGetValue(mainFile, out var sourceFile))
                    {
                        MarkRequiredAs(sourceFile, splitName);
                        continue;
                    }

                    Check(mainFile, splitName);
                }

                _splitMap[splitName] = new SplitInfo(splitName)
                {
                    ShortName = _ctx.GenerateBundleName(splitName), PropName = "ERROR", IsMainSplit = true
                };
            }

            foreach (var(_, sourceFile) in _cache)
            {
                if (sourceFile.NeedsWholeExport && sourceFile.WholeExport == null)
                {
                    sourceFile.CreateWholeExport();
                }
            }

            var lazySplitCounter = 0;

            foreach (var f in _order)
            {
                var fullBundleName = f.PartOfBundle !;
                if (!_splitMap.TryGetValue(fullBundleName, out var split))
                {
                    var shortenedBundleName = _ctx.GenerateBundleName(fullBundleName);
                    split = new SplitInfo(fullBundleName)
                    {
                        ShortName = shortenedBundleName,
                        PropName  = BundlerHelpers.NumberToIdent(lazySplitCounter++)
                    };
                    _splitMap[fullBundleName] = split;
                }

                foreach (var dependency in f.PlainJsDependencies)
                {
                    split.PlainJsDependencies.Add(dependency);
                }
            }

            if (lazySplitCounter > 0)
            {
                DetectBundleExportsImports(ref lazySplitCounter);
            }

            foreach (var(splitName, splitInfo) in _splitMap)
            {
                var topLevelAst = new Parser(new Options(), _ctx.JsHeaders(splitName, lazySplitCounter > 0)).Parse();
                if (GlobalDefines != null && GlobalDefines.Count > 0)
                {
                    topLevelAst.Body.Add(Helpers.EmitVarDefines(GlobalDefines));
                }
                topLevelAst.FigureOutScope();
                foreach (var jsDependency in splitInfo.PlainJsDependencies)
                {
                    var jsAst = new Parser(new Options(), _ctx.ReadContent(jsDependency) !).Parse();
                    jsAst.FigureOutScope();
                    _currentFileIdent = BundlerHelpers.FileNameToIdent(jsDependency);
                    BundlerHelpers.AppendToplevelWithRename(topLevelAst, jsAst, _currentFileIdent);
                }

                AddExternallyImportedFromOtherBundles(topLevelAst, splitInfo);
                foreach (var sourceFile in _order)
                {
                    if (sourceFile.PartOfBundle != splitName)
                    {
                        continue;
                    }
                    _currentSourceFile = sourceFile;
                    _currentFileIdent  = BundlerHelpers.FileNameToIdent(sourceFile.Name);
                    BundlerHelpers.AppendToplevelWithRename(topLevelAst, sourceFile.Ast, _currentFileIdent
                                                            , BeforeAdd);
                }

                AddExportsFromLazyBundle(splitInfo, topLevelAst);

                BundlerHelpers.WrapByIIFE(topLevelAst);
                if (lazySplitCounter > 0 && PartToMainFilesMap.ContainsKey(splitName))
                {
                    var astVar = new AstVar(topLevelAst);
                    astVar.Definitions.Add(new AstVarDef(new AstSymbolVar("__bbb"), new AstObject()));
                    topLevelAst.Body.Insert(0) = astVar;
                }

                if (CompressOptions != null)
                {
                    topLevelAst.FigureOutScope();
                    topLevelAst = topLevelAst.Compress(CompressOptions);
                }

                if (Mangle)
                {
                    topLevelAst.Mangle(new ScopeOptions
                    {
                        FrequencyCounting = MangleWithFrequencyCounting, TopLevel = false,
                        BeforeMangling    = IgnoreEvalInTwoScopes
                    });
                }

                _ctx.WriteBundle(splitInfo.ShortName !, topLevelAst.PrintToString(OutputOptions));
            }
        }