KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > oracle > toplink > libraries > asm > tree > analysis > SimpleVerifier


1 /***
2  * ASM: a very small and fast Java bytecode manipulation framework
3  * Copyright (c) 2000,2002,2003 INRIA, France Telecom
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  * 3. Neither the name of the copyright holders nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28  * THE POSSIBILITY OF SUCH DAMAGE.
29  */

30
31 package oracle.toplink.libraries.asm.tree.analysis;
32
33 import oracle.toplink.libraries.asm.Type;
34
35 /**
36  * An extended {@link BasicVerifier} that performs more precise verifications.
37  * This verifier computes exact class types, instead of using a single
38  * "object reference" type (as done in the {@link BasicVerifier}).
39  *
40  * @author Eric Bruneton
41  * @author Bing Ran
42  */

43
44 public class SimpleVerifier extends BasicVerifier {
45
46   public Value newValue (final Type type) {
47     Value v = super.newValue(type);
48     if (v == BasicValue.REFERENCE_VALUE) {
49       if (type.getSort() == Type.ARRAY) {
50         v = newValue(type.getElementType());
51         String JavaDoc desc = ((BasicValue)v).getType().getDescriptor();
52         for (int i = 0; i < type.getDimensions(); ++i) {
53           desc = "[" + desc;
54         }
55         v = new BasicValue(Type.getType(desc));
56       } else {
57         v = new BasicValue(type);
58       }
59     }
60     return v;
61   }
62   
63   protected boolean isArrayValue (final Value value) {
64     Type t = ((BasicValue)value).getType();
65     if (t != null) {
66       return t.getDescriptor().equals("Lnull;") || t.getSort() == Type.ARRAY;
67     }
68     return false;
69   }
70       
71   protected Value getElementValue (final Value objectArrayValue)
72     throws AnalyzerException
73   {
74     Type arrayType = ((BasicValue)objectArrayValue).getType();
75     if (arrayType != null) {
76       if (arrayType.getSort() == Type.ARRAY) {
77         return newValue(Type.getType(arrayType.getDescriptor().substring(1)));
78       } else if (arrayType.getDescriptor().equals("Lnull;")) {
79         return objectArrayValue;
80       }
81     }
82     throw new AnalyzerException("Not an array type");
83   }
84     
85   protected boolean isSubTypeOf (final Value value, final Value expected) {
86     Type expectedType = ((BasicValue)expected).getType();
87     Type type = ((BasicValue)value).getType();
88     if (expectedType == null) {
89       return type == null;
90     } else {
91       switch (expectedType.getSort()) {
92         case Type.INT:
93         case Type.FLOAT:
94         case Type.LONG:
95         case Type.DOUBLE:
96           return type == expectedType;
97         case Type.ARRAY:
98         case Type.OBJECT:
99           if (expectedType.getDescriptor().equals("Lnull;")) {
100             return type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY;
101           }
102           Class JavaDoc expectedClass = getClass(expectedType);
103           if (type.getDescriptor().equals("Lnull;")) {
104             return !expectedClass.isPrimitive();
105           } else if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) {
106             Class JavaDoc actualClass = getClass(type);
107             return expectedClass.isAssignableFrom(actualClass);
108           } else {
109             return false;
110           }
111         default:
112           throw new RuntimeException JavaDoc("Internal error");
113       }
114     }
115   }
116
117   public Value merge (final Value v, final Value w) {
118     if (!v.equals(w)) {
119       Type t = ((BasicValue)v).getType();
120       Type u = ((BasicValue)w).getType();
121       if (t != null && (t.getSort() == Type.OBJECT || t.getSort() == Type.ARRAY)) {
122         if (u != null && (u.getSort() == Type.OBJECT || u.getSort() == Type.ARRAY)) {
123           if (t.getDescriptor().equals("Lnull;")) {
124             return w;
125           }
126           if (u.getDescriptor().equals("Lnull;")) {
127             return v;
128           }
129           Class JavaDoc c = getClass(t);
130           Class JavaDoc d = getClass(u);
131           if (c.isAssignableFrom(d)) {
132             return v;
133           }
134           if (d.isAssignableFrom(c)) {
135             return w;
136           }
137           // TODO case of array classes of the same dimension
138
// TODO should we look also for a common super interface?
139
// problem: there may be several possible common super interfaces
140
do {
141             if (c == null || c.isInterface()) {
142               return BasicValue.REFERENCE_VALUE;
143             } else {
144               c = c.getSuperclass();
145             }
146             if (c.isAssignableFrom(d)) {
147               return newValue(Type.getType(c));
148             }
149           } while (true);
150         }
151       }
152       return BasicValue.UNINITIALIZED_VALUE;
153     }
154     return v;
155   }
156   
157   protected Class JavaDoc getClass (final Type t) {
158     try {
159       if (t.getSort() == Type.ARRAY) {
160         return Class.forName(t.getDescriptor().replace('/', '.'));
161       } else {
162         return Class.forName(t.getClassName());
163       }
164     } catch (ClassNotFoundException JavaDoc e) {
165       throw new RuntimeException JavaDoc(e.toString());
166     }
167   }
168 }
169
Popular Tags