1 34 35 package org.logicalcobwebs.asm.util; 36 37 import org.logicalcobwebs.asm.ClassAdapter; 38 import org.logicalcobwebs.asm.ClassVisitor; 39 import org.logicalcobwebs.asm.CodeVisitor; 40 import org.logicalcobwebs.asm.Constants; 41 import org.logicalcobwebs.asm.Attribute; 42 43 51 52 public class CheckClassAdapter extends ClassAdapter { 53 54 57 58 private boolean start; 59 60 63 64 private boolean end; 65 66 71 72 public CheckClassAdapter (final ClassVisitor cv) { 73 super(cv); 74 } 75 76 public void visit ( 77 final int access, 78 final String name, 79 final String superName, 80 final String [] interfaces, 81 final String sourceFile) 82 { 83 if (start) { 84 throw new IllegalStateException ("visit must be called only once"); 85 } else { 86 start = true; 87 } 88 checkState(); 89 checkAccess(access, 1 + 2 + 4 + 16 + 512 + 1024 + 32 + 65536 + 131072); 90 CheckCodeAdapter.checkInternalName(name, "class name"); 91 if (name.equals("java/lang/Object")) { 92 if (superName != null) { 93 throw new IllegalArgumentException ( 94 "The super class name of the Object class must be 'null'"); 95 } 96 } else { 97 CheckCodeAdapter.checkInternalName(superName, "super class name"); 98 } 99 if ((access & Constants.ACC_INTERFACE) != 0) { 100 if (!superName.equals("java/lang/Object")) { 101 throw new IllegalArgumentException ( 102 "The super class name of interfaces must be 'java/lang/Object'"); 103 } 104 } 105 if (interfaces != null) { 106 for (int i = 0; i < interfaces.length; ++i) { 107 CheckCodeAdapter.checkInternalName( 108 interfaces[i], "interface name at index " + i); 109 } 110 } 111 cv.visit(access, name, superName, interfaces, sourceFile); 112 } 113 114 public void visitInnerClass ( 115 final String name, 116 final String outerName, 117 final String innerName, 118 final int access) 119 { 120 checkState(); 121 CheckCodeAdapter.checkInternalName(name, "class name"); 122 if (outerName != null) { 123 CheckCodeAdapter.checkInternalName(outerName, "outer class name"); 124 } 125 if (innerName != null) { 126 CheckCodeAdapter.checkIdentifier(innerName, "inner class name"); 127 } 128 checkAccess(access, 1 + 2 + 4 + 8 + 16 + 512 + 1024 + 32); 129 cv.visitInnerClass(name, outerName, innerName, access); 130 } 131 132 public void visitField ( 133 final int access, 134 final String name, 135 final String desc, 136 final Object value, 137 final Attribute attrs) 138 { 139 checkState(); 140 checkAccess(access, 1 + 2 + 4 + 8 + 16 + 64 + 128 + 65536 + 131072); 141 CheckCodeAdapter.checkIdentifier(name, "field name"); 142 CheckCodeAdapter.checkDesc(desc, false); 143 if (value != null) { 144 CheckCodeAdapter.checkConstant(value); 145 } 146 cv.visitField(access, name, desc, value, attrs); 147 } 148 149 public CodeVisitor visitMethod ( 150 final int access, 151 final String name, 152 final String desc, 153 final String [] exceptions, 154 final Attribute attrs) 155 { 156 checkState(); 157 checkAccess( 158 access, 1 + 2 + 4 + 8 + 16 + 32 + 256 + 1024 + 2048 + 65536 + 131072); 159 CheckCodeAdapter.checkMethodIdentifier(name, "method name"); 160 CheckCodeAdapter.checkMethodDesc(desc); 161 if (exceptions != null) { 162 for (int i = 0; i < exceptions.length; ++i) { 163 CheckCodeAdapter.checkInternalName( 164 exceptions[i], "exception name at index " + i); 165 } 166 } 167 return new CheckCodeAdapter( 168 cv.visitMethod(access, name, desc, exceptions, attrs)); 169 } 170 171 public void visitAttribute (final Attribute attr) { 172 checkState(); 173 if (attr == null) { 174 throw new IllegalArgumentException ( 175 "Invalid attribute (must not be null)"); 176 } 177 } 178 179 public void visitEnd () { 180 checkState(); 181 end = true; 182 cv.visitEnd(); 183 } 184 185 187 191 192 private void checkState () { 193 if (!start) { 194 throw new IllegalStateException ( 195 "Cannot visit member before visit has been called."); 196 } 197 if (end) { 198 throw new IllegalStateException ( 199 "Cannot visit member after visitEnd has been called."); 200 } 201 } 202 203 211 212 static void checkAccess (final int access, final int possibleAccess) { 213 if ((access & ~possibleAccess) != 0) { 214 throw new IllegalArgumentException ("Invalid access flags: " + access); 215 } 216 int pub = ((access & Constants.ACC_PUBLIC) != 0 ? 1 : 0); 217 int pri = ((access & Constants.ACC_PRIVATE) != 0 ? 1 : 0); 218 int pro = ((access & Constants.ACC_PROTECTED) != 0 ? 1 : 0); 219 if (pub + pri + pro > 1) { 220 throw new IllegalArgumentException ( 221 "public private and protected are mutually exclusive: " + access); 222 } 223 int fin = ((access & Constants.ACC_FINAL) != 0 ? 1 : 0); 224 int abs = ((access & Constants.ACC_ABSTRACT) != 0 ? 1 : 0); 225 if (fin + abs > 1) { 226 throw new IllegalArgumentException ( 227 "final and abstract are mutually exclusive: " + access); 228 } 229 } 230 } 231 | Popular Tags |