private static void Walk([NotNull] BlockStatementNode blockStatement, [NotNull] IList <string> list)
 {
     foreach (var baseNode in blockStatement.Body)
     {
         if (baseNode is LabelledStatementNode labelledStatement)
         {
             if (labelledStatement.Body is FunctionDeclarationNode functionDeclaration)
             {
                 BoundNamesWalker.Walk(functionDeclaration, list);
             }
         }
         else if (baseNode is FunctionDeclarationNode functionDeclaration)
         {
             BoundNamesWalker.Walk(functionDeclaration, list);
         }
         else if (baseNode is ClassDeclarationNode classDeclaration)
         {
             BoundNamesWalker.Walk(classDeclaration, list);
         }
         else if (baseNode is VariableDeclarationNode variableDeclaration && variableDeclaration.Kind != VariableKind.Var)
         {
             BoundNamesWalker.Walk(variableDeclaration, list);
         }
     }
 }
 public static void Walk([NotNull] IEnumerable <BaseNode> statementList, [NotNull] List <string> list)
 {
     foreach (var statement in statementList)
     {
         if (statement is FunctionDeclarationNode functionDeclaration)
         {
             foreach (var boundName in BoundNamesWalker.Walk(functionDeclaration))
             {
                 list.Add(boundName);
             }
         }
         else if (statement is ClassDeclarationNode || statement is VariableDeclarationNode variableDeclaration && variableDeclaration.Kind != VariableKind.Var)
         {
         }
Beispiel #3
0
 public static void Walk([NotNull] IEnumerable <BaseNode> statementList, [NotNull] IList <string> list)
 {
     foreach (var statement in statementList)
     {
         if (statement is FunctionDeclarationNode)
         {
             continue;
         }
         if (statement is ClassDeclarationNode classDeclarationNode)
         {
             BoundNamesWalker.Walk(classDeclarationNode, list);
         }
         else if (statement is VariableDeclarationNode variableDeclarationNode && variableDeclarationNode.Kind != VariableKind.Var)
         {
             BoundNamesWalker.Walk(variableDeclarationNode, list);
         }
     }
 }
        private static void WalkFunction([NotNull] Agent agent, [CanBeNull] IdentifierNode id, [NotNull] IReadOnlyList <ExpressionNode> parameters, [NotNull] BaseNode body, bool isStrict)
        {
            //https://tc39.github.io/ecma262/#sec-function-definitions-static-semantics-early-errors

            if (isStrict)
            {
                if (ContainsDuplicate(BoundNamesWalker.Walk(parameters)))
                {
                    throw agent.CreateSyntaxError();
                }

                if (id != null && (id.Name == "eval" || id.Name == "arguments"))
                {
                    throw agent.CreateSyntaxError($"Cannot have a function named ${id.Name} in strict mode.");
                }
            }

            //TODO It is a Syntax Error if ContainsUseStrict of FunctionBody is true and IsSimpleParameterList of FormalParameters is false.
            //TODO It is a Syntax Error if any element of the BoundNames of FormalParameters also occurs in the LexicallyDeclaredNames of FunctionBody.
            //TODO It is a Syntax Error if FormalParameters Contains SuperProperty is true.
            //TODO It is a Syntax Error if FunctionBody Contains SuperProperty is true.
            if (HasParameterSuper(parameters))
            {
                throw agent.CreateSyntaxError();
            }
            if (HasDirectSuper(body))
            {
                throw agent.CreateSyntaxError();
            }

            if (id != null)
            {
                Walk(agent, id, isStrict);
            }

            foreach (var parameter in parameters)
            {
                WalkBinding(agent, parameter, isStrict);
            }

            Walk(agent, body, isStrict);
        }
        private static void Walk([NotNull] Agent agent, [NotNull] VariableDeclarationNode variableDeclaration, bool isStrict)
        {
            if (variableDeclaration.Kind != VariableKind.Var)
            {
                //https://tc39.github.io/ecma262/#sec-let-and-const-declarations-static-semantics-early-errors
                var boundNames = BoundNamesWalker.Walk(variableDeclaration);
                if (ContainsDuplicate(boundNames))
                {
                    throw agent.CreateSyntaxError();
                }

                if (boundNames.Contains("let"))
                {
                    throw agent.CreateSyntaxError();
                }
            }

            foreach (var variableDeclarator in variableDeclaration.Declarations)
            {
                Walk(agent, variableDeclarator, isStrict);
            }
        }
        public static void Walk([NotNull] BaseNode statement, [NotNull] List <string> list)
        {
            switch (statement)
            {
            case BreakStatementNode _:
            case ClassDeclarationNode _:
            case ContinueStatementNode _:
            case DebuggerStatementNode _:
            case EmptyStatementNode _:
            case ExpressionStatementNode _:
            case FunctionDeclarationNode _:
            case ReturnStatementNode _:
            case ThrowStatementNode _:
                return;

            case BlockStatementNode blockStatement:
                foreach (var node in blockStatement.Body)
                {
                    Walk(node, list);
                }
                break;

            case DoWhileStatementNode doWhileStatement:
                Walk(doWhileStatement.Body, list);
                break;

            case ForStatementNode forStatement:
            {
                if (forStatement.Init is VariableDeclarationNode forBinding)
                {
                    Walk(forBinding, list);
                }

                Walk(forStatement.Body, list);
                break;
            }

            case ForInStatementNode forInStatement:
            {
                if (forInStatement.Left is VariableDeclarationNode forBinding)
                {
                    Walk(forBinding, list);
                }

                Walk(forInStatement.Body, list);
                break;
            }

            case ForOfStatementNode forOfStatement:
            {
                if (forOfStatement.Left is VariableDeclarationNode forBinding)
                {
                    Walk(forBinding, list);
                }

                Walk(forOfStatement.Body, list);
                break;
            }

            case IfStatementNode ifStatement:
                Walk(ifStatement.Consequent, list);
                if (ifStatement.Alternate != null)
                {
                    Walk(ifStatement.Alternate, list);
                }
                break;

            case LabelledStatementNode labelledStatement:
                if (!(labelledStatement.Body is FunctionDeclarationNode))
                {
                    Walk(labelledStatement.Body, list);
                }
                break;

            case SwitchStatementNode switchStatement:
                foreach (var switchCase in switchStatement.Cases)
                {
                    foreach (var node in switchCase.Consequent)
                    {
                        Walk(node, list);
                    }
                }
                break;

            case TryStatementNode tryStatement:
                Walk(tryStatement.Block, list);
                if (tryStatement.Handler != null)
                {
                    Walk(tryStatement.Handler.Body, list);
                }
                if (tryStatement.Finaliser != null)
                {
                    Walk(tryStatement.Finaliser, list);
                }
                break;

            case VariableDeclarationNode variableDeclaration:
                if (variableDeclaration.Kind != VariableKind.Var)
                {
                    return;
                }

                list.AddRange(BoundNamesWalker.Walk(variableDeclaration));

                break;

            case WhileStatementNode whileStatement:
                Walk(whileStatement.Body, list);
                break;

            case WithStatementNode withStatement:
                Walk(withStatement.Body, list);
                break;

            default:
                throw new NotImplementedException();
            }
        }