1 19 20 package soot.toolkits.astmetrics; 21 22 import soot.G; 23 import soot.options.*; 24 import polyglot.ast.*; 25 import polyglot.ast.Node; 26 import polyglot.visit.NodeVisitor; 27 28 import java.util.*; 29 import java.io.*; 30 31 36 public class IdentifiersMetric extends ASTMetric { 37 38 double nameComplexity = 0; 39 40 int dictionarySize = 0; 41 ArrayList dictionary; 42 43 HashMap names; 45 80 public IdentifiersMetric(Node astNode) { 81 super(astNode); 82 83 initializeDictionary(); 84 } 85 86 private void initializeDictionary() { 87 String line; 88 BufferedReader br; 89 dictionary = new ArrayList(); 90 names = new HashMap(); 91 92 InputStream is = ClassLoader.getSystemResourceAsStream("mydict.txt"); 93 if (is != null) 94 { 95 br = new BufferedReader(new InputStreamReader(is)); 96 97 try { 98 while ((line = br.readLine()) != null) 99 addWord(line); 100 } catch (IOException ioexc) {} 101 } 102 103 is = ClassLoader.getSystemResourceAsStream("soot/toolkits/astmetrics/dict.txt"); 104 if (is != null) 105 { 106 br = new BufferedReader(new InputStreamReader(is)); 107 108 try { 109 while ((line = br.readLine()) != null) 110 addWord(line.trim().toLowerCase()); 111 } catch (IOException ioexc) {} 112 } 113 114 if ((dictionarySize = dictionary.size()) == 0) 115 G.v().out.println("Error reading in dictionary file(s)"); 116 else if (Options.v().verbose()) 117 G.v().out.println("Read "+dictionarySize+" words in from dictionary file(s)"); 118 } 119 120 private void addWord(String word) { 121 if (dictionarySize == 0 || word.compareTo((String )dictionary.get(dictionarySize - 1)) > 0) { 122 dictionary.add(word); 123 } else { 124 int i = 0; 125 while (i < dictionarySize && word.compareTo((String )dictionary.get(i)) > 0) 126 i++; 127 128 if (word.compareTo((String )dictionary.get(i)) == 0) 129 return; 130 131 dictionary.add(i,word); 132 } 133 134 dictionarySize++; 135 } 136 137 140 public void reset() { 141 nameComplexity = 0; 142 } 143 144 147 public void addMetrics(ClassData data) { 148 data.addMetric(new MetricData("NameComplexity",new Double (nameComplexity))); 149 } 150 151 public NodeVisitor enter(Node parent, Node n){ 152 double multiplier = 1; 153 String name = null; 154 if(n instanceof ClassDecl){ 155 name = ((ClassDecl)n).name(); 156 multiplier = 3; 157 } else if (n instanceof MethodDecl) { 158 name = ((MethodDecl)n).name(); 159 multiplier = 4; 160 } else if (n instanceof FieldDecl) { 161 name = ((FieldDecl)n).name(); 162 multiplier = 2; 163 } else if (n instanceof Formal) { name = ((Formal)n).name(); 165 multiplier = 1.5; 166 } else if (n instanceof LocalDecl) { name = ((LocalDecl)n).name(); 168 } 169 170 if (name!=null) 171 { 172 nameComplexity += (double) (multiplier * computeNameComplexity(name)); 173 } 174 return enter(n); 175 } 176 177 private double computeNameComplexity(String name) { 178 if (names.containsKey(name)) 179 return ((Double )names.get(name)).doubleValue(); 180 181 int index = 0; 182 ArrayList strings = new ArrayList(); 183 184 String tmp = ""; 186 for (int i = 0; i < name.length(); i++) 187 { 188 char c = name.charAt(i); 189 if ((c > 64 && c < 91) || (c > 96 && c < 123)) { 190 tmp+=c; 191 } else if (tmp.length() > 0) { 192 strings.add(tmp); 193 tmp = ""; 194 } 195 } 196 if (tmp.length()>0) 197 strings.add(tmp); 198 199 ArrayList tokens = new ArrayList(); 200 for (int i = 0; i < strings.size(); i++) 201 { 202 tmp = (String )strings.get(i); 203 while (tmp.length() > 0) { 204 int caps = countCaps(tmp); 205 if (caps == 0) 206 { 207 int idx = findCap(tmp); 208 if (idx > 0) { 209 tokens.add(tmp.substring(0,idx)); 210 tmp = tmp.substring(idx,tmp.length()); 211 } else { 212 tokens.add(tmp.substring(0,tmp.length())); 213 break; 214 } 215 } else if (caps == 1){ 216 int idx = findCap(tmp.substring(1)) + 1; 217 if (idx > 0) { 218 tokens.add(tmp.substring(0,idx)); 219 tmp = tmp.substring(idx,tmp.length()); 220 } else { 221 tokens.add(tmp.substring(0,tmp.length())); 222 break; 223 } 224 } else { 225 if (caps < tmp.length()) { 226 tokens.add(tmp.substring(0, caps - 1).toLowerCase()); 228 tmp = tmp.substring(caps); 229 } else { 230 tokens.add(tmp.substring(0, caps).toLowerCase()); 231 break; 232 } 233 } 234 } 235 } 236 237 double words = 0; 238 double complexity = 0; 239 for (int i = 0; i < tokens.size(); i++) 240 if (dictionary.contains(tokens.get(i))) 241 words++; 242 243 if (words>0) 244 complexity = ((double)tokens.size()) / words; 245 246 names.put(name,new Double (complexity + computeCharComplexity(name))); 247 248 return complexity; 249 } 250 251 private double computeCharComplexity(String name) { 252 int count = 0, index = 0, last = 0, lng = name.length(); 253 while (index < lng) { 254 char c = name.charAt(index); 255 if ((c < 65 || c > 90) && (c < 97 || c > 122)) { 256 last++; 257 } else { 258 if (last>1) 259 count += last; 260 last = 0; 261 } 262 index++; 263 } 264 265 double complexity = lng - count; 266 267 if (complexity > 0) 268 return (((double)lng) / complexity); 269 else return (double)lng; 270 } 271 272 273 281 private int countNonAlphas(String name) { 282 int chars = 0; 283 while (chars < name.length()) { 284 char c = name.charAt(chars); 285 if ((c < 65 || c > 90) && (c < 97 || c > 122)) 286 chars++; 287 else 288 break; 289 } 290 291 return chars; 292 } 293 294 302 private int countCaps(String name) { 303 int caps = 0; 304 while (caps < name.length()) { 305 char c = name.charAt(caps); 306 if (c > 64 && c < 91) 307 caps++; 308 else 309 break; 310 } 311 312 return caps; 313 } 314 315 323 private int findCap(String name) { 324 int idx = 0; 325 while (idx < name.length()) { 326 char c = name.charAt(idx); 327 if (c > 64 && c < 91) 328 return idx; 329 else 330 idx++; 331 } 332 333 return -1; 334 } 335 } 336 | Popular Tags |