001: /*=============================================================================
002: * Copyright Texas Instruments 2000-2004. All Rights Reserved.
003: *
004: * This program is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2 of the License, or (at your option) any later version.
008: *
009: * This program is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: *
018: * $ProjectHeader: OSCRIPT 0.155 Fri, 20 Dec 2002 18:34:22 -0800 rclark $
019: */
020:
021: package oscript.data;
022:
023: import oscript.exceptions.*;
024: import oscript.util.*;
025:
026: /**
027: * The <code>FunctionScope</code> to implement the scope for a function.
028: *
029: * @author Rob Clark (rob@ti.com)
030: */
031: public class FunctionScope extends BasicScope {
032: protected Function fxn;
033:
034: /**
035: * Class Constructor.
036: *
037: * @param fxn the function
038: * @param previous the previous
039: * @param smit shared member idx table
040: * @param members the members table, containing function arguments
041: */
042: public FunctionScope(Function fxn, Scope previous,
043: SymbolTable smit, MemberTable members) {
044: super (previous, smit, members);
045: this .fxn = fxn;
046: }
047:
048: protected FunctionScope(Function fxn, Scope previous,
049: SymbolTable smit) {
050: super (previous, smit);
051: this .fxn = fxn;
052: }
053:
054: /**
055: * Overridden to check for statics
056: */
057: protected Value getMemberImpl(int id) {
058: Value val = super .getMemberImpl(id);
059:
060: if (val == null)
061: val = fxn.getStaticMember(id);
062:
063: return val;
064: }
065:
066: /**
067: * Lookup the "super" within a scope. Within a function body, "super"
068: * is the overriden function (if there is one).
069: *
070: * @return the "this" ScriptObject within this scope
071: */
072: public Value getSuper() {
073: return new OSuper(this , fxn.getOverriden());
074: }
075:
076: /**
077: * Lookup the qualified "this" within a scope. The qualified "this" is
078: * the first scope chain node that is an object and an instance of the
079: * specified type, rather than a regular scope chain node.
080: *
081: * @param val the type that the "this" qualifies
082: * @return the qualified "this" ScriptObject within this scope
083: */
084: public Value getThis(Value val) {
085: if (fxn == val.unhand())
086: return new OThis(this );
087: return super .getThis(val);
088: }
089:
090: /**
091: * Lookup the "callee" within a scope. The "callee" is the first scope
092: * chain node that is a function-scope, rather than a regular scope chain
093: * node.
094: *
095: * @return the "callee" Function within callee scope
096: */
097: public Value getCallee() {
098: return fxn;
099: }
100:
101: /**
102: * The special value, <code>this</code> doesn't have the same permissions
103: * checking for the <code>getMember</code> method.
104: * <p>
105: * Because of how assignement to a Reference works, this will get
106: * unhand()'d if it is assigned or passed as an argument, so the special
107: * privilages cannot be passed to another function.
108: */
109: protected static class OThis extends AbstractReference {
110: private Scope scope;
111: private Scope scriptObject;
112:
113: OThis(Scope scope) {
114: super ();
115: this .scope = scope;
116:
117: while (!(scope instanceof ScriptObject))
118: scope = scope.previous;
119: scriptObject = scope;
120:
121: if (scriptObject == null)
122: throw new ProgrammingErrorException(
123: "this shouldn't happen");
124: }
125:
126: protected Value get() {
127: return scriptObject;
128: }
129:
130: public Value getMember(int id, boolean exception)
131: throws PackagedScriptObjectException {
132: // first check constructor scope:
133: Value val = scope.getMemberImpl(id);
134:
135: // then script-object scope:
136: if (val == null)
137: val = scriptObject.getMemberImpl(id);
138:
139: if ((val == null) && exception)
140: throw noSuchMember(Symbol.getSymbol(id).castToString());
141:
142: return val;
143: }
144: }
145:
146: /**
147: * Super object in most cases acts as the overriden function value, but
148: * overrides {@link #getMember(int,boolean)} to allow to access the
149: * other overriden function values, ie: <code>super.foo()</code>
150: */
151: protected static class OSuper extends AbstractReference {
152: private Scope scope;
153: private Value val;
154:
155: OSuper(Scope scope, Value val) {
156: if (val == null)
157: val = NULL;
158:
159: this .scope = scope;
160: this .val = val;
161: }
162:
163: protected Value get() {
164: return val;
165: }
166:
167: public Value getMember(int id, boolean exception)
168: throws PackagedScriptObjectException {
169: try {
170: Value member = scope.lookupInScope(id);
171: member = member.unhand();
172: if (member instanceof Function)
173: return ((Function) member).getOverriden();
174: } catch (PackagedScriptObjectException e) {
175: }
176: return val.getMember(id, exception);
177: }
178: }
179: }
180:
181: /*
182: * Local Variables:
183: * tab-width: 2
184: * indent-tabs-mode: nil
185: * mode: java
186: * c-indentation-style: java
187: * c-basic-offset: 2
188: * eval: (c-set-offset 'substatement-open '0)
189: * eval: (c-set-offset 'case-label '+)
190: * eval: (c-set-offset 'inclass '+)
191: * eval: (c-set-offset 'inline-open '0)
192: * End:
193: */
|