1 21 package proguard; 22 23 import proguard.classfile.ClassPool; 24 import proguard.classfile.attribute.visitor.AllAttributeVisitor; 25 import proguard.classfile.instruction.visitor.AllInstructionVisitor; 26 import proguard.classfile.util.*; 27 import proguard.classfile.visitor.*; 28 import proguard.util.ClassNameListMatcher; 29 30 import java.io.IOException ; 31 import java.util.*; 32 33 38 public class Initializer 39 { 40 private Configuration configuration; 41 42 43 47 public Initializer(Configuration configuration) 48 { 49 this.configuration = configuration; 50 } 51 52 53 57 public void execute(ClassPool programClassPool, 58 ClassPool libraryClassPool) throws IOException 59 { 60 int originalLibraryClassPoolSize = libraryClassPool.size(); 61 62 WarningPrinter hierarchyWarningPrinter = configuration.warn ? 64 new WarningPrinter(System.err) : 65 null; 66 67 programClassPool.classesAccept( 68 new ClassSuperHierarchyInitializer(programClassPool, 69 libraryClassPool, 70 hierarchyWarningPrinter)); 71 72 libraryClassPool.classesAccept( 74 new ClassSuperHierarchyInitializer(programClassPool, 75 libraryClassPool, 76 null)); 77 78 WarningPrinter classForNameNotePrinter = configuration.note ? 80 new WarningPrinter(System.out) : 81 null; 82 83 programClassPool.classesAccept( 84 new AllMethodVisitor( 85 new AllAttributeVisitor( 86 new AllInstructionVisitor( 87 new DynamicClassReferenceInitializer(programClassPool, 88 libraryClassPool, 89 classForNameNotePrinter, 90 createClassNoteExceptionMatcher(configuration.keep)))))); 91 92 WarningPrinter referenceWarningPrinter = configuration.warn ? 94 new WarningPrinter(System.err) : 95 null; 96 97 programClassPool.classesAccept( 98 new ClassReferenceInitializer(programClassPool, 99 libraryClassPool, 100 referenceWarningPrinter)); 101 102 WarningPrinter getMemberNotePrinter = configuration.note ? 104 new WarningPrinter(System.out) : 105 null; 106 107 programClassPool.classesAccept( 108 new AllMethodVisitor( 109 new AllAttributeVisitor( 110 new AllInstructionVisitor( 111 new DynamicMemberReferenceInitializer(getMemberNotePrinter, 112 createClassMemberNoteExceptionMatcher(configuration.keep, true), 113 createClassMemberNoteExceptionMatcher(configuration.keep, false)))))); 114 115 WarningPrinter fullyQualifiedClassNameNotePrinter = 117 new WarningPrinter(System.out); 118 119 WarningPrinter descriptorKeepNotePrinter = 120 new WarningPrinter(System.out); 121 122 if (configuration.note) 123 { 124 new FullyQualifiedClassNameChecker(programClassPool, 125 libraryClassPool, 126 fullyQualifiedClassNameNotePrinter).checkClassSpecifications(configuration.keep); 127 128 new DescriptorKeepChecker(programClassPool, 129 libraryClassPool, 130 descriptorKeepNotePrinter).checkClassSpecifications(configuration.keep); 131 } 132 133 if (configuration.useUniqueClassMemberNames) 138 { 139 libraryClassPool.classesAccept( 141 new ClassReferenceInitializer(programClassPool, 142 libraryClassPool, 143 null)); 144 } 145 else 146 { 147 ClassPool referencedLibraryClassPool = new ClassPool(); 148 149 programClassPool.classesAccept( 152 new ReferencedClassVisitor( 153 new LibraryClassFilter( 154 new ClassHierarchyTraveler(true, true, true, false, 155 new LibraryClassFilter( 156 new ClassPoolFiller(referencedLibraryClassPool)))))); 157 158 referencedLibraryClassPool.classesAccept( 160 new ClassReferenceInitializer(programClassPool, 161 libraryClassPool, 162 null)); 163 164 libraryClassPool.clear(); 166 167 referencedLibraryClassPool.classesAccept( 171 new MultiClassVisitor(new ClassVisitor[] 172 { 173 new ClassHierarchyTraveler(true, true, true, false, 174 new LibraryClassFilter( 175 new ClassPoolFiller(libraryClassPool))), 176 177 new ReferencedClassVisitor( 178 new LibraryClassFilter( 179 new ClassHierarchyTraveler(true, true, true, false, 180 new LibraryClassFilter( 181 new ClassPoolFiller(libraryClassPool))))) 182 })); 183 } 184 185 programClassPool.classesAccept(new ClassSubHierarchyInitializer()); 187 libraryClassPool.classesAccept(new ClassSubHierarchyInitializer()); 188 189 programClassPool.classesAccept(new StringSharer()); 191 libraryClassPool.classesAccept(new StringSharer()); 192 193 if (configuration.note) 195 { 196 int fullyQualifiedNoteCount = fullyQualifiedClassNameNotePrinter.getWarningCount(); 197 if (fullyQualifiedNoteCount > 0) 198 { 199 System.out.println("Note: there were " + fullyQualifiedNoteCount + 200 " references to unknown classes."); 201 System.out.println(" You should check your configuration for typos."); 202 } 203 204 int descriptorNoteCount = descriptorKeepNotePrinter.getWarningCount(); 205 if (descriptorNoteCount > 0) 206 { 207 System.out.println("Note: there were " + descriptorNoteCount + 208 " unkept descriptor classes in kept class members."); 209 System.out.println(" You should consider explicitly keeping the mentioned classes"); 210 System.out.println(" (using '-keep')."); 211 } 212 213 int classForNameNoteCount = classForNameNotePrinter.getWarningCount(); 214 if (classForNameNoteCount > 0) 215 { 216 System.out.println("Note: there were " + classForNameNoteCount + 217 " class casts of dynamically created class instances."); 218 System.out.println(" You might consider explicitly keeping the mentioned classes and/or"); 219 System.out.println(" their implementations (using '-keep')."); 220 } 221 222 int getmemberNoteCount = getMemberNotePrinter.getWarningCount(); 223 if (getmemberNoteCount > 0) 224 { 225 System.out.println("Note: there were " + getmemberNoteCount + 226 " accesses to class members by means of introspection."); 227 System.out.println(" You should consider explicitly keeping the mentioned class members"); 228 System.out.println(" (using '-keep' or '-keepclassmembers')."); 229 } 230 } 231 232 if (configuration.warn) 234 { 235 int hierarchyWarningCount = hierarchyWarningPrinter.getWarningCount(); 236 if (hierarchyWarningCount > 0) 237 { 238 System.err.println("Warning: there were " + hierarchyWarningCount + 239 " unresolved references to superclasses or interfaces."); 240 System.err.println(" You may need to specify additional library jars (using '-libraryjars'),"); 241 System.err.println(" or perhaps the '-dontskipnonpubliclibraryclasses' option."); 242 } 243 244 int referenceWarningCount = referenceWarningPrinter.getWarningCount(); 245 if (referenceWarningCount > 0) 246 { 247 System.err.println("Warning: there were " + referenceWarningCount + 248 " unresolved references to program class members."); 249 System.err.println(" Your input classes appear to be inconsistent."); 250 System.err.println(" You may need to recompile them and try again."); 251 System.err.println(" Alternatively, you may have to specify the options "); 252 System.err.println(" '-dontskipnonpubliclibraryclasses' and/or"); 253 System.err.println(" '-dontskipnonpubliclibraryclassmembers'."); 254 } 255 256 if ((hierarchyWarningCount > 0 || 257 referenceWarningCount > 0) && 258 !configuration.ignoreWarnings) 259 { 260 throw new IOException ("Please correct the above warnings first."); 261 } 262 } 263 264 if (configuration.verbose) 266 { 267 System.out.println("Ignoring unused library classes..."); 268 System.out.println(" Original number of library classes: " + originalLibraryClassPoolSize); 269 System.out.println(" Final number of library classes: " + libraryClassPool.size()); 270 } 271 } 272 273 274 278 private ClassNameListMatcher createClassNoteExceptionMatcher(List noteExceptions) 279 { 280 if (noteExceptions != null) 281 { 282 List noteExceptionNames = new ArrayList(noteExceptions.size()); 283 for (int index = 0; index < noteExceptions.size(); index++) 284 { 285 KeepSpecification keepSpecification = (KeepSpecification)noteExceptions.get(index); 286 if (keepSpecification.markClasses) 287 { 288 String className = keepSpecification.className; 290 if (className != null) 291 { 292 noteExceptionNames.add(className); 293 } 294 295 String extendsClassName = keepSpecification.extendsClassName; 297 if (extendsClassName != null) 298 { 299 noteExceptionNames.add(extendsClassName); 300 } 301 } 302 } 303 304 if (noteExceptionNames.size() > 0) 305 { 306 return new ClassNameListMatcher(noteExceptionNames); 307 } 308 } 309 310 return null; 311 } 312 313 314 318 private ClassNameListMatcher createClassMemberNoteExceptionMatcher(List noteExceptions, 319 boolean isField) 320 { 321 if (noteExceptions != null) 322 { 323 List noteExceptionNames = new ArrayList(); 324 for (int index = 0; index < noteExceptions.size(); index++) 325 { 326 KeepSpecification keepSpecification = (KeepSpecification)noteExceptions.get(index); 327 List memberSpecifications = isField ? 328 keepSpecification.fieldSpecifications : 329 keepSpecification.methodSpecifications; 330 331 if (memberSpecifications != null) 332 { 333 for (int index2 = 0; index2 < memberSpecifications.size(); index2++) 334 { 335 MemberSpecification memberSpecification = 336 (MemberSpecification)memberSpecifications.get(index2); 337 338 String memberName = memberSpecification.name; 339 if (memberName != null) 340 { 341 noteExceptionNames.add(memberName); 342 } 343 } 344 } 345 } 346 347 if (noteExceptionNames.size() > 0) 348 { 349 return new ClassNameListMatcher(noteExceptionNames); 350 } 351 } 352 353 return null; 354 } 355 } 356 | Popular Tags |