1 21 package proguard.shrink; 22 23 import proguard.classfile.*; 24 import proguard.classfile.attribute.*; 25 import proguard.classfile.attribute.annotation.*; 26 import proguard.classfile.instruction.*; 27 import proguard.classfile.visitor.*; 28 29 30 39 public class ShortestUsageMarker extends UsageMarker 40 { 41 private static final ShortestUsageMark INITIAL_MARK = 42 new ShortestUsageMark("is kept by a directive in the configuration.\n\n"); 43 44 45 private ShortestUsageMark currentUsageMark = INITIAL_MARK; 47 48 private MyRecursiveCauseChecker recursiveCauseChecker = new MyRecursiveCauseChecker(); 50 51 52 54 protected void markProgramClassBody(ProgramClass programClass) 55 { 56 ShortestUsageMark previousUsageMark = currentUsageMark; 57 58 currentUsageMark = new ShortestUsageMark(getShortestUsageMark(programClass), 59 "is extended by ", 60 10000, 61 programClass); 62 63 super.markProgramClassBody(programClass); 64 65 currentUsageMark = previousUsageMark; 66 } 67 68 69 protected void markProgramMethodBody(ProgramClass programClass, ProgramMethod programMethod) 70 { 71 ShortestUsageMark previousUsageMark = currentUsageMark; 72 73 currentUsageMark = new ShortestUsageMark(getShortestUsageMark(programMethod), 74 "is invoked by ", 75 1, 76 programClass, 77 programMethod); 78 79 super.markProgramMethodBody(programClass, programMethod); 80 81 currentUsageMark = previousUsageMark; 82 } 83 84 85 protected void markMethodHierarchy(Clazz clazz, Method method) 86 { 87 ShortestUsageMark previousUsageMark = currentUsageMark; 88 89 currentUsageMark = new ShortestUsageMark(getShortestUsageMark(method), 90 "implements ", 91 100, 92 clazz, 93 method); 94 95 super.markMethodHierarchy(clazz, method); 96 97 currentUsageMark = previousUsageMark; 98 } 99 100 101 103 protected void markAsUsed(VisitorAccepter visitorAccepter) 104 { 105 Object visitorInfo = visitorAccepter.getVisitorInfo(); 106 107 ShortestUsageMark shortestUsageMark = 108 visitorInfo != null && 109 visitorInfo instanceof ShortestUsageMark && 110 !((ShortestUsageMark)visitorInfo).isCertain() && 111 !currentUsageMark.isShorter((ShortestUsageMark)visitorInfo) ? 112 new ShortestUsageMark((ShortestUsageMark)visitorInfo, true): 113 currentUsageMark; 114 115 visitorAccepter.setVisitorInfo(shortestUsageMark); 116 } 117 118 119 protected boolean shouldBeMarkedAsUsed(VisitorAccepter visitorAccepter) 120 { 121 Object visitorInfo = visitorAccepter.getVisitorInfo(); 122 123 return (visitorInfo == null || 126 !(visitorInfo instanceof ShortestUsageMark) || 127 !((ShortestUsageMark)visitorInfo).isCertain() || 128 currentUsageMark.isShorter((ShortestUsageMark)visitorInfo)); 129 } 130 131 132 protected boolean isUsed(VisitorAccepter visitorAccepter) 133 { 134 Object visitorInfo = visitorAccepter.getVisitorInfo(); 135 136 return visitorInfo != null && 137 visitorInfo instanceof ShortestUsageMark && 138 ((ShortestUsageMark)visitorInfo).isCertain(); 139 } 140 141 142 protected void markAsPossiblyUsed(VisitorAccepter visitorAccepter) 143 { 144 visitorAccepter.setVisitorInfo(new ShortestUsageMark(currentUsageMark, false)); 145 } 146 147 148 protected boolean shouldBeMarkedAsPossiblyUsed(VisitorAccepter visitorAccepter) 149 { 150 Object visitorInfo = visitorAccepter.getVisitorInfo(); 151 152 return visitorInfo == null || 153 !(visitorInfo instanceof ShortestUsageMark) || 154 (!((ShortestUsageMark)visitorInfo).isCertain() && 155 currentUsageMark.isShorter((ShortestUsageMark)visitorInfo)); 156 } 157 158 159 protected boolean isPossiblyUsed(VisitorAccepter visitorAccepter) 160 { 161 Object visitorInfo = visitorAccepter.getVisitorInfo(); 162 163 return visitorInfo != null && 164 visitorInfo instanceof ShortestUsageMark && 165 !((ShortestUsageMark)visitorInfo).isCertain(); 166 } 167 168 169 protected ShortestUsageMark getShortestUsageMark(VisitorAccepter visitorAccepter) 170 { 171 Object visitorInfo = visitorAccepter.getVisitorInfo(); 172 173 return (ShortestUsageMark)visitorInfo; 174 } 175 176 177 179 private boolean isCausedBy(ShortestUsageMark shortestUsageMark, 180 Clazz clazz) 181 { 182 return recursiveCauseChecker.check(shortestUsageMark, clazz); 183 } 184 185 186 private class MyRecursiveCauseChecker implements ClassVisitor, MemberVisitor 187 { 188 private Clazz checkClass; 189 private boolean isRecursing; 190 191 192 public boolean check(ShortestUsageMark shortestUsageMark, 193 Clazz clazz) 194 { 195 checkClass = clazz; 196 isRecursing = false; 197 198 shortestUsageMark.acceptClassVisitor(this); 199 shortestUsageMark.acceptMethodVisitor(this); 200 201 return isRecursing; 202 } 203 204 206 public void visitProgramClass(ProgramClass programClass) 207 { 208 checkCause(programClass); 209 } 210 211 212 public void visitLibraryClass(LibraryClass libraryClass) 213 { 214 checkCause(libraryClass); 215 } 216 217 218 220 public void visitProgramField(ProgramClass programClass, ProgramField programField) 221 { 222 checkCause(programField); 223 } 224 225 226 public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) 227 { 228 checkCause(programMethod); 229 } 230 231 232 public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField) 233 { 234 checkCause(libraryField); 235 } 236 237 238 public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod) 239 { 240 checkCause(libraryMethod); 241 } 242 243 244 246 private void checkCause(VisitorAccepter visitorAccepter) 247 { 248 if (ShortestUsageMarker.this.isUsed(visitorAccepter)) 249 { 250 ShortestUsageMark shortestUsageMark = ShortestUsageMarker.this.getShortestUsageMark(visitorAccepter); 251 252 isRecursing = shortestUsageMark.isCausedBy(checkClass); 254 255 if (!isRecursing) 257 { 258 shortestUsageMark.acceptClassVisitor(this); 259 shortestUsageMark.acceptMethodVisitor(this); 260 } 261 } 262 } 263 } 264 } 265 | Popular Tags |