|
|||||||||||||||||||
| Source file | Conditionals | Statements | Methods | TOTAL | |||||||||||||||
| TigerUtilities.java | 88.2% | 80% | 64.3% | 80.6% |
|
||||||||||||||
| 1 | /*BEGIN_COPYRIGHT_BLOCK | |
| 2 | * | |
| 3 | * Copyright (c) 2001-2010, JavaPLT group at Rice University (drjava@rice.edu) | |
| 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 are met: | |
| 8 | * * Redistributions of source code must retain the above copyright | |
| 9 | * notice, this list of conditions and the following disclaimer. | |
| 10 | * * Redistributions in binary form must reproduce the above copyright | |
| 11 | * notice, this list of conditions and the following disclaimer in the | |
| 12 | * documentation and/or other materials provided with the distribution. | |
| 13 | * * Neither the names of DrJava, the JavaPLT group, Rice University, nor the | |
| 14 | * names of its contributors may be used to endorse or promote products | |
| 15 | * derived from this software without specific prior written permission. | |
| 16 | * | |
| 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
| 18 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
| 19 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
| 20 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | |
| 21 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
| 22 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
| 23 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |
| 24 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |
| 25 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |
| 26 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
| 27 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 28 | * | |
| 29 | * This software is Open Source Initiative approved Open Source Software. | |
| 30 | * Open Source Initative Approved is a trademark of the Open Source Initiative. | |
| 31 | * | |
| 32 | * This file is part of DrJava. Download the current version of this project | |
| 33 | * from http://www.drjava.org/ or http://sourceforge.net/projects/drjava/ | |
| 34 | * | |
| 35 | * END_COPYRIGHT_BLOCK*/ | |
| 36 | ||
| 37 | ||
| 38 | ||
| 39 | package koala.dynamicjava.util; | |
| 40 | ||
| 41 | ||
| 42 | import java.lang.reflect.*; | |
| 43 | ||
| 44 | import koala.dynamicjava.interpreter.error.*; | |
| 45 | ||
| 46 | /** | |
| 47 | * Common utilities of DynamicJava for implementing features of 1.5. | |
| 48 | */ | |
| 49 | public class TigerUtilities { | |
| 50 | ||
| 51 | // The following constants are pulled from | |
| 52 | // java.lang.reflect.Modifier. This way, | |
| 53 | // the utility can run under 1.4 | |
| 54 | ||
| 55 | public static final int BRIDGE = 0x00000040; | |
| 56 | public static final int VARARGS = 0x00000080; | |
| 57 | public static final int SYNTHETIC = 0x00001000; | |
| 58 | public static final int ANNOTATION = 0x00002000; | |
| 59 | public static final int ENUM = 0x00004000; | |
| 60 | ||
| 61 | /** | |
| 62 | * The version of the java runtime environment that is in use. | |
| 63 | */ | |
| 64 | public static final float VERSION = Float.parseFloat(System.getProperty("java.specification.version")); | |
| 65 | ||
| 66 | /** | |
| 67 | * Field that is set to determine whether or not features of 1.5 are enabled. | |
| 68 | * Disabling this field and then attempting to use a feature of 1.5 will cause a | |
| 69 | * WrongVersionException to be thrown | |
| 70 | */ | |
| 71 | private static boolean _tigerEnabled; | |
| 72 | ||
| 73 | static { | |
| 74 | 1 | resetVersion(); |
| 75 | } | |
| 76 | ||
| 77 | ||
| 78 | /** | |
| 79 | * Resets _tigerEnabled based upon the version of the runtime environment that is being used. | |
| 80 | */ | |
| 81 | 9 | public static void resetVersion() { |
| 82 | 9 | _tigerEnabled = (VERSION > 1.49); // We don't use >= since we're dealing with a float |
| 83 | } | |
| 84 | ||
| 85 | /** | |
| 86 | * Accessor method for _tigerEnabled. Returns true if the features in 1.5 are enabled currently. | |
| 87 | * @return boolean - true if 1.5 features are enabled | |
| 88 | */ | |
| 89 | 1 | public static boolean isTigerEnabled() { return _tigerEnabled; } |
| 90 | ||
| 91 | /** | |
| 92 | * Allows the features in 1.5 to be enabled or disabled. Used only in test cases. | |
| 93 | * @param enabled - a boolean that specifies whether or not Tiger features are to be enabled | |
| 94 | */ | |
| 95 | 9 | public static void setTigerEnabled(boolean enabled) { |
| 96 | 9 | _tigerEnabled = enabled; |
| 97 | } | |
| 98 | ||
| 99 | /** | |
| 100 | * To be called before a feature of 1.5 is used. Asserts that Tiger features are enabled. | |
| 101 | * @param msg The error message if 1.5 is not enabled | |
| 102 | */ | |
| 103 | 0 | public static void assertTigerEnabled(String msg) { |
| 104 | 0 | if(!_tigerEnabled) |
| 105 | 0 | throw new WrongVersionException(msg); |
| 106 | } | |
| 107 | ||
| 108 | /** | |
| 109 | * @return @{code true} iff m has the vararg modifier set. | |
| 110 | */ | |
| 111 | 4 | public static boolean isVarArgs(Method m) { |
| 112 | 4 | return _tigerEnabled && ((m.getModifiers() & VARARGS) != 0); |
| 113 | } | |
| 114 | ||
| 115 | /** | |
| 116 | * @return @{code true} iff c has the vararg modifier set. | |
| 117 | */ | |
| 118 | 0 | public static boolean isVarArgs(Constructor<?> c) { |
| 119 | 0 | return _tigerEnabled && ((c.getModifiers() & VARARGS) != 0); |
| 120 | } | |
| 121 | ||
| 122 | /** | |
| 123 | * @return @{code true} iff m has the bridge modifier set. | |
| 124 | */ | |
| 125 | 0 | public static boolean isBridge(Method m) { |
| 126 | 0 | return _tigerEnabled && ((m.getModifiers() & BRIDGE) != 0); |
| 127 | } | |
| 128 | ||
| 129 | /** | |
| 130 | * @return @{code true} iff c has the enum modifier set. | |
| 131 | */ | |
| 132 | 0 | public static boolean isEnum(Class<?> c) { |
| 133 | // Since the DynamicJava implementation of EnumDeclaration relies on the presence of constructors, | |
| 134 | // and the restrictions of the JVM won't allow constructors in classes flagged as ENUM, | |
| 135 | // we can't use the ENUM modifier flag here. | |
| 136 | ||
| 137 | // Note: we use "Class.forName" instead of "Enum.class" to avoid Retroweaver conversion of Enum.class | |
| 138 | // to its own Enum implementation. | |
| 139 | 0 | try { |
| 140 | 0 | return _tigerEnabled && (c.getSuperclass() != null) && |
| 141 | (c.getSuperclass().equals(Class.forName("java.lang.Enum"))); | |
| 142 | } | |
| 143 | 0 | catch (ClassNotFoundException e) { return false; } |
| 144 | } | |
| 145 | ||
| 146 | /** | |
| 147 | * @return @{code true} iff f has the enum modifier set. | |
| 148 | */ | |
| 149 | 0 | public static boolean isEnumConstant(Field f) { |
| 150 | 0 | return _tigerEnabled && ((f.getModifiers() & ENUM) != 0); |
| 151 | } | |
| 152 | ||
| 153 | /** | |
| 154 | * Returns the reference type that corresponds to the given primitive type. | |
| 155 | * If the type given is not primitive, it returns the given type. | |
| 156 | * @param primType the primitive type | |
| 157 | * @return the corresponding reference type | |
| 158 | */ | |
| 159 | 8 | public static Class<?> correspondingBoxingType(Class<?> primType) { |
| 160 | 1 | if (primType == boolean.class) { return Boolean.class; } |
| 161 | 1 | else if (primType == byte.class) { return Byte.class; } |
| 162 | 1 | else if (primType == char.class) { return Character.class; } |
| 163 | 1 | else if (primType == short.class) { return Short.class; } |
| 164 | 1 | else if (primType == int.class) { return Integer.class; } |
| 165 | 1 | else if (primType == long.class) { return Long.class; } |
| 166 | 1 | else if (primType == float.class) { return Float.class; } |
| 167 | 1 | else if (primType == double.class) { return Double.class; } |
| 168 | else { | |
| 169 | 0 | return primType; // It's already a reference type |
| 170 | } | |
| 171 | } | |
| 172 | ||
| 173 | /** | |
| 174 | * Returns the primitive type that corresponds to the given reference type. | |
| 175 | * If the given type is not a boxing type, it returns the given type. | |
| 176 | * @param refType the reference type | |
| 177 | * @return the corresponding primitive type | |
| 178 | */ | |
| 179 | 8 | public static Class<?> correspondingPrimType(Class<?> refType) { |
| 180 | 1 | if (refType == Boolean.class) { return boolean.class; } |
| 181 | 1 | else if (refType == Byte.class) { return byte.class; } |
| 182 | 1 | else if (refType == Character.class) { return char.class; } |
| 183 | 1 | else if (refType == Short.class) { return short.class; } |
| 184 | 1 | else if (refType == Integer.class) { return int.class; } |
| 185 | 1 | else if (refType == Long.class) { return long.class; } |
| 186 | 1 | else if (refType == Float.class) { return float.class; } |
| 187 | 1 | else if (refType == Double.class) { return double.class; } |
| 188 | else { | |
| 189 | 0 | return refType; // It's already a primitive type |
| 190 | } | |
| 191 | } | |
| 192 | ||
| 193 | /** | |
| 194 | * Returns if the given class is a reference type | |
| 195 | * @param c the class that may be a reference type | |
| 196 | * @return boolean that is true if the input class is a boxing type | |
| 197 | */ | |
| 198 | 9 | public static boolean isBoxingType(Class<?> c) { |
| 199 | 9 | return (c == Integer.class || c == Long.class || |
| 200 | c == Boolean.class || c == Double.class || | |
| 201 | c == Character.class || c == Short.class || | |
| 202 | c == Byte.class || c == Float.class ); | |
| 203 | } | |
| 204 | ||
| 205 | /** | |
| 206 | * Returns true iff the given class is an integral type | |
| 207 | * This includes both primitive and boxing integral types.<br><br> | |
| 208 | * Allowed primitives: byte, char, short, int, long | |
| 209 | * Allowed Refrence: Byte, Character, Short, Integer, Long | |
| 210 | * @param c The class to check | |
| 211 | * @return true iff the given class is an integral type | |
| 212 | */ | |
| 213 | 17 | public static boolean isIntegralType(Class<?> c) { |
| 214 | 17 | return (c == int.class || c == Integer.class || |
| 215 | c == long.class || c == Long.class || | |
| 216 | c == byte.class || c == Byte.class || | |
| 217 | c == char.class || c == Character.class || | |
| 218 | c == short.class || c == Short.class); | |
| 219 | } | |
| 220 | ||
| 221 | /** | |
| 222 | * Returns true iff the given primitive class can be boxed | |
| 223 | * to the given reference class. | |
| 224 | * @param prim - the primitive class being boxed | |
| 225 | * @param ref - the reference class being boxed to | |
| 226 | * @return true iff the given primitive class can be boxed to the given reference class | |
| 227 | */ | |
| 228 | 33 | public static boolean boxesTo(Class<?> prim, Class<?> ref) { |
| 229 | 33 | return |
| 230 | ((prim == int.class && ref == Integer.class) || | |
| 231 | (prim == long.class && ref == Long.class) || | |
| 232 | (prim == byte.class && ref == Byte.class) || | |
| 233 | (prim == char.class && ref == Character.class) || | |
| 234 | (prim == short.class && ref == Short.class) || | |
| 235 | (prim == boolean.class && ref == Boolean.class) || | |
| 236 | (prim == float.class && ref == Float.class) || | |
| 237 | (prim == double.class && ref == Double.class)); | |
| 238 | } | |
| 239 | } |
|
||||||||||