Source Code Cross Referenced for Function.java in  » Scripting » oscript-2.10.4 » oscript » data » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Scripting » oscript 2.10.4 » oscript.data 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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 java.io.*;
024:        import java.util.*;
025:
026:        import oscript.syntaxtree.FunctionPrimaryPrefix;
027:        import oscript.util.StackFrame;
028:        import oscript.util.MemberTable;
029:        import oscript.util.SymbolTable;
030:        import oscript.exceptions.*;
031:        import oscript.NodeEvaluator;
032:
033:        /**
034:         * A script function/constructor.  Since native (and other) objects that
035:         * behave as a function can re-use some functionality (ie checking number
036:         * of args, type casting, etc., the stuff specific to a script function/
037:         * constructor is pushed out into a seperate class.
038:         * 
039:         * @author Rob Clark (rob@ti.com)
040:         */
041:        public class Function extends Type {
042:            /**
043:             * The type object for an script function.
044:             */
045:            public final static Value TYPE = BuiltinType
046:                    .makeBuiltinType("oscript.data.Function");
047:            public final static String PARENT_TYPE_NAME = "oscript.data.OObject";
048:            public final static String TYPE_NAME = "Function";
049:            public final static String[] MEMBER_NAMES = new String[] {
050:                    "getName", "getComment", "getMinimumArgCount",
051:                    "takesVarArgs", "getArgNames", "isA", "castToString",
052:                    "callAsFunction", "callAsConstructor", "callAsExtends" };
053:
054:            /**
055:             * The scope this function is defined in.  This does not change throughout
056:             * the life of the function.
057:             */
058:            private final Scope enclosingScope;
059:
060:            /**
061:             * The scope the static members of this function are defined in.  When
062:             * the function is constructed, if there are any static members, they
063:             * are evaluated within this scope.  Otherwise this is null.
064:             */
065:            private final Scope staticScope;
066:
067:            /**
068:             * The function this function extends, if any.
069:             */
070:            private final Value super Fxn;
071:
072:            /**
073:             * The shared function data... parameters that are shared by all instances
074:             * of the same function.
075:             * <p>
076:             * public for {@link StackFrame#evalNode}
077:             */
078:            public final FunctionData fd;
079:
080:            /**
081:             * If this function overrides a value, this is the previous value.
082:             */
083:            private Value overriden;
084:
085:            /**
086:             * In order to keep function instances more lightweight, the values that
087:             * will be the same for any instance of a function representing the same
088:             * portion of the parse tree have been split out into this class, in order
089:             * to be shared between different function instances.
090:             */
091:            public static final class FunctionData implements  Externalizable {
092:                /* 
093:                 * XXX   all these would be final if it weren't for needing the no-arg
094:                 *       constructor for serialization
095:                 */
096:
097:                /**
098:                 * The node-evaluator for evaluating the body of this function.
099:                 * <p>
100:                 * only public for {@link StackFrame}
101:                 */
102:                public NodeEvaluator program;
103:
104:                /**
105:                 * The node-evaluator for evaluating the static body of this function.
106:                 */
107:                NodeEvaluator sprogram;
108:
109:                /**
110:                 * The expressions to evaluate to determine args to superFxn.
111:                 */
112:                NodeEvaluator exprList;
113:
114:                /**
115:                 * The id of this function.
116:                 */
117:                int id;
118:
119:                /**
120:                 * The ids of the arguments and there permissions.  The n'th parameter
121:                 * to the function has its <code>id</code> specified by the 2*n element
122:                 * in the array, and <code>attr</code> specified by the 2*n+1 element in
123:                 * the array.
124:                 */
125:                int[] argIds;
126:
127:                /**
128:                 * The number of args (if not vararg fxn), or minimum number of args (if
129:                 * vararg fxn).
130:                 */
131:                int nargs;
132:
133:                /**
134:                 * Is this a var-args function.  If it is, then the zero or more remaining
135:                 * args to the function are copied into an array that is assigned to the
136:                 * last arg to the function.
137:                 */
138:                boolean varargs;
139:
140:                /**
141:                 * A hint from the parser about whether we need to create an extra level
142:                 * of scope (ie. there are variables declared in that scope)
143:                 */
144:                boolean hasVarInScope;
145:
146:                /**
147:                 * A hint from the parser about whether scope storage can be allocated from
148:                 * the stack, which can only be done if there are no functions declared
149:                 * within this function
150:                 * <p>
151:                 * only public for {@link StackFrame}
152:                 */
153:                public boolean hasFxnInScope;
154:
155:                /**
156:                 * Comment generated from javadoc comment block in src file.
157:                 */
158:                Value comment;
159:
160:                /**
161:                 * Class Constructor.
162:                 * 
163:                 * @param id           the id of the symbol that maps to the member, ie. it's name
164:                 * @param argIds       array of argument ids and attributes
165:                 * @param varargs      is this a function that can take a variable number of args?
166:                 * @param exprList     expressions to evaluate to get args to <code>superFxn</code> 
167:                 *    or <code>null</code> if <code>superFxn</code> is <code>null</code>
168:                 * @param program      the body of the function
169:                 * @param sprogram     the static body of the function, or <code>null</code>
170:                 * @param hasVarInScope whether one or more vars/functions are declared in the
171:                 *    function body's scope... this is a hint from the parser to tell us if we
172:                 *    can avoid creating a scope object at runtime
173:                 * @param hasFxnInScope whether one or more functions are enclosed by this function
174:                 *    body's scope... this is a hint from the parser to tell us if we can allocate
175:                 *    scope storage from the stack
176:                 * @param comment      html formatted comment generated from javadoc 
177:                 *    comment in src file, or <code>null</code>
178:                 */
179:                public FunctionData(int id, int[] argIds, boolean varargs,
180:                        NodeEvaluator exprList, NodeEvaluator program,
181:                        NodeEvaluator sprogram, boolean hasVarInScope,
182:                        boolean hasFxnInScope, Value comment) {
183:                    this .id = id;
184:                    this .argIds = argIds;
185:                    this .varargs = varargs;
186:                    this .exprList = exprList;
187:                    this .program = program;
188:                    this .sprogram = sprogram;
189:                    this .hasVarInScope = hasVarInScope;
190:                    this .hasFxnInScope = hasFxnInScope;
191:                    this .comment = comment;
192:
193:                    if (varargs)
194:                        nargs = (argIds.length / 2) - 1;
195:                    else
196:                        nargs = (argIds.length / 2);
197:                }
198:
199:                /* 
200:                 * Externalizable Support:
201:                 */
202:
203:                public FunctionData() {
204:                }
205:
206:                /**
207:                 * Derived class that implements {@link java.io.Externalizable} must
208:                 * call this if it overrides it.  It should override it to save/restore
209:                 * it's own state.
210:                 */
211:                public void readExternal(ObjectInput in) throws IOException,
212:                        ClassNotFoundException {
213:                    program = (NodeEvaluator) (in.readObject());
214:                    sprogram = (NodeEvaluator) (in.readObject());
215:                    exprList = (NodeEvaluator) (in.readObject());
216:                    id = in.readInt();
217:                    argIds = new int[in.readInt()];
218:                    for (int i = 0; i < argIds.length; i++)
219:                        argIds[i] = in.readInt();
220:                    nargs = in.readInt();
221:                    varargs = in.readBoolean();
222:                    hasVarInScope = in.readBoolean();
223:                    hasFxnInScope = in.readBoolean();
224:                    if (in.readByte() == 1) {
225:                        comment = new OString();
226:                        comment.readExternal(in);
227:                    }
228:                }
229:
230:                /**
231:                 * Derived class that implements {@link Externalizable} must
232:                 * call this if it overrides it.  It should override it to save/restore
233:                 * it's own state.
234:                 */
235:                public void writeExternal(ObjectOutput out) throws IOException {
236:                    out.writeObject(program);
237:                    out.writeObject(sprogram);
238:                    out.writeObject(exprList);
239:                    out.writeInt(id);
240:                    out.writeInt(argIds.length);
241:                    for (int i = 0; i < argIds.length; i++)
242:                        out.writeInt(argIds[i]);
243:                    out.writeInt(nargs);
244:                    out.writeBoolean(varargs);
245:                    out.writeBoolean(hasVarInScope);
246:                    out.writeBoolean(hasFxnInScope);
247:                    if (comment != null) {
248:                        out.writeByte(1);
249:                        comment.writeExternal(out);
250:                    } else {
251:                        out.writeByte(0);
252:                    }
253:                }
254:
255:                /**
256:                 * Map arguments to a function into the member-table which is used for
257:                 * a function scope.  Since the compiler ensures that the function
258:                 * parameters map to idx 0 thru n in the function-scope, all this has
259:                 * to do is collapse the var-arg parameter (if present) into a single
260:                 * array, and if there is a function within this function's body copy
261:                 * into new table..  This also ensures that the correct number of parameters is
262:                 * passed to the function.  This is used instead of {@link #addArgs} 
263:                 * when calling as a function.
264:                 * <p>
265:                 * XXX this could be used in case of constructor scope, by stripping
266:                 * out private parameters... maybe
267:                 * 
268:                 * @param args   the input arguments
269:                 * @return
270:                 */
271:                public final MemberTable mapArgs(MemberTable args) {
272:                    if (hasFxnInScope)
273:                        args = args.safeCopy();
274:
275:                    int alen = args.length();
276:
277:                    if ((alen == nargs) || (varargs && (alen >= nargs))) {
278:                        if (varargs) {
279:                            // XXX in theory, it should be possible to bring back an optimization
280:                            // to avoid the copy, if nargs==0....
281:
282:                            OArray arr = new OArray(alen - nargs);
283:                            for (int i = nargs; i < alen; i++)
284:                                arr.elementAt(i - nargs).opAssign(
285:                                        args.referenceAt(i));
286:
287:                            args.ensureCapacity(nargs);
288:                            args.referenceAt(nargs).reset(arr);
289:                        }
290:
291:                        return args;
292:                    } else {
293:                        throw PackagedScriptObjectException
294:                                .makeExceptionWrapper(new OIllegalArgumentException(
295:                                        "wrong number of args!"));
296:                    }
297:                }
298:
299:                /**
300:                 * A helper to populate a fxn-scope with args
301:                 */
302:                public final void addArgs(FunctionScope fxnScope,
303:                        MemberTable args) {
304:                    int len = (args == null) ? 0 : args.length();
305:
306:                    if ((len == nargs) || (varargs && (len >= nargs))) {
307:                        for (int i = 0; i < nargs; i++) {
308:                            int id = argIds[2 * i];
309:                            int attr = argIds[2 * i + 1];
310:
311:                            fxnScope.createMember(id, attr).opAssign(
312:                                    args.referenceAt(i));
313:                        }
314:
315:                        if (varargs) {
316:                            int id = argIds[2 * nargs];
317:                            int attr = argIds[2 * nargs + 1];
318:
319:                            // XXX in theory, it should be possible to bring back an optimization
320:                            // to avoid the copy, if nargs==0....
321:
322:                            OArray arr = new OArray(len - nargs);
323:                            for (int i = nargs; i < len; i++)
324:                                arr.elementAt(i - nargs).opAssign(
325:                                        args.referenceAt(i));
326:
327:                            fxnScope.createMember(id, attr).opAssign(arr);
328:                        }
329:                    } else {
330:                        throw PackagedScriptObjectException
331:                                .makeExceptionWrapper(new OIllegalArgumentException(
332:                                        "wrong number of args!"));
333:                    }
334:                }
335:
336:                public Value getName() {
337:                    return Symbol.getSymbol(id);
338:                }
339:            }
340:
341:            /*=======================================================================*/
342:            /**
343:             * Class Constructor.  Construct an anonymous function.
344:             * 
345:             * @param enclosingScope the context the function was declared in
346:             * @param superFxn     the function this function extends, or 
347:             *    <code>null</code>
348:             * @param fd           the shared function data, for all instances 
349:             *    of this function
350:             * 
351:             */
352:            public Function(Scope enclosingScope, Value super Fxn,
353:                    FunctionData fd) {
354:                super ();
355:
356:                // every script type implicitly inherits from <i>Object</i>
357:                if (super Fxn == null)
358:                    super Fxn = OObject.TYPE;
359:
360:                // if this function is overriding a function in an object scope, keep a
361:                // reference to the overriden function:
362:                if ((fd.id != FunctionPrimaryPrefix.ANON_FXN_ID)
363:                        && (enclosingScope instanceof  ConstructorScope)) {
364:                    Scope scope = enclosingScope.getPreviousScope();
365:                    while (!(scope instanceof  ScriptObject))
366:                        scope = scope.getPreviousScope();
367:                    overriden = scope.getMemberImpl(fd.id);
368:                    if (overriden != null)
369:                        overriden = overriden.unhand();
370:                }
371:
372:                // XXX seems to cause apple's VM to bus-error... not sure if it causes 
373:                // problems on other platforms or not. --RDC
374:                //    if(DEBUG)
375:                //      if( !enclosingScope.isSafe() )
376:                //        StackFrame.dumpStack(System.err);
377:
378:                this .enclosingScope = enclosingScope;
379:                this .super Fxn = super Fxn;
380:                this .fd = fd;
381:
382:                if (fd.sprogram != null) {
383:                    staticScope = new BasicScope(enclosingScope);
384:                    StackFrame.currentStackFrame().evalNode(fd.sprogram,
385:                            staticScope);
386:                } else {
387:                    staticScope = null;
388:                }
389:            }
390:
391:            /*=======================================================================*/
392:            /**
393:             * Get the function that this function extends, or <code>null</code> if
394:             * none.
395:             */
396:            Value getSuper() {
397:                return super Fxn;
398:            }
399:
400:            /*=======================================================================*/
401:            /**
402:             * If this function overrides a value, this method returns it.  Otherwise
403:             * it returns <code>null</code>.
404:             */
405:            Value getOverriden() {
406:                return overriden;
407:            }
408:
409:            /*=======================================================================*/
410:            /**
411:             * Get the type of this object.  The returned type doesn't have to take
412:             * into account the possibility of a script type extending a built-in
413:             * type, since that is handled by {@link #getType}.
414:             * 
415:             * @return the object's type
416:             */
417:            protected Value getTypeImpl() {
418:                return TYPE;
419:            }
420:
421:            /*=======================================================================*/
422:            /**
423:             * Get the name of this function.  An anonymous function will have the
424:             * name "anon".
425:             * 
426:             * @return the function's name
427:             */
428:            public Value getName() {
429:                return fd.getName();
430:            }
431:
432:            /*=======================================================================*/
433:            /**
434:             * Get the comment block.  If there was a javadoc comment block preceding
435:             * the definition of this function in the src file, it can be accessed
436:             * with this method.
437:             * 
438:             * @return the function's comment, or <code>null</code>
439:             */
440:            public Value getComment() {
441:                return fd.comment;
442:            }
443:
444:            /*=======================================================================*/
445:            /**
446:             * Get the minimum number of args that should be passed to this function.
447:             * If {@link #isVarArgs} returns <code>true</code>, then it is possible
448:             * to pass more arguments to this function, otherwise, you should pass
449:             * exactly this number of args to the function.
450:             * 
451:             * @return minimum number of args to pass when calling this function
452:             * @see #isVarArgs
453:             * @see #getArgNames
454:             */
455:            public int getMinimumArgCount() {
456:                return fd.nargs;
457:            }
458:
459:            /*=======================================================================*/
460:            /**
461:             * Can this function be called with a variable number of arguments?
462:             * @see #getMinimumArgCount
463:             * @see #getArgNames
464:             */
465:            public boolean takesVarArgs() {
466:                return fd.varargs;
467:            }
468:
469:            /*=======================================================================*/
470:            /**
471:             * Get the names of the arguments to the function, in order.  If this 
472:             * function takes a variable number of arguments, the last name in the 
473:             * array is the "var-arg" variable, to which the array of all remaining
474:             * arguments are bound.
475:             */
476:            public Value[] getArgNames() {
477:                Value[] names = new Value[fd.argIds.length / 2];
478:                for (int i = 0; i < names.length; i++)
479:                    names[i] = Symbol.getSymbol(fd.argIds[2 * i]);
480:                return names;
481:            }
482:
483:            /* Note:  arg-permissions are not made visible, because that seems
484:             *        to me like an implementation detail, whereas the arg-names
485:             *        is (sort of) part of the interface
486:             */
487:
488:            /*=======================================================================*/
489:            /**
490:             * If this object is a type, determine if an instance of this type is
491:             * an instance of the specified type, ie. if this is <code>type</code>,
492:             * or a subclass.
493:             * 
494:             * @param type         the type to compare this type to
495:             * @return <code>true</code> or <code>false</code>
496:             * @throws PackagedScriptObjectException(NoSuchMemberException)
497:             */
498:            public boolean isA(Value type) {
499:                return super .isA(type) || this .super Fxn.isA(type);
500:            }
501:
502:            private static final int BOPCAST = Symbol.getSymbol("_bopCast")
503:                    .getId();
504:
505:            /*=======================================================================*/
506:            /**
507:             * Perform the cast operation, <code>(a)b</code> is equivalent to <code>a.bopCast(b)</code>
508:             * 
509:             * @param val          the other value
510:             * @return the result
511:             * @throws PackagedScriptObjectException(NoSuchMemberException)
512:             */
513:            public Value bopCast(Value val)
514:                    throws PackagedScriptObjectException {
515:                Value bopCast = getMember(BOPCAST, false);
516:                if (bopCast != null)
517:                    return bopCast.callAsFunction(new Value[] { val });
518:                return super .bopCast(val);
519:            }
520:
521:            // bopCastR would be an instance member, not static (class) member
522:
523:            /*=======================================================================*/
524:            /**
525:             * Convert this object to a native java <code>String</code> value.
526:             * 
527:             * @return a String value
528:             * @throws PackagedScriptObjectException(NoSuchMethodException)
529:             */
530:            public String castToString() throws PackagedScriptObjectException {
531:                return "[function: " + getName() + "]";
532:            }
533:
534:            /*=======================================================================*/
535:            /**
536:             * Call this object as a function.
537:             * 
538:             * @param sf           the current stack frame
539:             * @param args         the arguments to the function, or <code>null</code> if none
540:             * @return the value returned by the function
541:             * @throws PackagedScriptObjectException
542:             * @see Function
543:             */
544:            public Value callAsFunction(StackFrame sf, MemberTable args)
545:                    throws PackagedScriptObjectException {
546:                if (super Fxn != OObject.TYPE)
547:                    throw PackagedScriptObjectException
548:                            .makeExceptionWrapper(new OUnsupportedOperationException(
549:                                    getName() + ": cannot call as function!"));
550:
551:                if (!fd.hasVarInScope && (fd.argIds.length == 0)
552:                        && (args == null)) {
553:                    return (Value) (sf.evalNode(fd.program, enclosingScope));
554:                } else {
555:                    Scope scope;
556:                    SymbolTable smit = fd.program
557:                            .getSharedMemberIndexTable(NodeEvaluator.ALL);
558:                    if (args == null)
559:                        args = fd.hasFxnInScope ? new OArray(0) : sf
560:                                .allocateMemberTable((short) 0);
561:                    args = fd.mapArgs(args); // even if args length is zero, to deal with var-args
562:                    if (!fd.hasFxnInScope)
563:                        scope = sf.allocateFunctionScope(this , enclosingScope,
564:                                smit, args);
565:                    else
566:                        scope = new FunctionScope(this , enclosingScope, smit,
567:                                args);
568:                    try {
569:                        return (Value) (sf.evalNode(fd.program, scope));
570:                    } finally {
571:                        scope.free();
572:                    }
573:                }
574:            }
575:
576:            /*=======================================================================*/
577:            /**
578:             * Call this object as a constructor.
579:             * 
580:             * @param sf           the current stack frame
581:             * @param args         the arguments to the function, or <code>null</code> if none
582:             * @return the newly constructed object
583:             * @throws PackagedScriptObjectException
584:             * @see Function
585:             */
586:            public Value callAsConstructor(StackFrame sf, MemberTable args)
587:                    throws PackagedScriptObjectException {
588:                /* XXX we should only need to create ConstructorScope if the number of
589:                 * args is greater than zero, and hasVarInScope
590:                 */
591:                ScriptObject newThisScope = new ScriptObject(
592:                        this ,
593:                        enclosingScope,
594:                        fd.program
595:                                .getSharedMemberIndexTable(NodeEvaluator.PUBPROT));
596:                ConstructorScope fxnScope = new ConstructorScope(
597:                        this ,
598:                        newThisScope,
599:                        fd.program
600:                                .getSharedMemberIndexTable(NodeEvaluator.PRIVATE));
601:
602:                fd.addArgs(fxnScope, args);
603:
604:                MemberTable super FxnArgs;
605:                if (fd.exprList != null)
606:                    super FxnArgs = (MemberTable) (sf.evalNode(fd.exprList,
607:                            fxnScope));
608:                else
609:                    super FxnArgs = new OArray(0);
610:
611:                super Fxn.callAsExtends(sf, newThisScope, super FxnArgs);
612:
613:                sf.evalNode(fd.program, fxnScope);
614:
615:                return newThisScope;
616:            }
617:
618:            /*=======================================================================*/
619:            /**
620:             * Call this object as a parent class constructor.
621:             * 
622:             * @param sf           the current stack frame
623:             * @param scope        the object
624:             * @param args         the arguments to the function, or <code>null</code> if none
625:             * @return the value returned by the function
626:             * @throws PackagedScriptObjectException
627:             * @see Function
628:             */
629:            public Value callAsExtends(StackFrame sf, Scope scope,
630:                    MemberTable args) throws PackagedScriptObjectException {
631:                /* XXX we should only need to create ConstructorScope if the number of
632:                 * args is greater than zero, and hasVarInScope
633:                 */
634:
635:                scope = new ForkScope(scope, enclosingScope);
636:                ConstructorScope fxnScope = new ConstructorScope(
637:                        this ,
638:                        scope,
639:                        fd.program
640:                                .getSharedMemberIndexTable(NodeEvaluator.PRIVATE));
641:
642:                fd.addArgs(fxnScope, args);
643:
644:                MemberTable super FxnArgs;
645:                if (fd.exprList != null)
646:                    super FxnArgs = (MemberTable) (sf.evalNode(fd.exprList,
647:                            fxnScope));
648:                else
649:                    super FxnArgs = new OArray(0);
650:
651:                super Fxn.callAsExtends(sf, scope, super FxnArgs);
652:
653:                return (Value) (sf.evalNode(fd.program, fxnScope));
654:            }
655:
656:            /*=======================================================================*/
657:            /**
658:             * Get a member of this object.
659:             * 
660:             * @param id           the id of the symbol that maps to the member
661:             * @param exception    whether an exception should be thrown if the
662:             *   member object is not resolved
663:             * @return a reference to the member
664:             * @throws PackagedScriptObjectException(NoSuchMethodException)
665:             * @throws PackagedScriptObjectException(NoSuchMemberException)
666:             */
667:            public Value getMember(int id, boolean exception)
668:                    throws PackagedScriptObjectException {
669:                Value val = getStaticMember(id);
670:
671:                if (val == null)
672:                    val = super .getMember(id, exception);
673:
674:                return val;
675:            }
676:
677:            /*=======================================================================*/
678:            /**
679:             * Get a member of this type.  This is used to interface to the java
680:             * method of having members be attributes of a type.  Regular object-
681:             * script object's members are attributes of the object, but in the
682:             * case of java types (including built-in types), the members are
683:             * attributes of the type.
684:             * 
685:             * @param obj          an object of this type
686:             * @param id           the id of the symbol that maps to the member
687:             * @return a reference to the member, or null
688:             */
689:            protected Value getTypeMember(Value obj, int id) {
690:                Value val = super Fxn.getTypeMember(obj, id);
691:
692:                if (val == null)
693:                    val = getStaticMember(id);
694:
695:                return val;
696:            }
697:
698:            /*=======================================================================*/
699:            /**
700:             * Get a static member of this function object.
701:             */
702:            final Value getStaticMember(int id) {
703:                Value val = null;
704:
705:                if (staticScope != null)
706:                    val = staticScope.getMember(id, false);
707:
708:                return val;
709:            }
710:
711:            /*=======================================================================*/
712:            /**
713:             * Derived classes that implement {@link #getMember} should also
714:             * implement this.
715:             * 
716:             * @param s   the set to populate
717:             * @param debugger  <code>true</code> if being used by debugger, in
718:             *   which case both public and private/protected field names should 
719:             *   be returned
720:             * @see #getMember
721:             */
722:            protected void populateMemberSet(Set s, boolean debugger) {
723:                if (staticScope != null)
724:                    staticScope.populateMemberSet(s, debugger);
725:            }
726:
727:            /*=======================================================================*/
728:            /**
729:             * Derived classes that implement {@link #getTypeMember} should also
730:             * implement this.
731:             * 
732:             * @param s   the set to populate
733:             * @param debugger  <code>true</code> if being used by debugger, in
734:             *   which case both public and private/protected field names should 
735:             *   be returned
736:             * @see #getTypeMember
737:             */
738:            protected void populateTypeMemberSet(Set s, boolean debugger) {
739:                if (super Fxn != null)
740:                    super Fxn.populateTypeMemberSet(s, debugger);
741:            }
742:
743:            /*=======================================================================*/
744:            /**
745:             */
746:            public static Value extractJavadocComment(Vector specials,
747:                    Value name, int[] argIds) {
748:                Value[] argNames = new Value[argIds.length / 2];
749:                for (int i = 0; i < argNames.length; i++)
750:                    argNames[i] = Symbol.getSymbol(argIds[2 * i]);
751:
752:                StringBuffer sb = new StringBuffer();
753:
754:                for (int i = 0; i < specials.size(); i++)
755:                    sb.append(((oscript.syntaxtree.NodeToken) (specials
756:                            .elementAt(i))).toString());
757:
758:                return extractJavadocComment(sb.toString(), name, argNames);
759:            }
760:
761:            public static Value extractJavadocComment(String str, Value name,
762:                    Value[] argNames) {
763:                int idx = str.lastIndexOf("/**"); /**/
764:
765:                if (idx == -1)
766:                    return null;
767:
768:                str = str.substring(idx + "/**".length()); /**/
769:
770:                StringBuffer sb = new StringBuffer();
771:
772:                sb.append("<html><head><title>" + name
773:                        + "</title></head><body>");
774:                extractJavadocCommentBodyImpl(sb, str, name, argNames);
775:                sb.append("</body></html>");
776:
777:                return new OString(sb.toString());
778:            }
779:
780:            public static Value extractJavadocCommentBody(String str,
781:                    Value name, Value[] argNames) {
782:                int idx = str.lastIndexOf("/**"); /**/
783:
784:                if (idx == -1)
785:                    return null;
786:
787:                str = str.substring(idx + "/**".length()); /**/
788:
789:                StringBuffer sb = new StringBuffer();
790:
791:                extractJavadocCommentBodyImpl(sb, str, name, argNames);
792:
793:                return new OString(sb.toString());
794:            }
795:
796:            private static String extractJavadocCommentBodyImpl(
797:                    StringBuffer sb, String str, Value name, Value[] argNames) {
798:                BufferedReader br = new BufferedReader(new StringReader(str));
799:
800:                LinkedList paramList = new LinkedList();
801:                LinkedList throwsList = new LinkedList();
802:                LinkedList returnList = new LinkedList(); // shouldn't have more than one!
803:
804:                sb.append("<pre>function <b>" + name + "</b>(");
805:                for (int i = 0; i < argNames.length; i++)
806:                    sb.append(((i == 0) ? "" : ", ") + argNames[i]);
807:                //     if(fd.varargs)
808:                //       sb.append("...");
809:                sb.append(")</pre>");
810:
811:                try {
812:                    while ((str = strip(br.readLine())) != null) {
813:                        // check for @XXX parameters:
814:                        if (str.startsWith("@"))
815:                            break;
816:                        else
817:                            sb.append(str + " ");
818:                    }
819:
820:                    // handle @XXX paramters:
821:                    while (str != null) {
822:                        LinkedList list = null;
823:                        String match = null;
824:
825:                        if (str.startsWith("@param")) {
826:                            list = paramList;
827:                            match = "@param";
828:                        } else if (str.startsWith("@throws")) {
829:                            list = throwsList;
830:                            match = "@throws";
831:                        } else if (str.startsWith("@return")) {
832:                            list = returnList;
833:                            match = "@return";
834:                        }
835:                        // else ignore...
836:
837:                        if (list != null) {
838:                            str = str.substring(match.length()).trim();
839:                            String val = str;
840:
841:                            // check for continuation on following line:
842:                            do {
843:                                str = strip(br.readLine());
844:                                if ((str == null) || str.startsWith("@"))
845:                                    break;
846:                                else
847:                                    val += str;
848:                            } while (true);
849:
850:                            list.add(val);
851:
852:                            continue;
853:                        }
854:
855:                        str = strip(br.readLine());
856:                    }
857:                } catch (IOException e) {
858:                    e.printStackTrace();
859:                    throw new ProgrammingErrorException(
860:                            "this shouldn't happen: " + e);
861:                }
862:
863:                if (paramList.size() > 0)
864:                    appendParamBlock(sb, "Parameters", paramList);
865:
866:                if (throwsList.size() > 0)
867:                    appendParamBlock(sb, "Exceptions", throwsList);
868:
869:                if (returnList.size() > 0)
870:                    sb.append("<dl><dt><b>Returns</b></dt><dd>"
871:                            + returnList.getFirst() + "</dd></dl>");
872:
873:                return sb.toString();
874:            }
875:
876:            // strip off leading whitespace, and "*"'s
877:            private static final String strip(String str) {
878:                if (str == null)
879:                    return null;
880:                str = str.trim();
881:                while (str.startsWith("*/"))
882:                    str = str.substring(2);
883:                while (str.startsWith("*"))
884:                    str = str.substring(1);
885:                str = str.trim();
886:                return str;
887:            }
888:
889:            private static final void appendParamBlock(StringBuffer sb,
890:                    String title, LinkedList list) {
891:                sb.append("<dl><dt><b>" + title + "</b></dt>");
892:
893:                for (Iterator itr = list.iterator(); itr.hasNext();) {
894:                    String str = (String) (itr.next());
895:                    String name;
896:                    int idx = str.indexOf(" ");
897:
898:                    if (idx != -1) {
899:                        name = str.substring(0, idx);
900:                        str = str.substring(idx).trim();
901:                    } else {
902:                        name = str;
903:                        str = "";
904:                    }
905:
906:                    sb.append("<dd><code>" + name + "</code> - " + str
907:                            + "</dd>");
908:                }
909:
910:                sb.append("</dl>");
911:            }
912:        }
913:
914:        /*
915:         *   Local Variables:
916:         *   tab-width: 2
917:         *   indent-tabs-mode: nil
918:         *   mode: java
919:         *   c-indentation-style: java
920:         *   c-basic-offset: 2
921:         *   eval: (c-set-offset 'substatement-open '0)
922:         *   eval: (c-set-offset 'case-label '+)
923:         *   eval: (c-set-offset 'inclass '+)
924:         *   eval: (c-set-offset 'inline-open '0)
925:         *   End:
926:         */
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.