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.DAsgnNode;
034: import org.jruby.ast.DVarNode;
035: import org.jruby.ast.Node;
036: import org.jruby.lexer.yacc.ISourcePosition;
037: import org.jruby.runtime.DynamicScope;
038:
039: public class BlockStaticScope extends StaticScope {
040: private static final long serialVersionUID = -3882063260379968149L;
041:
042: public BlockStaticScope(StaticScope parentScope) {
043: super (parentScope);
044: }
045:
046: public BlockStaticScope(StaticScope parentScope, String[] names) {
047: super (parentScope, names);
048: }
049:
050: public StaticScope getLocalScope() {
051: return getEnclosingScope().getLocalScope();
052: }
053:
054: public int isDefined(String name, int depth) {
055: int slot = exists(name);
056: if (slot >= 0)
057: return (depth << 16) | exists(name);
058:
059: return getEnclosingScope().isDefined(name, depth + 1);
060: }
061:
062: /**
063: * @see org.jruby.parser.StaticScope#getAllNamesInScope()
064: */
065: public String[] getAllNamesInScope(DynamicScope dynamicScope) {
066: String[] variables = getEnclosingScope().getAllNamesInScope(
067: dynamicScope.getNextCapturedScope());
068: String[] ourVariables = getVariables();
069: List resultList = new ArrayList();
070:
071: // We have no names to add to existing list
072: if (ourVariables == null)
073: return variables;
074:
075: for (int i = 0; i < ourVariables.length; i++) {
076: if (dynamicScope.getValue(i, 0) != null)
077: resultList.add(ourVariables[i]);
078: }
079: int localNamesSize = resultList.size();
080:
081: String[] ourNames = new String[localNamesSize];
082: resultList.toArray(ourNames);
083:
084: // we know variables cannot be null since localstaticscope will create a 0 length one.
085: int newSize = variables.length + resultList.size();
086: String[] names = new String[newSize];
087:
088: System.arraycopy(variables, 0, names, 0, variables.length);
089: System.arraycopy(ourNames, 0, names, variables.length,
090: ourNames.length);
091:
092: return names;
093: }
094:
095: protected AssignableNode assign(ISourcePosition position,
096: String name, Node value, StaticScope topScope, int depth) {
097: int slot = exists(name);
098:
099: if (slot >= 0) {
100: return new DAsgnNode(position, name,
101: ((depth << 16) | slot), value);
102: }
103:
104: return getEnclosingScope().assign(position, name, value,
105: topScope, depth + 1);
106: }
107:
108: public AssignableNode addAssign(ISourcePosition position,
109: String name, Node value) {
110: int slot = addVariable(name);
111:
112: // No bit math to store level since we know level is zero for this case
113: return new DAsgnNode(position, name, slot, value);
114: }
115:
116: public Node declare(ISourcePosition position, String name, int depth) {
117: int slot = exists(name);
118:
119: if (slot >= 0) {
120: return new DVarNode(position, ((depth << 16) | slot), name);
121: }
122:
123: return getEnclosingScope().declare(position, name, depth + 1);
124: }
125: }
|