/// <summary> /// Creates a new class expression. /// </summary> /// <param name="scope"> The scope that contains the class. </param> /// <param name="name"> The class name. </param> /// <param name="extends"> The base class, or <c>null</c> if this class doesn't inherit /// from another class. </param> /// <param name="constructor"> The constructor, or <c>null</c> if the class doesn't have one. </param> /// <param name="members"> A list of class members. </param> public ClassExpression(Scope scope, string name, Expression extends, FunctionExpression constructor, List <FunctionExpression> members) { this.Scope = scope ?? throw new ArgumentNullException(nameof(scope)); this.Name = name; this.Extends = extends; this.Constructor = constructor; this.Members = members ?? throw new ArgumentNullException(nameof(members)); }
/// <summary> /// Declares a variable or function in this scope. This will be initialized with the value /// of the given expression. /// </summary> /// <param name="keyword"> The keyword that was used to declare the variable (var, let or /// const). </param> /// <param name="name"> The name of the variable. </param> /// <param name="hoistedFunction"> The function value to hoist to the top of the scope. /// Should be <c>null</c> for everything except function declarations. </param> /// <returns> A reference to the variable that was declared. </returns> internal void DeclareVariable(KeywordToken keyword, string name, FunctionExpression hoistedFunction = null) { if (name == null) { throw new ArgumentNullException(nameof(name)); } // If variables cannot be declared in the scope, try the parent scope instead. var declarationScope = this; if (keyword == KeywordToken.Var) { while (declarationScope != null && (declarationScope.Type == ScopeType.Block || declarationScope.Type == ScopeType.With)) { declarationScope = declarationScope.ParentScope; } } if (declarationScope != null && !declarationScope.variables.ContainsKey(name)) { // This is a local variable that has not been declared before. var variable = new DeclaredVariable() { Scope = declarationScope, Index = declarationScope.variables.Count, Keyword = keyword, Name = name, }; declarationScope.variables.Add(name, variable); } if (hoistedFunction != null) { var hoistedScope = this; while (hoistedScope != null && hoistedScope.Type == ScopeType.Block) { hoistedScope = hoistedScope.ParentScope; } if (hoistedScope.hoistedFunctions == null) { hoistedScope.hoistedFunctions = new Dictionary <string, FunctionExpression>(); } hoistedScope.hoistedFunctions[name] = hoistedFunction; } }