Ejemplo n.º 1
0
 /// <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));
 }
Ejemplo n.º 2
0
        /// <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;
            }
        }