Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   ***** BEGIN LICENSE BLOCK *****
   * Version: CPL 1.0/GPL 2.0/LGPL 2.1
   *
   * The contents of this file are subject to the Common Public
   * License Version 1.0 (the "License"); you may not use this file
   * except in compliance with the License. You may obtain a copy of
   * the License at http://www.eclipse.org/legal/cpl-v10.html
   *
  * Software distributed under the License is distributed on an "AS
  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  * implied. See the License for the specific language governing
  * rights and limitations under the License.
  *
  * Copyright (C) 2006-2007 Thomas E Enebo <enebo@acm.org>
  * 
  * Alternatively, the contents of this file may be used under the terms of
  * either of the GNU General Public License Version 2 or later (the "GPL"),
  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the CPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the CPL, the GPL or the LGPL.
  ***** END LICENSE BLOCK *****/
 package org.jruby.parser;
 
 
 import org.jruby.Ruby;
StaticScope represents lexical scoping of variables and module/class constants. At a very high level every scopes enclosing scope contains variables in the next outer lexical layer. The enclosing scopes variables may or may not be reachable depending on the scoping rules for variables (governed by BlockStaticScope and LocalStaticScope). StaticScope also keeps track of current module/class that is in scope. previousCRefScope will point to the previous scope of the enclosing module/class (cref).
 
 public abstract class StaticScope implements Serializable {
     private static final long serialVersionUID = 4843861446986961013L;
     
     // Next immediate scope.  Variable and constant scoping rules make use of this variable
     // in different ways.
     final protected StaticScope enclosingScope;
     
     // Live reference to module
     private transient RubyModule cref = null;
     
     // Next CRef down the lexical structure
     private StaticScope previousCRefScope = null;
     
     // Our name holder (offsets are assigned as variables are added
     private String[] variableNames;
     
     // number of variables in this scope representing required arguments
     private int requiredArgs = 0;
     
     // number of variables in this scope representing optional arguments
     private int optionalArgs = 0;
     
     // index of variable that represents a "rest" arg
     private int restArg = -1;
 
     private boolean isBackrefLastlineScope = false;
     
     private DynamicScope dummyScope;

    
Construct a new static scope. The array of strings should all be the interned versions, since several other optimizations depend on being able to do object equality checks.

Parameters:
enclosingScope The lexically containing scope.
names The list of interned String variable names.
 
     protected StaticScope(StaticScope enclosingScopeString[] names) {
         assert names != null : "names is not null";
         assert namesAreInterned(names);
         
         this. = enclosingScope;
         this. = names;
     }

    
Check that all strings in the given array are the interned versions.

Parameters:
names The array of strings
Returns:
true if they are all interned, false otherwise
    private static boolean namesAreInterned(String[] names) {
        for (String name : names) {
            // Note that this object equality check is intentional, to ensure
            // the string and its interned version are the same object.
            if (name != name.intern()) return false;
        }
        return true;
    }

    
Add a new variable to this (current) scope unless it is already defined in the current scope.

Parameters:
name of new variable
Returns:
index+depth merged location of scope
    public int addVariableThisScope(String name) {
        int slot = exists(name);
        if (slot >= 0) return slot;
        // This is perhaps innefficient timewise?  Optimal spacewise
        growVariableNames(name);
        // Returns slot of variable
        return . - 1;
    }

    
Add a new variable to this (current) scope unless it is already defined in any reachable scope.

Parameters:
name of new variable
Returns:
index+depth merged location of scope
    public int addVariable(String name) {
        int slot = isDefined(name); 
        if (slot >= 0) return slot;
            
        // This is perhaps innefficient timewise?  Optimal spacewise
        growVariableNames(name);
        
        // Returns slot of variable
        return . - 1;
    }
    
    public String[] getVariables() {
        return ;
    }
    
    public int getNumberOfVariables() {
        return .;
    }
    
    public void setVariables(String[] names) {
        assert names != null : "names is not null";
        
         = new String[names.length];
        System.arraycopy(names, 0, , 0, names.length);
    }
    /* Note: Only used by compiler until it can use getConstant again or use some other refactoring */
    public IRubyObject getConstantWithConstMissing(Ruby runtimeString internedNameRubyModule object) {
        IRubyObject result = getConstantInner(runtimeinternedNameobject);
        // If we could not find the constant from cref..then try getting from inheritence hierarchy
        return result == null ? .getConstant(internedName) : result;        
    }
    
    public IRubyObject getConstant(Ruby runtimeString internedNameRubyModule object) {
        IRubyObject result = getConstantInner(runtimeinternedNameobject);
        // If we could not find the constant from cref..then try getting from inheritence hierarchy
        return result == null ? .getConstantNoConstMissing(internedName) : result;
    }
    public IRubyObject getConstantInner(Ruby runtimeString internedNameRubyModule object) {
        IRubyObject result = .fetchConstant(internedName);
        if (result != null) {
            return result == . ? .resolveUndefConstant(runtimeinternedName) : result;
        }
        return  == null ? null : .getConstantInnerNoObject(runtimeinternedNameobject);
    }
    
    private IRubyObject getConstantInnerNoObject(Ruby runtimeString internedNameRubyModule object) {
        if ( == nullreturn null;
        return getConstantInner(runtimeinternedNameobject);
    }
    
    
Next outer most scope in list of scopes. An enclosing scope may have no direct scoping relationship to its child. If I am in a localScope and then I enter something which creates another localScope the enclosing scope will be the first scope, but there are no valid scoping relationships between the two. Methods which walk the enclosing scopes are responsible for enforcing appropriate scoping relationships.

Returns:
the parent scope
    public StaticScope getEnclosingScope() {
        return ;
    }
    
    
Does the variable exist?

Parameters:
name of the variable to find
Returns:
index of variable or -1 if it does not exist
    public int exists(String name) {
        return findVariableName(name);
    }
    
    private int findVariableName(String name) {
        for (int i = 0; i < .i++) {
            if (name == [i]) return i;
        }
        return -1;
    }
    
    
Is this name in the visible to the current scope

Parameters:
name to be looked for
Returns:
a location where the left-most 16 bits of number of scopes down it is and the right-most 16 bits represents its index in that scope
    public int isDefined(String name) {
        return isDefined(name, 0);
    }
    
    
Make a DASgn or LocalAsgn node based on scope logic

Parameters:
position
name
value
Returns:
    public AssignableNode assign(ISourcePosition positionString nameNode value) {
        return assign(positionnamevaluethis, 0);
    }
    
    
Get all visible variables that we can see from this scope that have been assigned (e.g. seen so far)

Returns:
a list of all names (sans $~ and $_ which are special names)
    public abstract String[] getAllNamesInScope();
    
    protected abstract int isDefined(String nameint depth);
    protected abstract AssignableNode assign(ISourcePosition positionString nameNode value
            StaticScope topScopeint depth);
    protected abstract Node declare(ISourcePosition positionString nameint depth);
    
    
Make a DVar or LocalVar node based on scoping logic

Parameters:
position the location that in the source that the new node will come from
name of the variable to be created is named
Returns:
a DVarNode or LocalVarNode
    public Node declare(ISourcePosition positionString name) {
        return declare(positionname, 0);
    }

    
Gets the Local Scope relative to the current Scope. For LocalScopes this will be itself. Blocks will contain the LocalScope it contains.

Returns:
localScope
    public abstract StaticScope getLocalScope();
    
    
Get the live CRef module associated with this scope.

Returns:
the live module
    public RubyModule getModule() {
        return ;
    }
    
    public StaticScope getPreviousCRefScope() {
        return ;
    }
    public void setPreviousCRefScope(StaticScope crefScope) {
        this. = crefScope;
    }
    public void setModule(RubyModule module) {
        this. = module;
        
        for (StaticScope scope = getEnclosingScope(); scope != nullscope = scope.getEnclosingScope()) {
            if (scope.cref != null) {
                 = scope;
                return;
            }
        }
    }

    
Update current scoping structure to populate with proper cref scoping values. This should be called at any point when you reference a scope for the first time. For the interpreter this is done in a small number of places (defnNode, defsNode, and getBlock). The compiler does this in the same places.

Returns:
the current cref, though this is largely an implementation detail
    public RubyModule determineModule() {
        if ( == null) {
             = getEnclosingScope().determineModule();
            
            assert  != null : "CRef is always created before determine happens";
            
        }
        
        return ;
    }
    public int getOptionalArgs() {
        return ;
    }
    public int getRequiredArgs() {
        return ;
    }
    public void setRequiredArgs(int requiredArgs) {
        this. = requiredArgs;
    }
    public int getRestArg() {
        return ;
    }
    public void setRestArg(int restArg) {
        this. = restArg;
    }

    
Argument scopes represent scopes which contain arguments for zsuper. All LocalStaticScopes are argument scopes and BlockStaticScopes can be when they are used by define_method.
    public abstract boolean isArgumentScope();
    public abstract void makeArgumentScope();
    public boolean isBlockScope() {
        return false;
    }
    public boolean isBackrefLastlineScope() {
        return ;
    }
    public void setBackrefLastlineScope(boolean isBackrefLastlineScope) {
        this. = isBackrefLastlineScope;
    }
    
    public Arity getArity() {
        if ( > 0) {
            if ( >= 0) {
                return Arity.optional();
            }
            return Arity.required();
        } else {
            if ( >= 0) {
                return Arity.optional();
            }
            return Arity.fixed();
        }
    }
    
    public void setArities(int requiredint optionalint rest) {
        this. = required;
        this. = optional;
        this. = rest;
    }
    
    public DynamicScope getDummyScope() {
        return  == null ?  = new DummyDynamicScope(this) : ;
    }
    private void growVariableNames(String name) {
        String[] newVariableNames = new String[. + 1];
        System.arraycopy(, 0, newVariableNames, 0, .);
         = newVariableNames;
        [. - 1] = name;
    }
    @Override
    public String toString() {
        StringBuilder buf = new StringBuilder("[");
            
        for (int i = 0; i < . - 1; i++) {
            buf.append([i]).append(", ");
        }
        if (. > 0) {
            buf.append([. - 1]);
        }
        buf.append("]");
        buf.append(", cref = ").append();
            
        return buf.toString();
    }
New to GrepCode? Check out our FAQ X