KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > corext > dom > TypeRules


1 /*******************************************************************************
2  * Copyright (c) 2000, 2005 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  * Dmitry Stalnov (dstalnov@fusionone.com) - contributed fix for
11  * bug "inline method - doesn't handle implicit cast" (see
12  * https://bugs.eclipse.org/bugs/show_bug.cgi?id=24941).
13  *******************************************************************************/

14 package org.eclipse.jdt.internal.corext.dom;
15
16 import org.eclipse.jdt.core.dom.ITypeBinding;
17 import org.eclipse.jdt.core.dom.Modifier;
18 import org.eclipse.jdt.core.dom.PrimitiveType;
19 import org.eclipse.jdt.core.dom.PrimitiveType.Code;
20
21 /**
22  * Helper class to check if objects are assignable to each other.
23  */

24 public class TypeRules {
25
26     /**
27      * Tests if a two primitive types are assign compatible
28      * @param toAssignCode The binding of the type to assign
29      * @param definedTypeCode The type of the object that is assigned
30      * @return boolean Returns true if definedType = typeToAssign is true
31      */

32     public static boolean canAssignPrimitive(PrimitiveType.Code toAssignCode, PrimitiveType.Code definedTypeCode) {
33         // definedTypeCode = typeCodeToAssign;
34
if (toAssignCode == definedTypeCode) {
35             return true;
36         }
37         if (definedTypeCode == PrimitiveType.BOOLEAN || toAssignCode == PrimitiveType.BOOLEAN) {
38             return false;
39         }
40         if (definedTypeCode == PrimitiveType.CHAR && toAssignCode == PrimitiveType.BYTE) {
41             return false;
42         }
43         return getTypeOrder(definedTypeCode) > getTypeOrder(toAssignCode);
44     }
45         
46     /**
47      * Tests if two types are assign compatible. Void types are never compatible.
48      * @param typeToAssign The binding of the type to assign
49      * @param definedType The type of the object that is assigned
50      * @return boolean Returns true if definedType = typeToAssign is true
51      */

52     public static boolean canAssign(ITypeBinding typeToAssign, ITypeBinding definedType) {
53         //see bug 80715
54

55         // definedType = typeToAssign;
56

57         String JavaDoc voidName= PrimitiveType.VOID.toString();
58         if (voidName.equals(typeToAssign.getName()) || voidName.equals(definedType.getName())) {
59             return false;
60         }
61
62         if (typeToAssign.isNullType()) {
63             return !definedType.isPrimitive();
64         }
65         if (definedType.isArray()) {
66             if (!typeToAssign.isArray()) {
67                 return false; // can not assign a non-array type to an array
68
}
69             int definedDim= definedType.getDimensions();
70             int toAssignDim= typeToAssign.getDimensions();
71             if (definedDim == toAssignDim) {
72                 definedType= definedType.getElementType();
73                 typeToAssign= typeToAssign.getElementType();
74                 if (typeToAssign.isPrimitive() && typeToAssign != definedType) {
75                     return false; // can't assign arrays of different primitive types to each other
76
}
77                 // fall through
78
} else if (definedDim < toAssignDim) {
79                 return isArrayCompatible(definedType.getElementType());
80             } else {
81                 return false;
82             }
83         }
84
85         if (typeToAssign.isPrimitive()) {
86             if (!definedType.isPrimitive()) {
87                 return false;
88             }
89             PrimitiveType.Code toAssignCode= PrimitiveType.toCode(typeToAssign.getName());
90             PrimitiveType.Code definedTypeCode= PrimitiveType.toCode(definedType.getName());
91             return canAssignPrimitive(toAssignCode, definedTypeCode);
92         } else {
93             if (definedType.isPrimitive()) {
94                 return false;
95             }
96
97             if (typeToAssign.isArray()) {
98                 return isArrayCompatible(definedType);
99             }
100             if (isJavaLangObject(definedType)) { //$NON-NLS-1$
101
return true;
102             }
103             return Bindings.isSuperType(definedType, typeToAssign);
104         }
105     }
106
107     private static int getTypeOrder(Code type) {
108         if (type == PrimitiveType.BYTE)
109             return 2;
110         if (type == PrimitiveType.CHAR)
111             return 3;
112         if (type == PrimitiveType.SHORT)
113             return 3;
114         if (type == PrimitiveType.INT)
115             return 4;
116         if (type == PrimitiveType.LONG)
117             return 5;
118         if (type == PrimitiveType.FLOAT)
119             return 6;
120         if (type == PrimitiveType.DOUBLE)
121             return 7;
122         return 0;
123     }
124     
125     public static boolean isArrayCompatible(ITypeBinding definedType) {
126         if (definedType.isTopLevel()) {
127             if (definedType.isClass()) {
128                 return "Object".equals(definedType.getName()) && "java.lang".equals(definedType.getPackage().getName()); //$NON-NLS-1$//$NON-NLS-2$
129
} else {
130                 String JavaDoc qualifiedName= definedType.getQualifiedName();
131                 return "java.io.Serializable".equals(qualifiedName) || "java.lang.Cloneable".equals(qualifiedName); //$NON-NLS-1$ //$NON-NLS-2$
132
}
133         }
134         return false;
135     }
136     
137     public static boolean isJavaLangObject(ITypeBinding definedType) {
138         return definedType.isTopLevel() && definedType.isClass() && "Object".equals(definedType.getName()) && "java.lang".equals(definedType.getPackage().getName()); //$NON-NLS-1$//$NON-NLS-2$
139
}
140
141     /**
142      * Tests if a two types are cast compatible
143      * @param castType The binding of the type to cast to
144      * @param bindingToCast The binding ef the expression to cast.
145      * @return boolean Returns true if (castType) bindingToCast is a valid cast expression (can be unnecessary, but not invalid).
146      */

147     public static boolean canCast(ITypeBinding castType, ITypeBinding bindingToCast) {
148         //see bug 80715
149

150         String JavaDoc voidName= PrimitiveType.VOID.toString();
151         
152         if (castType.isAnonymous() || castType.isNullType() || voidName.equals(castType.getName())) {
153             throw new IllegalArgumentException JavaDoc();
154         }
155         
156         if (castType == bindingToCast) {
157             return true;
158         }
159         
160         if (voidName.equals(bindingToCast.getName())) {
161             return false;
162         }
163         
164         if (bindingToCast.isArray()) {
165             if (!castType.isArray()) {
166                 return isArrayCompatible(castType); // can not cast an arraytype to a non array type (except to Object, Serializable...)
167
}
168
169             int toCastDim= bindingToCast.getDimensions();
170             int castTypeDim= castType.getDimensions();
171             if (toCastDim == castTypeDim) {
172                 bindingToCast= bindingToCast.getElementType();
173                 castType= castType.getElementType();
174                 if (castType.isPrimitive() && castType != bindingToCast) {
175                     return false; // can't assign arrays of different primitive types to each other
176
}
177                 // fall through
178
} else if (toCastDim < castTypeDim) {
179                 return isArrayCompatible(bindingToCast.getElementType());
180             } else {
181                 return isArrayCompatible(castType.getElementType());
182             }
183         }
184         if (castType.isPrimitive()) {
185             if (!bindingToCast.isPrimitive()) {
186                 return false;
187             }
188             String JavaDoc boolName= PrimitiveType.BOOLEAN.toString();
189             return (!boolName.equals(castType.getName()) && !boolName.equals(bindingToCast.getName()));
190         } else {
191             if (bindingToCast.isPrimitive()) {
192                 return false;
193             }
194             if (castType.isArray()) {
195                 return isArrayCompatible(bindingToCast);
196             }
197             if (castType.isInterface()) {
198                 if ((bindingToCast.getModifiers() & Modifier.FINAL) != 0) {
199                     return Bindings.isSuperType(castType, bindingToCast);
200                 } else {
201                     return true;
202                 }
203             }
204             if (bindingToCast.isInterface()) {
205                 if ((castType.getModifiers() & Modifier.FINAL) != 0) {
206                     return Bindings.isSuperType(bindingToCast, castType);
207                 } else {
208                     return true;
209                 }
210             }
211             if (isJavaLangObject(castType)) {
212                 return true;
213             }
214             
215             return Bindings.isSuperType(bindingToCast, castType) || Bindings.isSuperType(castType, bindingToCast);
216         }
217     }
218     
219 }
220
Popular Tags