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) { }
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(); } }