001: /***** BEGIN LICENSE BLOCK *****
002: * Version: CPL 1.0/GPL 2.0/LGPL 2.1
003: *
004: * The contents of this file are subject to the Common Public
005: * License Version 1.0 (the "License"); you may not use this file
006: * except in compliance with the License. You may obtain a copy of
007: * the License at http://www.eclipse.org/legal/cpl-v10.html
008: *
009: * Software distributed under the License is distributed on an "AS
010: * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
011: * implied. See the License for the specific language governing
012: * rights and limitations under the License.
013: *
014: * Copyright (C) 2006 Thomas E Enebo <enebo@acm.org>
015: *
016: * Alternatively, the contents of this file may be used under the terms of
017: * either of the GNU General Public License Version 2 or later (the "GPL"),
018: * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
019: * in which case the provisions of the GPL or the LGPL are applicable instead
020: * of those above. If you wish to allow use of your version of this file only
021: * under the terms of either the GPL or the LGPL, and not to allow others to
022: * use your version of this file under the terms of the CPL, indicate your
023: * decision by deleting the provisions above and replace them with the notice
024: * and other provisions required by the GPL or the LGPL. If you do not delete
025: * the provisions above, a recipient may use your version of this file under
026: * the terms of any one of the CPL, the GPL or the LGPL.
027: ***** END LICENSE BLOCK *****/package org.jruby.parser;
028:
029: import java.util.ArrayList;
030: import java.util.List;
031:
032: import org.jruby.ast.AssignableNode;
033: import org.jruby.ast.LocalAsgnNode;
034: import org.jruby.ast.LocalVarNode;
035: import org.jruby.ast.Node;
036: import org.jruby.ast.VCallNode;
037: import org.jruby.lexer.yacc.ISourcePosition;
038: import org.jruby.runtime.DynamicScope;
039:
040: public class LocalStaticScope extends StaticScope {
041: private static final long serialVersionUID = 2204064248888411628L;
042:
043: public LocalStaticScope(StaticScope enclosingScope) {
044: super (enclosingScope);
045:
046: addVariable("$~");
047: addVariable("$_");
048: }
049:
050: public LocalStaticScope(StaticScope enclosingScope, String[] names) {
051: super (enclosingScope, names);
052: }
053:
054: public StaticScope getLocalScope() {
055: return this ;
056: }
057:
058: public int isDefined(String name, int depth) {
059: return (depth << 16) | exists(name);
060: }
061:
062: /**
063: * @see org.jruby.parser.StaticScope#getAllNamesInScope()
064: */
065: public String[] getAllNamesInScope(DynamicScope dynamicScope) {
066: String[] variables = getVariables();
067: List resultList = new ArrayList();
068:
069: // We start at two since we know $_ and $~ are there and they are special and not
070: // what Ruby considers a local name. BTW- We always add $~ and $_ so we know variables
071: // cannot be null.
072: for (int i = 2; i < variables.length; i++) {
073: if (dynamicScope.getValue(i, 0) != null)
074: resultList.add(variables[i]);
075: }
076: int localNamesSize = resultList.size();
077:
078: String[] names = new String[localNamesSize];
079: resultList.toArray(names);
080:
081: return names;
082: }
083:
084: public AssignableNode assign(ISourcePosition position, String name,
085: Node value, StaticScope topScope, int depth) {
086: int slot = exists(name);
087:
088: // We can assign if we already have variable of that name here or we are the only
089: // scope in the chain (which Local scopes always are).
090: if (slot >= 0) {
091: //System.out.println("LASGN1: " + name + ", l: " + depth + ", i: " + slot);
092:
093: return new LocalAsgnNode(position, name,
094: ((depth << 16) | slot), value);
095: } else if (topScope == this ) {
096: slot = addVariable(name);
097: //System.out.println("LASGN2: " + name + ", l: " + depth + ", i: " + slot);
098:
099: return new LocalAsgnNode(position, name, slot, value);
100: }
101:
102: // We know this is a block scope because a local scope cannot be within a local scope
103: // If topScope was itself it would have created a LocalAsgnNode above.
104: return ((BlockStaticScope) topScope).addAssign(position, name,
105: value);
106: }
107:
108: public Node declare(ISourcePosition position, String name, int depth) {
109: int slot = exists(name);
110:
111: if (slot >= 0) {
112: //System.out.println("LVAR: " + name + ", l: " + depth + ", i: " + slot);
113: return new LocalVarNode(position, ((depth << 16) | slot),
114: name);
115: }
116:
117: return new VCallNode(position, name);
118: }
119:
120: }
|