Source Code Cross Referenced for Hierarchy2.java in  » Code-Analyzer » findbugs » edu » umd » cs » findbugs » ba » 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 » Code Analyzer » findbugs » edu.umd.cs.findbugs.ba 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Bytecode Analysis Framework
003:         * Copyright (C) 2003,2004 University of Maryland
004:         * 
005:         * This library is free software; you can redistribute it and/or
006:         * modify it under the terms of the GNU Lesser General Public
007:         * License as published by the Free Software Foundation; either
008:         * version 2.1 of the License, or (at your option) any later version.
009:         * 
010:         * This library is distributed in the hope that it will be useful,
011:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
012:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013:         * Lesser General Public License for more details.
014:         * 
015:         * You should have received a copy of the GNU Lesser General Public
016:         * License along with this library; if not, write to the Free Software
017:         * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
018:         */
019:
020:        package edu.umd.cs.findbugs.ba;
021:
022:        import static edu.umd.cs.findbugs.ba.Hierarchy.DEBUG_METHOD_LOOKUP;
023:        import static edu.umd.cs.findbugs.ba.Hierarchy.INSTANCE_METHOD;
024:        import static edu.umd.cs.findbugs.ba.Hierarchy.STATIC_METHOD;
025:
026:        import java.util.Collections;
027:        import java.util.HashSet;
028:        import java.util.Set;
029:
030:        import org.apache.bcel.Constants;
031:        import org.apache.bcel.generic.ArrayType;
032:        import org.apache.bcel.generic.ConstantPoolGen;
033:        import org.apache.bcel.generic.INVOKESTATIC;
034:        import org.apache.bcel.generic.InvokeInstruction;
035:        import org.apache.bcel.generic.ObjectType;
036:        import org.apache.bcel.generic.ReferenceType;
037:        import org.apache.bcel.generic.Type;
038:
039:        import edu.umd.cs.findbugs.annotations.CheckForNull;
040:        import edu.umd.cs.findbugs.annotations.NonNull;
041:        import edu.umd.cs.findbugs.ba.type.TypeFrame;
042:        import edu.umd.cs.findbugs.classfile.CheckedAnalysisException;
043:        import edu.umd.cs.findbugs.classfile.ClassDescriptor;
044:        import edu.umd.cs.findbugs.classfile.DescriptorFactory;
045:        import edu.umd.cs.findbugs.classfile.Global;
046:        import edu.umd.cs.findbugs.internalAnnotations.DottedClassName;
047:        import edu.umd.cs.findbugs.internalAnnotations.SlashedClassName;
048:        import edu.umd.cs.findbugs.util.ClassName;
049:        import edu.umd.cs.findbugs.util.Util;
050:
051:        /**
052:         * Facade for class hierarchy queries.
053:         * These typically access the class hierarchy using
054:         * the {@link org.apache.bcel.Repository} class.  Callers should generally
055:         * expect to handle ClassNotFoundException for when referenced
056:         * classes can't be found.
057:         *
058:         * @author William Pugh
059:         */
060:        public class Hierarchy2 {
061:
062:            public static final ClassDescriptor ObjectDescriptor = DescriptorFactory
063:                    .createClassDescriptor("java/lang/Object");
064:
065:            /**
066:             * Look up the method referenced by given InvokeInstruction.
067:             * This method does <em>not</em> look for implementations in
068:             * super or subclasses according to the virtual dispatch rules.
069:             *
070:             * @param inv     the InvokeInstruction
071:             * @param cpg     the ConstantPoolGen used by the class the InvokeInstruction belongs to
072:             * @param chooser JavaClassAndMethodChooser to use to pick the method from among the candidates
073:             * @return the JavaClassAndMethod, or null if no such method is defined in the class
074:             */
075:            public static XMethod findExactMethod(InvokeInstruction inv,
076:                    ConstantPoolGen cpg, JavaClassAndMethodChooser chooser)
077:                    throws ClassNotFoundException {
078:                String className = inv.getClassName(cpg);
079:                String methodName = inv.getName(cpg);
080:                String methodSig = inv.getSignature(cpg);
081:
082:                XMethod result = findMethod(DescriptorFactory
083:                        .createClassDescriptorFromDottedClassName(className),
084:                        methodName, methodSig, inv instanceof  INVOKESTATIC);
085:
086:                return this OrNothing(result, chooser);
087:            }
088:
089:            private static @CheckForNull
090:            XMethod this OrNothing(@CheckForNull
091:            XMethod m, JavaClassAndMethodChooser chooser) {
092:                if (m == null)
093:                    return null;
094:                if (chooser.choose(m))
095:                    return m;
096:                return null;
097:            }
098:
099:            public static @CheckForNull
100:            XMethod findInvocationLeastUpperBound(InvokeInstruction inv,
101:                    ConstantPoolGen cpg, JavaClassAndMethodChooser methodChooser)
102:                    throws ClassNotFoundException {
103:
104:                if (DEBUG_METHOD_LOOKUP) {
105:                    System.out.println("Find prototype method for "
106:                            + SignatureConverter.convertMethodSignature(inv,
107:                                    cpg));
108:                }
109:
110:                short opcode = inv.getOpcode();
111:
112:                if (opcode == Constants.INVOKESTATIC) {
113:                    if (methodChooser == INSTANCE_METHOD)
114:                        return null;
115:                } else {
116:                    if (methodChooser == STATIC_METHOD)
117:                        return null;
118:                }
119:
120:                // Find the method
121:                if (opcode == Constants.INVOKESPECIAL) {
122:                    // Non-virtual dispatch
123:                    return findExactMethod(inv, cpg, methodChooser);
124:                } else {
125:                    String className = inv.getClassName(cpg);
126:                    String methodName = inv.getName(cpg);
127:                    String methodSig = inv.getSignature(cpg);
128:                    if (DEBUG_METHOD_LOOKUP) {
129:                        System.out.println("[Class name is " + className + "]");
130:                        System.out.println("[Method name is " + methodName
131:                                + "]");
132:                        System.out.println("[Method signature is " + methodSig
133:                                + "]");
134:                    }
135:
136:                    if (className.startsWith("[")) {
137:                        // Java 1.5 allows array classes to appear as the class name
138:                        className = "java.lang.Object";
139:                    }
140:
141:                    try {
142:                        return this OrNothing(findInvocationLeastUpperBound(
143:                                getXClassFromDottedClassName(className),
144:                                methodName, methodSig,
145:                                opcode == Constants.INVOKESTATIC,
146:                                opcode == Constants.INVOKEINTERFACE),
147:                                methodChooser);
148:                    } catch (CheckedAnalysisException e) {
149:                        return null;
150:                    }
151:
152:                }
153:            }
154:
155:            public static @CheckForNull
156:            XMethod findInvocationLeastUpperBound(ClassDescriptor classDesc,
157:                    String methodName, String methodSig, boolean invokeStatic,
158:                    boolean invokeInterface) {
159:                try {
160:                    return findInvocationLeastUpperBound(getXClass(classDesc),
161:                            methodName, methodSig, invokeStatic,
162:                            invokeInterface);
163:                } catch (Exception e) {
164:                    return null;
165:                }
166:            }
167:
168:            public static @CheckForNull
169:            XMethod findInvocationLeastUpperBound(XClass jClass,
170:                    String methodName, String methodSig, boolean invokeStatic,
171:                    boolean invokeInterface) throws ClassNotFoundException {
172:                XMethod result = findMethod(jClass.getClassDescriptor(),
173:                        methodName, methodSig, invokeStatic);
174:                if (result != null)
175:                    return result;
176:                if (invokeInterface)
177:                    for (ClassDescriptor i : jClass
178:                            .getInterfaceDescriptorList()) {
179:                        result = findInvocationLeastUpperBound(i, methodName,
180:                                methodSig, invokeStatic, invokeInterface);
181:                        if (result != null)
182:                            return null;
183:                    }
184:                else {
185:                    ClassDescriptor sClass = jClass.getSuperclassDescriptor();
186:                    if (sClass != null)
187:                        return findInvocationLeastUpperBound(sClass,
188:                                methodName, methodSig, invokeStatic,
189:                                invokeInterface);
190:                }
191:                return null;
192:
193:            }
194:
195:            public static @CheckForNull
196:            XMethod findMethod(ClassDescriptor classDescriptor,
197:                    String methodName, String methodSig, boolean isStatic) {
198:                try {
199:                    return getXClass(classDescriptor).findMethod(methodName,
200:                            methodSig, isStatic);
201:                } catch (CheckedAnalysisException e) {
202:                    return null;
203:                }
204:            }
205:
206:            static XClass getXClass(@SlashedClassName
207:            String c) throws CheckedAnalysisException {
208:                return getXClass(DescriptorFactory.createClassDescriptor(c));
209:            }
210:
211:            static XClass getXClassFromDottedClassName(@DottedClassName
212:            String c) throws CheckedAnalysisException {
213:                return getXClass(DescriptorFactory
214:                        .createClassDescriptorFromDottedClassName(c));
215:            }
216:
217:            static XClass getXClass(ClassDescriptor c)
218:                    throws CheckedAnalysisException {
219:                return Global.getAnalysisCache().getClassAnalysis(XClass.class,
220:                        c);
221:            }
222:
223:            /**
224:             * Resolve possible method call targets.
225:             * This works for both static and instance method calls.
226:             * 
227:             * @param invokeInstruction the InvokeInstruction
228:             * @param typeFrame         the TypeFrame containing the types of stack values
229:             * @param cpg               the ConstantPoolGen
230:             * @return Set of methods which might be called
231:             * @throws DataflowAnalysisException 
232:             * @throws ClassNotFoundException 
233:             */
234:            public static @NonNull
235:            Set<XMethod> resolveMethodCallTargets(
236:                    InvokeInstruction invokeInstruction, TypeFrame typeFrame,
237:                    ConstantPoolGen cpg) throws DataflowAnalysisException,
238:                    ClassNotFoundException {
239:
240:                short opcode = invokeInstruction.getOpcode();
241:
242:                if (opcode == Constants.INVOKESTATIC) {
243:                    return Util
244:                            .emptyOrNonnullSingleton(findInvocationLeastUpperBound(
245:                                    invokeInstruction, cpg, STATIC_METHOD));
246:                }
247:
248:                if (!typeFrame.isValid()) {
249:                    return Collections.emptySet();
250:                }
251:
252:                Type receiverType;
253:                boolean receiverTypeIsExact;
254:
255:                if (opcode == Constants.INVOKESPECIAL) {
256:                    // invokespecial instructions are dispatched to EXACTLY
257:                    // the class specified by the instruction
258:                    receiverType = ObjectTypeFactory
259:                            .getInstance(invokeInstruction.getClassName(cpg));
260:                    receiverTypeIsExact = false; // Doesn't actually matter
261:                } else {
262:                    // For invokevirtual and invokeinterface instructions, we have
263:                    // virtual dispatch.  By taking the receiver type (which may be a
264:                    // subtype of the class specified by the instruction),
265:                    // we may get a more precise set of call targets.
266:                    int instanceStackLocation = typeFrame
267:                            .getInstanceStackLocation(invokeInstruction, cpg);
268:                    receiverType = typeFrame
269:                            .getStackValue(instanceStackLocation);
270:                    if (!(receiverType instanceof  ReferenceType)) {
271:                        return Collections.emptySet();
272:                    }
273:                    receiverTypeIsExact = typeFrame
274:                            .isExact(instanceStackLocation);
275:                }
276:                if (DEBUG_METHOD_LOOKUP) {
277:                    System.out.println("[receiver type is " + receiverType
278:                            + ", "
279:                            + (receiverTypeIsExact ? "exact]" : " not exact]"));
280:                }
281:
282:                return resolveMethodCallTargets((ReferenceType) receiverType,
283:                        invokeInstruction, cpg, receiverTypeIsExact);
284:            }
285:
286:            /**
287:             * Resolve possible instance method call targets.
288:             * Assumes that invokevirtual and invokeinterface methods may
289:             * call any subtype of the receiver class.
290:             * 
291:             * @param receiverType      type of the receiver object
292:             * @param invokeInstruction the InvokeInstruction
293:             * @param cpg               the ConstantPoolGen
294:             * @return Set of methods which might be called
295:             * @throws ClassNotFoundException
296:             */
297:            public static Set<XMethod> resolveMethodCallTargets(
298:                    ReferenceType receiverType,
299:                    InvokeInstruction invokeInstruction, ConstantPoolGen cpg)
300:                    throws ClassNotFoundException {
301:                return resolveMethodCallTargets(receiverType,
302:                        invokeInstruction, cpg, false);
303:            }
304:
305:            /**
306:             * Resolve possible instance method call targets.
307:             * 
308:             * @param receiverType        type of the receiver object
309:             * @param invokeInstruction   the InvokeInstruction
310:             * @param cpg                 the ConstantPoolGen
311:             * @param receiverTypeIsExact if true, the receiver type is known exactly,
312:             *                            which should allow a precise result
313:             * @return Set of methods which might be called
314:             * @throws ClassNotFoundException
315:             */
316:            public static Set<XMethod> resolveMethodCallTargets(
317:                    ReferenceType receiverType,
318:                    InvokeInstruction invokeInstruction, ConstantPoolGen cpg,
319:                    boolean receiverTypeIsExact) throws ClassNotFoundException {
320:                HashSet<XMethod> result = new HashSet<XMethod>();
321:
322:                if (invokeInstruction.getOpcode() == Constants.INVOKESTATIC)
323:                    throw new IllegalArgumentException();
324:
325:                String methodName = invokeInstruction.getName(cpg);
326:                String methodSig = invokeInstruction.getSignature(cpg);
327:
328:                // Array method calls aren't virtual.
329:                // They should just resolve to Object methods.
330:                if (receiverType instanceof  ArrayType)
331:                    try {
332:                        return Util.emptyOrNonnullSingleton(getXClass(
333:                                ObjectDescriptor).findMethod(methodName,
334:                                methodSig, false));
335:                    } catch (CheckedAnalysisException e) {
336:                        return Collections.emptySet();
337:                    }
338:
339:                AnalysisContext analysisContext = AnalysisContext
340:                        .currentAnalysisContext();
341:
342:                // Get the receiver class.
343:                String receiverClassName = ((ObjectType) receiverType)
344:                        .getClassName();
345:                ClassDescriptor receiverDesc = DescriptorFactory
346:                        .createClassDescriptorFromDottedClassName(receiverClassName);
347:                XClass xClass;
348:                try {
349:                    xClass = getXClass(receiverDesc);
350:                } catch (CheckedAnalysisException e) {
351:                    return Collections.emptySet();
352:                }
353:                // Figure out the upper bound for the method.
354:                // This is what will be called if this is not a virtual call site.
355:                XMethod upperBound = findMethod(receiverDesc, methodName,
356:                        methodSig, false);
357:                if (upperBound == null) {
358:                    upperBound = findInvocationLeastUpperBound(xClass,
359:                            methodName, methodSig, false, false);
360:                }
361:                if (upperBound != null) {
362:                    if (DEBUG_METHOD_LOOKUP) {
363:                        System.out.println("Adding upper bound: " + upperBound);
364:                    }
365:                    result.add(upperBound);
366:                }
367:
368:                // Is this a virtual call site?
369:                boolean virtualCall = (invokeInstruction.getOpcode() == Constants.INVOKEVIRTUAL || invokeInstruction
370:                        .getOpcode() == Constants.INVOKEINTERFACE)
371:                        && (upperBound == null || !upperBound.isFinal())
372:                        && !receiverTypeIsExact;
373:
374:                if (virtualCall) {
375:                    if (!receiverClassName.equals("java.lang.Object")) {
376:
377:                        // This is a true virtual call: assume that any concrete
378:                        // subtype method may be called.
379:                        Set<ClassDescriptor> subTypeSet = analysisContext
380:                                .getSubtypes2().getSubtypes(receiverDesc);
381:                        for (ClassDescriptor subtype : subTypeSet) {
382:                            XMethod concreteSubtypeMethod = findMethod(subtype,
383:                                    methodName, methodSig, false);
384:                            if (concreteSubtypeMethod != null
385:                                    && (concreteSubtypeMethod.getAccessFlags() & Constants.ACC_ABSTRACT) == 0) {
386:                                result.add(concreteSubtypeMethod);
387:                            }
388:                        }
389:                        if (false && subTypeSet.size() > 500)
390:                            new RuntimeException(receiverClassName + " has "
391:                                    + subTypeSet.size() + " subclasses, "
392:                                    + result.size() + " of which implement "
393:                                    + methodName + methodSig + " "
394:                                    + invokeInstruction)
395:                                    .printStackTrace(System.out);
396:
397:                    }
398:                }
399:                return result;
400:            }
401:
402:            /**
403:             * Find the declared exceptions for the method called
404:             * by given instruction.
405:             *
406:             * @param inv the InvokeInstruction
407:             * @param cpg the ConstantPoolGen used by the class the InvokeInstruction belongs to
408:             * @return array of ObjectTypes of thrown exceptions, or null
409:             *         if we can't find the method implementation
410:             */
411:            public static @CheckForNull
412:            ObjectType[] findDeclaredExceptions(InvokeInstruction inv,
413:                    ConstantPoolGen cpg) throws ClassNotFoundException {
414:                XMethod method = findInvocationLeastUpperBound(inv, cpg,
415:                        inv instanceof  INVOKESTATIC ? Hierarchy.STATIC_METHOD
416:                                : Hierarchy.INSTANCE_METHOD);
417:
418:                if (method == null)
419:                    return null;
420:                String[] exceptions = method.getThrownExceptions();
421:
422:                if (exceptions == null)
423:                    return new ObjectType[0];
424:
425:                ObjectType[] result = new ObjectType[exceptions.length];
426:                for (int i = 0; i < exceptions.length; ++i) {
427:                    result[i] = ObjectTypeFactory.getInstance(ClassName
428:                            .toDottedClassName(exceptions[i]));
429:                }
430:                return result;
431:            }
432:
433:        }
434:
435:        // vim:ts=4
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.