Source Code Cross Referenced for ClassExp.java in  » Scripting » Nice » gnu » expr » 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 » Nice » gnu.expr 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package gnu.expr;
002:
003:        import gnu.bytecode.*;
004:        import gnu.mapping.*;
005:        import java.util.Vector;
006:
007:        public class ClassExp extends LambdaExp {
008:            public boolean needsConstructor;
009:
010:            boolean simple;
011:
012:            public boolean isSimple() {
013:                return simple;
014:            }
015:
016:            public void setSimple(boolean value) {
017:                simple = value;
018:            }
019:
020:            int accessFlags;
021:
022:            public void setAccessFlags(int value) {
023:                accessFlags = value;
024:            }
025:
026:            public boolean isInterface() {
027:                return (accessFlags & Access.INTERFACE) != 0;
028:            }
029:
030:            /** The class of instances of this class.
031:             * Same as super.type unless isMakingClassPair(), in which case super.type
032:             * is an interface, and instanceType is a class implementing the interface.
033:             * Using an interface plus a class gives us true multiple inheritance. */
034:            ClassType instanceType;
035:
036:            boolean makeClassPair;
037:
038:            public void setMakingClassPair(boolean val) {
039:                makeClassPair = val;
040:            }
041:
042:            /** True if we should make a pair of an interface and a class. */
043:            public boolean isMakingClassPair() {
044:                return makeClassPair;
045:            }
046:
047:            /** List of base classes and implemented interfaces. */
048:            public Expression[] super s;
049:
050:            public LambdaExp initMethod;
051:
052:            public ClassExp() {
053:                type = null;
054:                // Make sure we actually generate a class.
055:                setCanRead(true);
056:            }
057:
058:            /**
059:               Create a ClassExp object to represent an existing class.
060:               This ClassExp will not be compiled to a new class.
061:             */
062:            public ClassExp(ClassType type) {
063:                this ();
064:                this .type = this .instanceType = type;
065:                setName(type.getName());
066:            }
067:
068:            public Declaration addField(String name, Type type) {
069:                Declaration res = addDeclaration(name, type);
070:                res.setSimple(false);
071:                res.setFlag(Declaration.NONSTATIC_SPECIFIED);
072:                res.setCanRead(true);
073:                res.setCanWrite(true);
074:                res.noteValue(null);
075:
076:                // If the class already exists, find the corresponding field there.
077:                if (instanceType != null)
078:                    res.field = instanceType.getDeclaredField(name);
079:
080:                return res;
081:            }
082:
083:            /**
084:               Add a method to this class.
085:               @return the expression that should be used to call that method.
086:             */
087:            public ReferenceExp addMethod(LambdaExp method, boolean isPrivate) {
088:                Declaration decl = new Declaration(method.getName());
089:                decl.noteValue(method);
090:                decl.setFlag(Declaration.IS_CONSTANT
091:                        | Declaration.STATIC_SPECIFIED);
092:                decl.setProcedureDecl(true);
093:                if (isPrivate)
094:                    decl.setSpecifiedPrivate(true);
095:                method.nameDecl.context = this ;
096:
097:                method.nextSibling = this .firstChild;
098:                this .firstChild = method;
099:
100:                if (instanceType != null) {
101:                    Method m = instanceType.getDeclaredMethod(method.getName(),
102:                            method.getArgTypes());
103:                    if (m != null && !m.isConstructor()) {
104:                        m.eraseCode();
105:                        method.declareThis(instanceType);
106:                        method.primMethods = new Method[] { m };
107:                    }
108:                }
109:
110:                return new ReferenceExp(decl);
111:            }
112:
113:            /**
114:               Add a method to this class.
115:               @return the expression that should be used to call that method.
116:             */
117:            public ReferenceExp addMethod(LambdaExp method) {
118:                return addMethod(method, false);
119:            }
120:
121:            /*
122:            public Object eval (Environment env)
123:            {
124:              System.err.println("eval ClassExp");
125:              Class clas = evalToClass();
126:              return Type.make(clas);
127:              }
128:             */
129:
130:            public void compile(Compilation comp, Target target) {
131:                if (target instanceof  IgnoreTarget)
132:                    return;
133:                ClassType new_class = compile(comp);
134:                String className = new_class.getName();
135:                // Type.make(Class.forname)
136:
137:                ClassType typeClass = ClassType.make("java.lang.Class");
138:                Method forNameClassMethod = typeClass.addMethod("forName",
139:                        comp.string1Arg, typeClass, Access.STATIC
140:                                | Access.PUBLIC);
141:                gnu.bytecode.CodeAttr code = comp.getCode();
142:                code.emitPushString(className);
143:                code.emitInvokeStatic(forNameClassMethod);
144:                ClassType typeType;
145:                int nargs;
146:                boolean needsLink = getNeedsClosureEnv();
147:                if (isMakingClassPair() || needsLink) {
148:                    code.emitPushString(instanceType.getName());
149:                    code.emitInvokeStatic(forNameClassMethod);
150:                    typeType = ClassType.make("gnu.expr.PairClassType");
151:                    nargs = needsLink ? 3 : 2;
152:                } else {
153:                    typeType = ClassType.make("gnu.bytecode.Type");
154:                    nargs = 1;
155:                }
156:                Type[] argsClass = new Type[nargs];
157:                if (needsLink) {
158:                    comp.curLambda.loadHeapFrame(comp);
159:                    argsClass[--nargs] = Type.pointer_type;
160:                }
161:                while (--nargs >= 0)
162:                    argsClass[nargs] = typeClass;
163:                Method makeMethod = typeType.addMethod("make", argsClass,
164:                        typeType, Access.STATIC | Access.PUBLIC);
165:                code.emitInvokeStatic(makeMethod);
166:
167:                target.compileFromStack(comp, typeType);
168:            }
169:
170:            public String getJavaName() {
171:                return name == null ? "object" : Compilation
172:                        .mangleNameIfNeeded(name);
173:            }
174:
175:            public ClassType getCompiledClassType(Compilation comp) {
176:                if (!partsDeclared) {
177:                    getType();
178:                    declareParts(comp);
179:                }
180:                if (type.getName() == null) {
181:                    String name = getName();
182:                    if (name == null)
183:                        name = "object";
184:                    else {
185:                        int nlen = name.length();
186:                        if (nlen > 2 && name.charAt(0) == '<'
187:                                && name.charAt(nlen - 1) == '>')
188:                            name = name.substring(1, nlen - 1);
189:                    }
190:                    if (!isSimple() || this  instanceof  ObjectExp)
191:                        name = comp.generateClassName(name);
192:                    else
193:                    // Keep the name if it is fully qualified, mangle it instead
194:                    if (name.indexOf('.') == -1)
195:                        name = comp.mangleNameIfNeeded(name);
196:                    type.setName(name);
197:                }
198:                if (filename != null)
199:                    type.setSourceFile(filename);
200:                if (!isInterface())
201:                    comp.generateConstructor(getClassType(), this );
202:                return type;
203:            }
204:
205:            public void recomputeInterfaces() {
206:                setTypes();
207:            }
208:
209:            private void setTypes() {
210:                int len = super s == null ? 0 : super s.length;
211:                ClassType[] super Types = new ClassType[len];
212:                ClassType super Type = null;
213:                int j = 0;
214:                for (int i = 0; i < len; i++) {
215:                    Type st = Interpreter.getInterpreter()
216:                            .getTypeFor(super s[i]);
217:                    if (st == null || !(st instanceof  ClassType))
218:                        throw new Error("invalid super type");
219:                    ClassType t = (ClassType) st;
220:                    if ((t.getModifiers() & Access.INTERFACE) == 0) {
221:                        if (j < i)
222:                            throw new Error("duplicate superclass");
223:                        super Type = t;
224:                    } else
225:                        super Types[j++] = t;
226:                }
227:
228:                // If type is null, we simply want to recompute interfaces
229:                if (type == null) {
230:                    if (super Type == null) {
231:                        if (!isSimple()) {
232:                            PairClassType ptype = new PairClassType();
233:                            type = ptype;
234:                            setMakingClassPair(true);
235:                            instanceType = new ClassType();
236:                            type.setInterface(true);
237:                            ClassType[] interfaces = { type };
238:                            // Can we better.  FIXME.
239:                            instanceType.setSuper(Type.pointer_type);
240:                            instanceType.setInterfaces(interfaces);
241:                            ptype.instanceType = instanceType;
242:                        } else
243:                            instanceType = type = new ClassType(getName());
244:                        type.setSuper(Type.pointer_type);
245:                    } else {
246:                        instanceType = type = new ClassType(getName());
247:                        type.setSuper(super Type);
248:                    }
249:
250:                    instanceType.collectable = true;
251:                    // Access.SUPER mut be set on all non-interface classes
252:                    if (!isInterface())
253:                        accessFlags |= Access.SUPER;
254:                    instanceType.setModifiers(accessFlags);
255:                }
256:
257:                if (j > 0) {
258:                    ClassType[] interfaces;
259:                    if (j == len)
260:                        interfaces = super Types;
261:                    else {
262:                        interfaces = new ClassType[j];
263:                        System.arraycopy(super Types, 0, interfaces, 0, j);
264:                    }
265:                    type.setInterfaces(interfaces);
266:                }
267:            }
268:
269:            public Type getType() {
270:                if (type == null)
271:                    setTypes();
272:                return type;
273:            }
274:
275:            public ClassType getClassType() {
276:                return (ClassType) getType();
277:            }
278:
279:            boolean partsDeclared;
280:
281:            public void declareParts(Compilation comp) {
282:                if (partsDeclared)
283:                    return;
284:                partsDeclared = true;
285:                comp.topLambda = this ;
286:                comp.topClass = this .type;
287:                for (Declaration decl = firstDecl(); decl != null; decl = decl
288:                        .nextDecl()) {
289:                    // If the declaration derives from a method, don't create field.
290:                    // Also, field can already exist if the class is imported from a
291:                    // compiled package.
292:                    if (decl.getCanRead() && decl.field == null) {
293:                        int flags = 0;
294:                        if (decl.isSpecifiedPrivate())
295:                            flags |= Access.PRIVATE;
296:                        else
297:                            flags |= Access.PUBLIC;
298:                        if (decl.getFlag(Declaration.STATIC_SPECIFIED))
299:                            flags |= Access.STATIC;
300:                        if (isMakingClassPair()) {
301:                            flags |= Access.ABSTRACT;
302:                            Type ftype = decl.getType().getImplementationType();
303:                            type.addMethod(slotToMethodName("get", decl
304:                                    .getName()), flags, Type.typeArray0, ftype);
305:                            Type[] stypes = { ftype };
306:                            type.addMethod(slotToMethodName("set", decl
307:                                    .getName()), flags, stypes, Type.void_type);
308:                        } else
309:                        // This handles class fields.
310:                        {
311:                            if (decl.getFlag(Declaration.TRANSIENT))
312:                                flags |= Access.TRANSIENT;
313:                            if (decl.getFlag(Declaration.VOLATILE))
314:                                flags |= Access.VOLATILE;
315:                            if (decl.getFlag(Declaration.IS_CONSTANT))
316:                                flags |= Access.FINAL;
317:                            String fname = Compilation.mangleNameIfNeeded(decl
318:                                    .getName());
319:                            decl.field = instanceType.addField(fname, decl
320:                                    .getType(), flags);
321:                            decl.setSimple(false);
322:                        }
323:                    }
324:                }
325:
326:                for (LambdaExp child = firstChild; child != null; child = child.nextSibling) {
327:                    // When we recompile an existing method in an existing class,
328:                    // we keep the same Method objects.
329:                    if (child.primMethods != null)
330:                        continue;
331:
332:                    if (child != initMethod || !isMakingClassPair())
333:                        child.addMethodFor(type, null, null);
334:                    if (isMakingClassPair())
335:                        child.addMethodFor(instanceType, null, type);
336:                }
337:
338:                addAttributes(instanceType);
339:            }
340:
341:            /** Return implementation method matching name and param types.
342:             * Used when compiling a pair class and generating a concrete method
343:             * implementing an interface method, to find static implementation method
344:             * in this or super implementation class we need to call.
345:             * @param interfaceType search the implementation classes corresponding
346:             *   to this interface type and its super-interfaces.
347:             * @param mname method name to look for.
348:             * @param paramTypes method types to look for.
349:             * @param vec where to place found methods
350:             * If a method is found, don't search super-interfaces, as the found method
351:             * is more specific and overrides any that might in super-interfaces.
352:             */
353:            static void getImplMethods(ClassType interfaceType, String mname,
354:                    Type[] paramTypes, Vector vec) {
355:                ClassType implType;
356:                if (interfaceType instanceof  PairClassType)
357:                    implType = ((PairClassType) interfaceType).instanceType;
358:                else if (!interfaceType.isInterface())
359:                    return;
360:                else {
361:                    String implTypeName = interfaceType.getName() + "$class";
362:                    implType = ClassType.make(implTypeName);
363:                }
364:                Type[] itypes = new Type[paramTypes.length + 1];
365:                itypes[0] = interfaceType;
366:                System.arraycopy(paramTypes, 0, itypes, 1, paramTypes.length);
367:                Method implMethod = implType.getDeclaredMethod(mname, itypes);
368:                if (implMethod != null) {
369:                    int count = vec.size();
370:                    if (count == 0
371:                            || !vec.elementAt(count - 1).equals(implMethod))
372:                        vec.addElement(implMethod);
373:                } else {
374:                    ClassType[] super Interfaces = interfaceType.getInterfaces();
375:                    for (int i = 0; i < super Interfaces.length; i++)
376:                        getImplMethods(super Interfaces[i], mname, paramTypes,
377:                                vec);
378:                }
379:            }
380:
381:            public ClassType compile(Compilation comp) {
382:                ClassType saveClass = comp.curClass;
383:                Method saveMethod = comp.method;
384:                try {
385:                    ClassType new_class = getCompiledClassType(comp);
386:                    comp.curClass = new_class;
387:
388:                    String filename = getFile();
389:                    if (filename != null)
390:                        new_class.setSourceFile(filename);
391:
392:                    LambdaExp saveLambda = comp.curLambda;
393:                    comp.curLambda = this ;
394:
395:                    allocFrame(comp);
396:                    if (getNeedsStaticLink()) {
397:                        Variable parentFrame = saveLambda.heapFrame != null ? saveLambda.heapFrame
398:                                : saveLambda.closureEnv;
399:                        if (parentFrame != null)
400:                            closureEnvField = staticLinkField = instanceType
401:                                    .addField("this$0", parentFrame.getType());
402:                    }
403:                    comp.generateConstructor(instanceType, this );
404:                    CodeAttr code;
405:
406:                    for (LambdaExp child = firstChild; child != null;) {
407:                        Method save_method = comp.method;
408:                        LambdaExp save_lambda = comp.curLambda;
409:                        comp.method = child.getMainMethod();
410:                        //comp.curClass = comp.method.getDeclaringClass();
411:                        child.declareThis(comp.curClass);
412:                        comp.curClass = instanceType;
413:                        comp.curLambda = child;
414:                        comp.method.initCode();
415:                        child.allocChildClasses(comp);
416:                        child.allocParameters(comp);
417:                        child.enterFunction(comp);
418:                        child.compileBody(comp);
419:                        child.compileEnd(comp);
420:                        child.compileChildMethods(comp);
421:                        comp.method = save_method;
422:                        comp.curClass = new_class;
423:                        comp.curLambda = save_lambda;
424:                        child = child.nextSibling;
425:                    }
426:
427:                    Method[] methods = type.getMethods(
428:                            AbstractMethodFilter.instance, 2);
429:                    for (int i = 0; i < methods.length; i++) {
430:                        Method meth = methods[i];
431:                        String mname = meth.getName();
432:                        Type[] ptypes = meth.getParameterTypes();
433:                        Type rtype = meth.getReturnType();
434:
435:                        Method mimpl = instanceType.getMethod(mname, ptypes);
436:                        if (mimpl != null && !mimpl.isAbstract())
437:                            continue;
438:
439:                        char ch;
440:                        if (mname.length() > 3 && mname.charAt(2) == 't'
441:                                && mname.charAt(1) == 'e'
442:                                && ((ch = mname.charAt(0)) == 'g' || ch == 's')) {
443:                            Type ftype;
444:                            if (ch == 's' && rtype.isVoid()
445:                                    && ptypes.length == 1)
446:                                ftype = ptypes[0];
447:                            else if (ch == 'g' && ptypes.length == 0)
448:                                ftype = rtype;
449:                            else
450:                                continue;
451:                            String fname = Character.toLowerCase(mname
452:                                    .charAt(3))
453:                                    + mname.substring(4);
454:                            Field fld = instanceType.getField(fname);
455:                            if (fld == null)
456:                                fld = instanceType.addField(fname, ftype,
457:                                        Access.PUBLIC);
458:                            Method impl = instanceType.addMethod(mname,
459:                                    Access.PUBLIC, ptypes, rtype);
460:                            impl.init_param_slots();
461:                            code = impl.getCode();
462:                            code.emitPushThis();
463:                            if (ch == 'g') {
464:                                code.emitGetField(fld);
465:                            } else {
466:                                code.emitLoad(code.getArg(1));
467:                                code.emitPutField(fld);
468:                            }
469:                            code.emitReturn();
470:                        } else {
471:                            Vector vec = new Vector();
472:                            getImplMethods(type, mname, ptypes, vec);
473:                            if (vec.size() != 1) {
474:                                // FIXME - need better error message!
475:                                String msg = vec.size() == 0 ? "missing implementation for "
476:                                        : "ambiguous implementation for ";
477:                                comp.error('e', msg + meth);
478:                            } else {
479:                                Method impl = instanceType.addMethod(mname,
480:                                        Access.PUBLIC, ptypes, rtype);
481:                                impl.init_param_slots();
482:                                code = impl.getCode();
483:                                for (Variable var = code.getCurrentScope()
484:                                        .firstVar(); var != null; var = var
485:                                        .nextVar())
486:                                    code.emitLoad(var);
487:                                Method imethod = (Method) vec.elementAt(0);
488:                                code.emitInvokeStatic(imethod);
489:                                code.emitReturn();
490:                            }
491:                        }
492:                    }
493:
494:                    comp.curLambda = saveLambda;
495:
496:                    return new_class;
497:                } finally {
498:                    comp.curClass = saveClass;
499:                    comp.method = saveMethod;
500:                }
501:            }
502:
503:            /**
504:               Return code to create an instance of this class.
505:               The instance is initialized by calling the default constructor.
506:             */
507:            public final Expression instantiate() {
508:                return new QuoteExp(new PrimProcedure(getDefaultConstructor()));
509:            }
510:
511:            private Method getDefaultConstructor() {
512:                ClassType clas = getClassType();
513:                return Compilation.getConstructor(clas, this );
514:            }
515:
516:            void compileChildMethods(Compilation comp) {
517:                // We set comp.curClass, so that literals are emited in the right class.
518:                ClassType save_class = comp.curClass;
519:                comp.curClass = this .type;
520:
521:                super .compileChildMethods(comp);
522:                setFieldValues(comp);
523:
524:                comp.curClass = save_class;
525:            }
526:
527:            private void setFieldValues(Compilation comp) {
528:                for (Declaration decl = firstDecl(); decl != null; decl = decl
529:                        .nextDecl()) {
530:                    if (decl.field != null) {
531:                        decl.setFieldValue(comp);
532:                    }
533:                }
534:            }
535:
536:            protected Expression walk(ExpWalker walker) {
537:                return walker.walkClassExp(this );
538:            }
539:
540:            protected void walkChildren(ExpWalker walker) {
541:                LambdaExp save = walker.currentLambda;
542:                walker.currentLambda = this ;
543:                try {
544:                    for (LambdaExp child = firstChild; child != null
545:                            && walker.exitValue == null; child = child.nextSibling)
546:                        walker.walkLambdaExp(child);
547:
548:                    // Walk static fields. This is particularly important for
549:                    // those initialized to some value, since that value might
550:                    // include closures that need to be walked.
551:                    for (Declaration decl = firstDecl(); decl != null; decl = decl
552:                            .nextDecl())
553:                        if (decl.isStatic() && decl.value != null)
554:                            decl.value.walk(walker);
555:                } finally {
556:                    walker.currentLambda = save;
557:                }
558:            }
559:
560:            public void print(OutPort out) {
561:                out.startLogicalBlock("(" + getExpClassName() + "/", ")", 2);
562:                if (name != null) {
563:                    out.print(name);
564:                    out.print('/');
565:                }
566:                out.print(id);
567:                out.print("/ (");
568:                Special prevMode = null;
569:                int i = 0;
570:                int opt_i = 0;
571:                int key_args = keywords == null ? 0 : keywords.length;
572:                int opt_args = defaultArgs == null ? 0 : defaultArgs.length
573:                        - key_args;
574:                for (Declaration decl = firstDecl(); decl != null; decl = decl
575:                        .nextDecl()) {
576:                    if (i > 0)
577:                        out.print(' ');
578:                    out.print(decl);
579:                    i++;
580:                }
581:                out.print(") ");
582:                for (LambdaExp child = firstChild; child != null; child = child.nextSibling) {
583:                    out.writeSpaceLinear();
584:                    out.print(" method: ");
585:                    child.print(out);
586:                }
587:                out.writeSpaceLinear();
588:                if (body == null)
589:                    out.print("<null body>");
590:                else
591:                    body.print(out);
592:                out.endLogicalBlock(")");
593:            }
594:
595:            public Field compileSetField(Compilation comp) {
596:                return (new ClassInitializer(this , comp)).field;
597:            }
598:
599:            /** Mangle a "slot" name to a get- or set- method name. */
600:            public static String slotToMethodName(String prefix, String sname) {
601:                StringBuffer sbuf = new StringBuffer(sname.length() + 3);
602:                sbuf.append(prefix);
603:                sbuf.append(Character.toTitleCase(sname.charAt(0)));
604:                sbuf.append(sname.substring(1));
605:                return sbuf.toString();
606:            }
607:
608:            /****************************************************************
609:             * Assertions
610:             ****************************************************************/
611:
612:            private Field assertionEnabledField;
613:
614:            public Field getAssertionEnabledField() {
615:                if (assertionEnabledField == null) {
616:                    ClassType classe = (ClassType) getType();
617:
618:                    // Get the field if it already exists.
619:                    // This is the case for already compiled classes.
620:                    assertionEnabledField = classe
621:                            .getField("$assertionsEnabled");
622:                    if (assertionEnabledField != null)
623:                        return assertionEnabledField;
624:
625:                    assertionEnabledField = classe.addField(
626:                            "$assertionsEnabled", Type.boolean_type,
627:                            Access.STATIC | Access.FINAL);
628:
629:                    addClassInitializer(new Initializer() {
630:                        {
631:                            field = assertionEnabledField;
632:                        }
633:
634:                        public void emit(Compilation comp) {
635:                            CodeAttr code = comp.getCode();
636:
637:                            // Try to get the assertion status, if in JDK 1.4 or later.
638:                            code.emitTryStart(false, Type.boolean_type);
639:                            code.emitPushString(getName());
640:                            code.emitInvokeStatic(forName);
641:                            code.emitInvokeVirtual(desiredAssertionStatus);
642:                            code.emitTryEnd();
643:
644:                            // If the method does not exist, get global assertion status.
645:                            Variable catchVar = new Variable("e", noSuchMethod);
646:                            catchVar.allocateLocal(code);
647:                            code.emitCatchStart(catchVar);
648:                            code.emitPushString("assertions");
649:                            code.emitInvokeStatic(getProperty);
650:                            code.emitIfNull();
651:                            code.emitPushBoolean(false);
652:                            code.emitElse();
653:                            code.emitPushBoolean(true);
654:                            code.emitFi();
655:                            code.emitCatchEnd();
656:                            code.emitTryCatchEnd();
657:
658:                            code.emitPutStatic(field);
659:                        }
660:                    });
661:                }
662:
663:                return assertionEnabledField;
664:            }
665:
666:            static final ClassType javaClass = ClassType
667:                    .make("java.lang.Class"), noSuchMethod = ClassType
668:                    .make("java.lang.NoSuchMethodError");
669:
670:            static final Method forName = javaClass.getDeclaredMethod(
671:                    "forName", 1), desiredAssertionStatus = javaClass
672:                    .addMethod("desiredAssertionStatus", Access.PUBLIC,
673:                            new Type[] {}, Type.boolean_type),
674:                    getProperty = ClassType.make("java.lang.System")
675:                            .getDeclaredMethod("getProperty", 1);
676:
677:        }
678:
679:        class AbstractMethodFilter implements  gnu.bytecode.Filter {
680:            public static AbstractMethodFilter instance = new AbstractMethodFilter();
681:
682:            public boolean select(Object value) {
683:                gnu.bytecode.Method method = (gnu.bytecode.Method) value;
684:                return method.isAbstract();
685:            }
686:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.