Source Code Cross Referenced for Javac.java in  » Byte-Code » Javassist » javassist » compiler » 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 » Byte Code » Javassist » javassist.compiler 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Javassist, a Java-bytecode translator toolkit.
003:         * Copyright (C) 1999-2006 Shigeru Chiba. All Rights Reserved.
004:         *
005:         * The contents of this file are subject to the Mozilla Public License Version
006:         * 1.1 (the "License"); you may not use this file except in compliance with
007:         * the License.  Alternatively, the contents of this file may be used under
008:         * the terms of the GNU Lesser General Public License Version 2.1 or later.
009:         *
010:         * Software distributed under the License is distributed on an "AS IS" basis,
011:         * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
012:         * for the specific language governing rights and limitations under the
013:         * License.
014:         */
015:
016:        package javassist.compiler;
017:
018:        import javassist.CtClass;
019:        import javassist.CtPrimitiveType;
020:        import javassist.CtMember;
021:        import javassist.CtField;
022:        import javassist.CtBehavior;
023:        import javassist.CtMethod;
024:        import javassist.CtConstructor;
025:        import javassist.CannotCompileException;
026:        import javassist.Modifier;
027:        import javassist.bytecode.Bytecode;
028:        import javassist.bytecode.CodeAttribute;
029:        import javassist.bytecode.LocalVariableAttribute;
030:        import javassist.bytecode.Opcode;
031:        import javassist.NotFoundException;
032:
033:        import javassist.compiler.ast.*;
034:
035:        public class Javac {
036:            JvstCodeGen gen;
037:            SymbolTable stable;
038:            private Bytecode bytecode;
039:
040:            public static final String param0Name = "$0";
041:            public static final String resultVarName = "$_";
042:            public static final String proceedName = "$proceed";
043:
044:            /**
045:             * Constructs a compiler.
046:             *
047:             * @param thisClass         the class that a compiled method/field
048:             *                          belongs to.
049:             */
050:            public Javac(CtClass this Class) {
051:                this (new Bytecode(this Class.getClassFile2().getConstPool(), 0,
052:                        0), this Class);
053:            }
054:
055:            /**
056:             * Constructs a compiler.
057:             * The produced bytecode is stored in the <code>Bytecode</code> object
058:             * specified by <code>b</code>.
059:             *
060:             * @param thisClass         the class that a compiled method/field
061:             *                          belongs to.
062:             */
063:            public Javac(Bytecode b, CtClass this Class) {
064:                gen = new JvstCodeGen(b, this Class, this Class.getClassPool());
065:                stable = new SymbolTable();
066:                bytecode = b;
067:            }
068:
069:            /**
070:             * Returns the produced bytecode.
071:             */
072:            public Bytecode getBytecode() {
073:                return bytecode;
074:            }
075:
076:            /**
077:             * Compiles a method, constructor, or field declaration
078:             * to a class.
079:             * A field declaration can declare only one field.
080:             *
081:             * <p>In a method or constructor body, $0, $1, ... and $_
082:             * are not available.
083:             *
084:             * @return          a <code>CtMethod</code>, <code>CtConstructor</code>,
085:             *                  or <code>CtField</code> object.
086:             * @see #recordProceed(String,String)
087:             */
088:            public CtMember compile(String src) throws CompileError {
089:                Parser p = new Parser(new Lex(src));
090:                ASTList mem = p.parseMember1(stable);
091:                try {
092:                    if (mem instanceof  FieldDecl)
093:                        return compileField((FieldDecl) mem);
094:                    else
095:                        return compileMethod(p, (MethodDecl) mem);
096:                } catch (CannotCompileException e) {
097:                    throw new CompileError(e.getMessage());
098:                }
099:            }
100:
101:            public static class CtFieldWithInit extends CtField {
102:                private ASTree init;
103:
104:                CtFieldWithInit(CtClass type, String name, CtClass declaring)
105:                        throws CannotCompileException {
106:                    super (type, name, declaring);
107:                    init = null;
108:                }
109:
110:                protected void setInit(ASTree i) {
111:                    init = i;
112:                }
113:
114:                protected ASTree getInitAST() {
115:                    return init;
116:                }
117:            }
118:
119:            private CtField compileField(FieldDecl fd) throws CompileError,
120:                    CannotCompileException {
121:                CtFieldWithInit f;
122:                Declarator d = fd.getDeclarator();
123:                f = new CtFieldWithInit(gen.resolver.lookupClass(d), d
124:                        .getVariable().get(), gen.getThisClass());
125:                f.setModifiers(MemberResolver.getModifiers(fd.getModifiers()));
126:                if (fd.getInit() != null)
127:                    f.setInit(fd.getInit());
128:
129:                return f;
130:            }
131:
132:            private CtMember compileMethod(Parser p, MethodDecl md)
133:                    throws CompileError {
134:                int mod = MemberResolver.getModifiers(md.getModifiers());
135:                CtClass[] plist = gen.makeParamList(md);
136:                CtClass[] tlist = gen.makeThrowsList(md);
137:                recordParams(plist, Modifier.isStatic(mod));
138:                md = p.parseMethod2(stable, md);
139:                try {
140:                    if (md.isConstructor()) {
141:                        CtConstructor cons = new CtConstructor(plist, gen
142:                                .getThisClass());
143:                        cons.setModifiers(mod);
144:                        md.accept(gen);
145:                        cons.getMethodInfo().setCodeAttribute(
146:                                bytecode.toCodeAttribute());
147:                        cons.setExceptionTypes(tlist);
148:                        return cons;
149:                    } else {
150:                        Declarator r = md.getReturn();
151:                        CtClass rtype = gen.resolver.lookupClass(r);
152:                        recordReturnType(rtype, false);
153:                        CtMethod method = new CtMethod(rtype, r.getVariable()
154:                                .get(), plist, gen.getThisClass());
155:                        method.setModifiers(mod);
156:                        gen.setThisMethod(method);
157:                        md.accept(gen);
158:                        if (md.getBody() != null)
159:                            method.getMethodInfo().setCodeAttribute(
160:                                    bytecode.toCodeAttribute());
161:                        else
162:                            method.setModifiers(mod | Modifier.ABSTRACT);
163:
164:                        method.setExceptionTypes(tlist);
165:                        return method;
166:                    }
167:                } catch (NotFoundException e) {
168:                    throw new CompileError(e.toString());
169:                }
170:            }
171:
172:            /**
173:             * Compiles a method (or constructor) body.
174:             *
175:             * @src	a single statement or a block.
176:             *          If null, this method produces a body returning zero or null.
177:             */
178:            public Bytecode compileBody(CtBehavior method, String src)
179:                    throws CompileError {
180:                try {
181:                    int mod = method.getModifiers();
182:                    recordParams(method.getParameterTypes(), Modifier
183:                            .isStatic(mod));
184:
185:                    CtClass rtype;
186:                    if (method instanceof  CtMethod) {
187:                        gen.setThisMethod((CtMethod) method);
188:                        rtype = ((CtMethod) method).getReturnType();
189:                    } else
190:                        rtype = CtClass.voidType;
191:
192:                    recordReturnType(rtype, false);
193:                    boolean isVoid = rtype == CtClass.voidType;
194:
195:                    if (src == null)
196:                        makeDefaultBody(bytecode, rtype);
197:                    else {
198:                        Parser p = new Parser(new Lex(src));
199:                        SymbolTable stb = new SymbolTable(stable);
200:                        Stmnt s = p.parseStatement(stb);
201:                        if (p.hasMore())
202:                            throw new CompileError(
203:                                    "the method/constructor body must be surrounded by {}");
204:
205:                        boolean callSuper = false;
206:                        if (method instanceof  CtConstructor)
207:                            callSuper = !((CtConstructor) method)
208:                                    .isClassInitializer();
209:
210:                        gen.atMethodBody(s, callSuper, isVoid);
211:                    }
212:
213:                    return bytecode;
214:                } catch (NotFoundException e) {
215:                    throw new CompileError(e.toString());
216:                }
217:            }
218:
219:            private static void makeDefaultBody(Bytecode b, CtClass type) {
220:                int op;
221:                int value;
222:                if (type instanceof  CtPrimitiveType) {
223:                    CtPrimitiveType pt = (CtPrimitiveType) type;
224:                    op = pt.getReturnOp();
225:                    if (op == Opcode.DRETURN)
226:                        value = Opcode.DCONST_0;
227:                    else if (op == Opcode.FRETURN)
228:                        value = Opcode.FCONST_0;
229:                    else if (op == Opcode.LRETURN)
230:                        value = Opcode.LCONST_0;
231:                    else if (op == Opcode.RETURN)
232:                        value = Opcode.NOP;
233:                    else
234:                        value = Opcode.ICONST_0;
235:                } else {
236:                    op = Opcode.ARETURN;
237:                    value = Opcode.ACONST_NULL;
238:                }
239:
240:                if (value != Opcode.NOP)
241:                    b.addOpcode(value);
242:
243:                b.addOpcode(op);
244:            }
245:
246:            /**
247:             * Records local variables available at the specified program counter.
248:             * If the LocalVariableAttribute is not available, this method does not
249:             * record any local variable.  It only returns false.
250:             *
251:             * @param pc    program counter (&gt;= 0)
252:             * @return false if the CodeAttribute does not include a
253:             *              LocalVariableAttribute.
254:             */
255:            public boolean recordLocalVariables(CodeAttribute ca, int pc)
256:                    throws CompileError {
257:                LocalVariableAttribute va = (LocalVariableAttribute) ca
258:                        .getAttribute(LocalVariableAttribute.tag);
259:                if (va == null)
260:                    return false;
261:
262:                int n = va.tableLength();
263:                for (int i = 0; i < n; ++i) {
264:                    int start = va.startPc(i);
265:                    int len = va.codeLength(i);
266:                    if (start <= pc && pc < start + len)
267:                        gen.recordVariable(va.descriptor(i),
268:                                va.variableName(i), va.index(i), stable);
269:                }
270:
271:                return true;
272:            }
273:
274:            /**
275:             * Records parameter names if the LocalVariableAttribute is available.
276:             * It returns false unless the LocalVariableAttribute is available.
277:             *
278:             * @param numOfLocalVars    the number of local variables used
279:             *                          for storing the parameters.
280:             * @return false if the CodeAttribute does not include a
281:             *              LocalVariableAttribute.
282:             */
283:            public boolean recordParamNames(CodeAttribute ca, int numOfLocalVars)
284:                    throws CompileError {
285:                LocalVariableAttribute va = (LocalVariableAttribute) ca
286:                        .getAttribute(LocalVariableAttribute.tag);
287:                if (va == null)
288:                    return false;
289:
290:                int n = va.tableLength();
291:                for (int i = 0; i < n; ++i) {
292:                    int index = va.index(i);
293:                    if (index < numOfLocalVars)
294:                        gen.recordVariable(va.descriptor(i),
295:                                va.variableName(i), index, stable);
296:                }
297:
298:                return true;
299:            }
300:
301:            /**
302:             * Makes variables $0 (this), $1, $2, ..., and $args represent method
303:             * parameters.  $args represents an array of all the parameters.
304:             * It also makes $$ available as a parameter list of method call.
305:             *
306:             * <p>This must be called before calling <code>compileStmnt()</code> and
307:             * <code>compileExpr()</code>.  The correct value of
308:             * <code>isStatic</code> must be recorded before compilation.
309:             * <code>maxLocals</code> is updated to include $0,...
310:             */
311:            public int recordParams(CtClass[] params, boolean isStatic)
312:                    throws CompileError {
313:                return gen.recordParams(params, isStatic, "$", "$args", "$$",
314:                        stable);
315:            }
316:
317:            /**
318:             * Makes variables $0, $1, $2, ..., and $args represent method
319:             * parameters.  $args represents an array of all the parameters.
320:             * It also makes $$ available as a parameter list of method call.
321:             * $0 can represent a local variable other than THIS (variable 0).
322:             * $class is also made available.
323:             *
324:             * <p>This must be called before calling <code>compileStmnt()</code> and
325:             * <code>compileExpr()</code>.  The correct value of
326:             * <code>isStatic</code> must be recorded before compilation.
327:             * <code>maxLocals</code> is updated to include $0,...
328:             *
329:             * @paaram use0     true if $0 is used.
330:             * @param varNo     the register number of $0 (use0 is true)
331:             *                          or $1 (otherwise).
332:             * @param target    the type of $0 (it can be null if use0 is false).
333:             *                  It is used as the name of the type represented
334:             *                  by $class.
335:             * @param isStatic  true if the method in which the compiled bytecode
336:             *                  is embedded is static.
337:             */
338:            public int recordParams(String target, CtClass[] params,
339:                    boolean use0, int varNo, boolean isStatic)
340:                    throws CompileError {
341:                return gen.recordParams(params, isStatic, "$", "$args", "$$",
342:                        use0, varNo, target, stable);
343:            }
344:
345:            /**
346:             * Sets <code>maxLocals</code> to <code>max</code>.
347:             * This method tells the compiler the local variables that have been
348:             * allocated for the rest of the code.  When the compiler needs
349:             * new local variables, the local variables at the index <code>max</code>,
350:             * <code>max + 1</code>, ... are assigned.
351:             *
352:             * <p>This method is indirectly called by <code>recordParams</code>.
353:             */
354:            public void setMaxLocals(int max) {
355:                gen.setMaxLocals(max);
356:            }
357:
358:            /**
359:             * Prepares to use cast $r, $w, $_, and $type.
360:             * $type is made to represent the specified return type.
361:             * It also enables to write a return statement with a return value
362:             * for void method.
363:             *
364:             * <p>If the return type is void, ($r) does nothing.
365:             * The type of $_ is java.lang.Object.
366:             *
367:             * @param type              the return type.
368:             * @param useResultVar      true if $_ is used.
369:             * @return          -1 or the variable index assigned to $_.
370:             * @see #recordType(CtClass)
371:             */
372:            public int recordReturnType(CtClass type, boolean useResultVar)
373:                    throws CompileError {
374:                gen.recordType(type);
375:                return gen.recordReturnType(type, "$r",
376:                        (useResultVar ? resultVarName : null), stable);
377:            }
378:
379:            /**
380:             * Prepares to use $type.  Note that recordReturnType() overwrites
381:             * the value of $type.
382:             *
383:             * @param t     the type represented by $type.
384:             */
385:            public void recordType(CtClass t) {
386:                gen.recordType(t);
387:            }
388:
389:            /**
390:             * Makes the given variable available.
391:             *
392:             * @param type      variable type
393:             * @param name      variable name
394:             */
395:            public int recordVariable(CtClass type, String name)
396:                    throws CompileError {
397:                return gen.recordVariable(type, name, stable);
398:            }
399:
400:            /**
401:             * Prepares to use $proceed().
402:             * If the return type of $proceed() is void, null is pushed on the
403:             * stack.
404:             *
405:             * @param target    an expression specifying the target object.
406:             *                          if null, "this" is the target.
407:             * @param method    the method name.
408:             */
409:            public void recordProceed(String target, String method)
410:                    throws CompileError {
411:                Parser p = new Parser(new Lex(target));
412:                final ASTree texpr = p.parseExpression(stable);
413:                final String m = method;
414:
415:                ProceedHandler h = new ProceedHandler() {
416:                    public void doit(JvstCodeGen gen, Bytecode b, ASTList args)
417:                            throws CompileError {
418:                        ASTree expr = new Member(m);
419:                        if (texpr != null)
420:                            expr = Expr.make('.', texpr, expr);
421:
422:                        expr = CallExpr.makeCall(expr, args);
423:                        gen.compileExpr(expr);
424:                        gen.addNullIfVoid();
425:                    }
426:
427:                    public void setReturnType(JvstTypeChecker check,
428:                            ASTList args) throws CompileError {
429:                        ASTree expr = new Member(m);
430:                        if (texpr != null)
431:                            expr = Expr.make('.', texpr, expr);
432:
433:                        expr = CallExpr.makeCall(expr, args);
434:                        expr.accept(check);
435:                        check.addNullIfVoid();
436:                    }
437:                };
438:
439:                gen.setProceedHandler(h, proceedName);
440:            }
441:
442:            /**
443:             * Prepares to use $proceed() representing a static method.
444:             * If the return type of $proceed() is void, null is pushed on the
445:             * stack.
446:             *
447:             * @param targetClass    the fully-qualified dot-separated name
448:             *				of the class declaring the method.
449:             * @param method         the method name.
450:             */
451:            public void recordStaticProceed(String targetClass, String method)
452:                    throws CompileError {
453:                final String c = targetClass;
454:                final String m = method;
455:
456:                ProceedHandler h = new ProceedHandler() {
457:                    public void doit(JvstCodeGen gen, Bytecode b, ASTList args)
458:                            throws CompileError {
459:                        Expr expr = Expr.make(TokenId.MEMBER, new Symbol(c),
460:                                new Member(m));
461:                        expr = CallExpr.makeCall(expr, args);
462:                        gen.compileExpr(expr);
463:                        gen.addNullIfVoid();
464:                    }
465:
466:                    public void setReturnType(JvstTypeChecker check,
467:                            ASTList args) throws CompileError {
468:                        Expr expr = Expr.make(TokenId.MEMBER, new Symbol(c),
469:                                new Member(m));
470:                        expr = CallExpr.makeCall(expr, args);
471:                        expr.accept(check);
472:                        check.addNullIfVoid();
473:                    }
474:                };
475:
476:                gen.setProceedHandler(h, proceedName);
477:            }
478:
479:            /**
480:             * Prepares to use $proceed() representing a private/super's method.
481:             * If the return type of $proceed() is void, null is pushed on the
482:             * stack.  This method is for methods invoked by INVOKESPECIAL.
483:             *
484:             * @param target    an expression specifying the target object.
485:             *                          if null, "this" is the target.
486:             * @param classname	    the class name declaring the method.
487:             * @param methodname    the method name.
488:             * @param descriptor    the method descriptor.
489:             */
490:            public void recordSpecialProceed(String target, String classname,
491:                    String methodname, String descriptor) throws CompileError {
492:                Parser p = new Parser(new Lex(target));
493:                final ASTree texpr = p.parseExpression(stable);
494:                final String cname = classname;
495:                final String method = methodname;
496:                final String desc = descriptor;
497:
498:                ProceedHandler h = new ProceedHandler() {
499:                    public void doit(JvstCodeGen gen, Bytecode b, ASTList args)
500:                            throws CompileError {
501:                        gen.compileInvokeSpecial(texpr, cname, method, desc,
502:                                args);
503:                    }
504:
505:                    public void setReturnType(JvstTypeChecker c, ASTList args)
506:                            throws CompileError {
507:                        c
508:                                .compileInvokeSpecial(texpr, cname, method,
509:                                        desc, args);
510:                    }
511:
512:                };
513:
514:                gen.setProceedHandler(h, proceedName);
515:            }
516:
517:            /**
518:             * Prepares to use $proceed().
519:             */
520:            public void recordProceed(ProceedHandler h) {
521:                gen.setProceedHandler(h, proceedName);
522:            }
523:
524:            /**
525:             * Compiles a statement (or a block).
526:             * <code>recordParams()</code> must be called before invoking
527:             * this method.
528:             *
529:             * <p>Local variables that are not declared
530:             * in the compiled source text might not be accessible within that
531:             * source text.  Fields and method parameters ($0, $1, ..) are available.
532:             */
533:            public void compileStmnt(String src) throws CompileError {
534:                Parser p = new Parser(new Lex(src));
535:                SymbolTable stb = new SymbolTable(stable);
536:                while (p.hasMore()) {
537:                    Stmnt s = p.parseStatement(stb);
538:                    if (s != null)
539:                        s.accept(gen);
540:                }
541:            }
542:
543:            /**
544:             * Compiles an exression.  <code>recordParams()</code> must be
545:             * called before invoking this method.
546:             *
547:             * <p>Local variables are not accessible
548:             * within the compiled source text.  Fields and method parameters
549:             * ($0, $1, ..) are available if <code>recordParams()</code>
550:             * have been invoked.
551:             */
552:            public void compileExpr(String src) throws CompileError {
553:                ASTree e = parseExpr(src, stable);
554:                compileExpr(e);
555:            }
556:
557:            /**
558:             * Parsers an expression.
559:             */
560:            public static ASTree parseExpr(String src, SymbolTable st)
561:                    throws CompileError {
562:                Parser p = new Parser(new Lex(src));
563:                return p.parseExpression(st);
564:            }
565:
566:            /**
567:             * Compiles an exression.  <code>recordParams()</code> must be
568:             * called before invoking this method.
569:             *
570:             * <p>Local variables are not accessible
571:             * within the compiled source text.  Fields and method parameters
572:             * ($0, $1, ..) are available if <code>recordParams()</code>
573:             * have been invoked.
574:             */
575:            public void compileExpr(ASTree e) throws CompileError {
576:                if (e != null)
577:                    gen.compileExpr(e);
578:            }
579:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.