1 11 package org.eclipse.jdt.internal.compiler; 12 13 33 import java.util.Arrays ; 34 import java.util.Comparator ; 35 import java.util.HashMap ; 36 import java.util.HashSet ; 37 import java.util.Hashtable ; 38 import java.util.Iterator ; 39 import java.util.Map ; 40 import java.util.Set ; 41 42 import org.eclipse.jdt.core.compiler.CategorizedProblem; 43 import org.eclipse.jdt.core.compiler.IProblem; 44 import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; 45 import org.eclipse.jdt.internal.compiler.env.ICompilationUnit; 46 import org.eclipse.jdt.internal.compiler.impl.ReferenceContext; 47 import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding; 48 import org.eclipse.jdt.internal.compiler.parser.RecoveryScannerData; 49 import org.eclipse.jdt.internal.compiler.problem.ProblemReporter; 50 import org.eclipse.jdt.internal.compiler.util.Util; 51 52 public class CompilationResult { 53 54 public CategorizedProblem problems[]; 55 public CategorizedProblem tasks[]; 56 public int problemCount; 57 public int taskCount; 58 public ICompilationUnit compilationUnit; 59 private Map problemsMap; 60 private Set firstErrors; 61 private int maxProblemPerUnit; 62 public char[][][] qualifiedReferences; 63 public char[][] simpleNameReferences; 64 public boolean hasAnnotations = false; 65 public int lineSeparatorPositions[]; 66 public RecoveryScannerData recoveryScannerData; 67 public Map compiledTypes = new Hashtable (11); 68 public int unitIndex, totalUnitsKnown; 69 public boolean hasBeenAccepted = false; 70 public char[] fileName; 71 public boolean hasInconsistentToplevelHierarchies = false; public boolean hasSyntaxError = false; 73 long[] suppressWarningIrritants; long[] suppressWarningScopePositions; int suppressWarningsCount; 76 public char[][] packageName; 77 78 private static final int[] EMPTY_LINE_ENDS = Util.EMPTY_INT_ARRAY; 79 private static final Comparator PROBLEM_COMPARATOR = new Comparator () { 80 public int compare(Object o1, Object o2) { 81 return ((CategorizedProblem) o1).getSourceStart() - ((CategorizedProblem) o2).getSourceStart(); 82 } 83 }; 84 85 public CompilationResult( 86 char[] fileName, 87 int unitIndex, 88 int totalUnitsKnown, 89 int maxProblemPerUnit){ 90 91 this.fileName = fileName; 92 this.unitIndex = unitIndex; 93 this.totalUnitsKnown = totalUnitsKnown; 94 this.maxProblemPerUnit = maxProblemPerUnit; 95 } 96 97 public CompilationResult( 98 ICompilationUnit compilationUnit, 99 int unitIndex, 100 int totalUnitsKnown, 101 int maxProblemPerUnit){ 102 103 this.fileName = compilationUnit.getFileName(); 104 this.compilationUnit = compilationUnit; 105 this.unitIndex = unitIndex; 106 this.totalUnitsKnown = totalUnitsKnown; 107 this.maxProblemPerUnit = maxProblemPerUnit; 108 } 109 110 private int computePriority(CategorizedProblem problem){ 111 final int P_STATIC = 10000; 112 final int P_OUTSIDE_METHOD = 40000; 113 final int P_FIRST_ERROR = 20000; 114 final int P_ERROR = 100000; 115 116 int priority = 10000 - problem.getSourceLineNumber(); if (priority < 0) priority = 0; 118 if (problem.isError()){ 119 priority += P_ERROR; 120 } 121 ReferenceContext context = this.problemsMap == null ? null : (ReferenceContext) this.problemsMap.get(problem); 122 if (context != null){ 123 if (context instanceof AbstractMethodDeclaration){ 124 AbstractMethodDeclaration method = (AbstractMethodDeclaration) context; 125 if (method.isStatic()) { 126 priority += P_STATIC; 127 } 128 } else { 129 priority += P_OUTSIDE_METHOD; 130 } 131 if (this.firstErrors.contains(problem)){ priority += P_FIRST_ERROR; 133 } 134 } else { 135 priority += P_OUTSIDE_METHOD; 136 } 137 return priority; 138 } 139 140 public void discardSuppressedWarnings() { 141 if (this.suppressWarningsCount == 0) return; 142 int removed = 0; 143 nextProblem: for (int i = 0, length = this.problemCount; i < length; i++) { 144 CategorizedProblem problem = this.problems[i]; 145 int problemID = problem.getID(); 146 if (!problem.isWarning()) { 147 continue nextProblem; 148 } 149 int start = problem.getSourceStart(); 150 int end = problem.getSourceEnd(); 151 nextSuppress: for (int j = 0, max = this.suppressWarningsCount; j < max; j++) { 152 long position = this.suppressWarningScopePositions[j]; 153 int startSuppress = (int) (position >>> 32); 154 int endSuppress = (int) position; 155 if (start < startSuppress) continue nextSuppress; 156 if (end > endSuppress) continue nextSuppress; 157 if ((ProblemReporter.getIrritant(problemID) & this.suppressWarningIrritants[j]) == 0) 158 continue nextSuppress; 159 removed++; 161 this.problems[i] = null; 162 if (this.problemsMap != null) this.problemsMap.remove(problem); 163 if (this.firstErrors != null) this.firstErrors.remove(problem); 164 continue nextProblem; 165 } 166 } 167 if (removed > 0) { 168 for (int i = 0, index = 0; i < this.problemCount; i++) { 169 CategorizedProblem problem; 170 if ((problem = this.problems[i]) != null) { 171 if (i > index) { 172 this.problems[index++] = problem; 173 } else { 174 index++; 175 } 176 } 177 } 178 this.problemCount -= removed; 179 } 180 } 181 182 public CategorizedProblem[] getAllProblems() { 183 CategorizedProblem[] onlyProblems = this.getProblems(); 184 int onlyProblemCount = onlyProblems != null ? onlyProblems.length : 0; 185 CategorizedProblem[] onlyTasks = this.getTasks(); 186 int onlyTaskCount = onlyTasks != null ? onlyTasks.length : 0; 187 if (onlyTaskCount == 0) { 188 return onlyProblems; 189 } 190 if (onlyProblemCount == 0) { 191 return onlyTasks; 192 } 193 194 int totalNumberOfProblem = onlyProblemCount + onlyTaskCount; 195 CategorizedProblem[] allProblems = new CategorizedProblem[totalNumberOfProblem]; 196 int allProblemIndex = 0; 197 int taskIndex = 0; 198 int problemIndex = 0; 199 while (taskIndex + problemIndex < totalNumberOfProblem) { 200 CategorizedProblem nextTask = null; 201 CategorizedProblem nextProblem = null; 202 if (taskIndex < onlyTaskCount) { 203 nextTask = onlyTasks[taskIndex]; 204 } 205 if (problemIndex < onlyProblemCount) { 206 nextProblem = onlyProblems[problemIndex]; 207 } 208 CategorizedProblem currentProblem = null; 210 if (nextProblem != null) { 211 if (nextTask != null) { 212 if (nextProblem.getSourceStart() < nextTask.getSourceStart()) { 213 currentProblem = nextProblem; 214 problemIndex++; 215 } else { 216 currentProblem = nextTask; 217 taskIndex++; 218 } 219 } else { 220 currentProblem = nextProblem; 221 problemIndex++; 222 } 223 } else { 224 if (nextTask != null) { 225 currentProblem = nextTask; 226 taskIndex++; 227 } 228 } 229 allProblems[allProblemIndex++] = currentProblem; 230 } 231 return allProblems; 232 } 233 234 public ClassFile[] getClassFiles() { 235 ClassFile[] classFiles = new ClassFile[this.compiledTypes.size()]; 236 this.compiledTypes.values().toArray(classFiles); 237 return classFiles; 238 } 239 240 243 public ICompilationUnit getCompilationUnit(){ 244 return this.compilationUnit; 245 } 246 247 250 public CategorizedProblem[] getErrors() { 251 CategorizedProblem[] reportedProblems = getProblems(); 252 int errorCount = 0; 253 for (int i = 0; i < this.problemCount; i++) { 254 if (reportedProblems[i].isError()) errorCount++; 255 } 256 if (errorCount == this.problemCount) return reportedProblems; 257 CategorizedProblem[] errors = new CategorizedProblem[errorCount]; 258 int index = 0; 259 for (int i = 0; i < this.problemCount; i++) { 260 if (reportedProblems[i].isError()) errors[index++] = reportedProblems[i]; 261 } 262 return errors; 263 } 264 265 266 269 public char[] getFileName(){ 270 return this.fileName; 271 } 272 273 public int[] getLineSeparatorPositions() { 274 return this.lineSeparatorPositions == null ? CompilationResult.EMPTY_LINE_ENDS : this.lineSeparatorPositions; 275 } 276 277 285 public CategorizedProblem[] getProblems() { 286 if (this.problems != null) { 288 discardSuppressedWarnings(); 289 290 if (this.problemCount != this.problems.length) { 291 System.arraycopy(this.problems, 0, (this.problems = new CategorizedProblem[this.problemCount]), 0, this.problemCount); 292 } 293 294 if (this.maxProblemPerUnit > 0 && this.problemCount > this.maxProblemPerUnit){ 295 quickPrioritize(this.problems, 0, this.problemCount - 1); 296 this.problemCount = this.maxProblemPerUnit; 297 System.arraycopy(this.problems, 0, (this.problems = new CategorizedProblem[this.problemCount]), 0, this.problemCount); 298 } 299 300 Arrays.sort(this.problems, 0, this.problems.length, CompilationResult.PROBLEM_COMPARATOR); 302 } 304 return this.problems; 305 } 306 307 315 public CategorizedProblem[] getTasks() { 316 if (this.tasks != null) { 318 319 if (this.taskCount != this.tasks.length) { 320 System.arraycopy(this.tasks, 0, (this.tasks = new CategorizedProblem[this.taskCount]), 0, this.taskCount); 321 } 322 Arrays.sort(this.tasks, 0, this.tasks.length, CompilationResult.PROBLEM_COMPARATOR); 324 } 326 return this.tasks; 327 } 328 329 public boolean hasErrors() { 330 if (this.problems != null) 331 for (int i = 0; i < this.problemCount; i++) { 332 if (this.problems[i].isError()) 333 return true; 334 } 335 return false; 336 } 337 338 public boolean hasProblems() { 339 return this.problemCount != 0; 340 } 341 342 public boolean hasTasks() { 343 return this.taskCount != 0; 344 } 345 346 public boolean hasWarnings() { 347 if (this.problems != null) 348 for (int i = 0; i < this.problemCount; i++) { 349 if (this.problems[i].isWarning()) 350 return true; 351 } 352 return false; 353 } 354 355 private void quickPrioritize(CategorizedProblem[] problemList, int left, int right) { 356 if (left >= right) return; 357 358 int original_left = left; 360 int original_right = right; 361 int mid = computePriority(problemList[left + (right - left) / 2]); 362 do { 363 while (computePriority(problemList[right]) < mid) 364 right--; 365 while (mid < computePriority(problemList[left])) 366 left++; 367 if (left <= right) { 368 CategorizedProblem tmp = problemList[left]; 369 problemList[left] = problemList[right]; 370 problemList[right] = tmp; 371 left++; 372 right--; 373 } 374 } while (left <= right); 375 if (original_left < right) 376 quickPrioritize(problemList, original_left, right); 377 if (left < original_right) 378 quickPrioritize(problemList, left, original_right); 379 } 380 383 public void recordPackageName(char[][] packName) { 384 this.packageName = packName; 385 } 386 public void record(CategorizedProblem newProblem, ReferenceContext referenceContext) { 387 if(newProblem.getID() == IProblem.Task) { 389 recordTask(newProblem); 390 return; 391 } 392 if (this.problemCount == 0) { 393 this.problems = new CategorizedProblem[5]; 394 } else if (this.problemCount == this.problems.length) { 395 System.arraycopy(this.problems, 0, (this.problems = new CategorizedProblem[this.problemCount * 2]), 0, this.problemCount); 396 } 397 this.problems[this.problemCount++] = newProblem; 398 if (referenceContext != null){ 399 if (this.problemsMap == null) this.problemsMap = new HashMap (5); 400 if (this.firstErrors == null) this.firstErrors = new HashSet (5); 401 if (newProblem.isError() && !referenceContext.hasErrors()) this.firstErrors.add(newProblem); 402 this.problemsMap.put(newProblem, referenceContext); 403 } 404 if ((newProblem.getID() & IProblem.Syntax) != 0 && newProblem.isError()) 405 this.hasSyntaxError = true; 406 } 407 408 411 public void record(char[] typeName, ClassFile classFile) { 412 SourceTypeBinding sourceType = classFile.referenceBinding; 413 if (!sourceType.isLocalType() && sourceType.isHierarchyInconsistent()) { 414 this.hasInconsistentToplevelHierarchies = true; 415 } 416 this.compiledTypes.put(typeName, classFile); 417 } 418 419 public void recordSuppressWarnings(long irritant, int scopeStart, int scopeEnd) { 420 if (this.suppressWarningIrritants == null) { 421 this.suppressWarningIrritants = new long[3]; 422 this.suppressWarningScopePositions = new long[3]; 423 } else if (this.suppressWarningIrritants.length == this.suppressWarningsCount) { 424 System.arraycopy(this.suppressWarningIrritants, 0,this.suppressWarningIrritants = new long[2*this.suppressWarningsCount], 0, this.suppressWarningsCount); 425 System.arraycopy(this.suppressWarningScopePositions, 0,this.suppressWarningScopePositions = new long[2*this.suppressWarningsCount], 0, this.suppressWarningsCount); 426 } 427 this.suppressWarningIrritants[this.suppressWarningsCount] = irritant; 428 this.suppressWarningScopePositions[this.suppressWarningsCount++] = ((long)scopeStart<<32) + scopeEnd; 429 } 430 431 private void recordTask(CategorizedProblem newProblem) { 432 if (this.taskCount == 0) { 433 this.tasks = new CategorizedProblem[5]; 434 } else if (this.taskCount == this.tasks.length) { 435 System.arraycopy(this.tasks, 0, (this.tasks = new CategorizedProblem[this.taskCount * 2]), 0, this.taskCount); 436 } 437 this.tasks[this.taskCount++] = newProblem; 438 } 439 440 public CompilationResult tagAsAccepted(){ 441 this.hasBeenAccepted = true; 442 this.problemsMap = null; this.firstErrors = null; return this; 445 } 446 447 public String toString(){ 448 StringBuffer buffer = new StringBuffer (); 449 if (this.fileName != null){ 450 buffer.append("Filename : ").append(this.fileName).append('\n'); } 452 if (this.compiledTypes != null){ 453 buffer.append("COMPILED type(s) \n"); Iterator keys = this.compiledTypes.keySet().iterator(); 455 while (keys.hasNext()) { 456 char[] typeName = (char[]) keys.next(); 457 buffer.append("\t - ").append(typeName).append('\n'); 459 } 460 } else { 461 buffer.append("No COMPILED type\n"); } 463 if (this.problems != null){ 464 buffer.append(this.problemCount).append(" PROBLEM(s) detected \n"); for (int i = 0; i < this.problemCount; i++){ 466 buffer.append("\t - ").append(this.problems[i]).append('\n'); } 468 } else { 469 buffer.append("No PROBLEM\n"); } 471 return buffer.toString(); 472 } 473 } 474 | Popular Tags |