1 11 package org.eclipse.jdt.internal.compiler.ast; 12 13 import java.util.Arrays ; 14 import java.util.Comparator ; 15 16 import org.eclipse.jdt.core.compiler.CategorizedProblem; 17 import org.eclipse.jdt.core.compiler.CharOperation; 18 import org.eclipse.jdt.internal.compiler.ASTVisitor; 19 import org.eclipse.jdt.internal.compiler.ClassFile; 20 import org.eclipse.jdt.internal.compiler.CompilationResult; 21 import org.eclipse.jdt.internal.compiler.impl.ReferenceContext; 22 import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope; 23 import org.eclipse.jdt.internal.compiler.lookup.ImportBinding; 24 import org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding; 25 import org.eclipse.jdt.internal.compiler.lookup.MethodScope; 26 import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; 27 import org.eclipse.jdt.internal.compiler.parser.NLSTag; 28 import org.eclipse.jdt.internal.compiler.problem.AbortCompilationUnit; 29 import org.eclipse.jdt.internal.compiler.problem.AbortMethod; 30 import org.eclipse.jdt.internal.compiler.problem.AbortType; 31 import org.eclipse.jdt.internal.compiler.problem.ProblemReporter; 32 import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities; 33 34 public class CompilationUnitDeclaration 35 extends ASTNode 36 implements ProblemSeverities, ReferenceContext { 37 38 private static final Comparator STRING_LITERAL_COMPARATOR = new Comparator () { 39 public int compare(Object o1, Object o2) { 40 StringLiteral literal1 = (StringLiteral) o1; 41 StringLiteral literal2 = (StringLiteral) o2; 42 return literal1.sourceStart - literal2.sourceStart; 43 } 44 }; 45 private static final int STRING_LITERALS_INCREMENT = 10; 46 47 public ImportReference currentPackage; 48 public ImportReference[] imports; 49 public TypeDeclaration[] types; 50 public int[][] comments; 51 52 public boolean ignoreFurtherInvestigation = false; public boolean ignoreMethodBodies = false; 54 public CompilationUnitScope scope; 55 public ProblemReporter problemReporter; 56 public CompilationResult compilationResult; 57 58 public LocalTypeBinding[] localTypes; 59 public int localTypeCount = 0; 60 61 public boolean isPropagatingInnerClassEmulation; 62 63 public Javadoc javadoc; 65 public NLSTag[] nlsTags; 66 private StringLiteral[] stringLiterals; 67 private int stringLiteralsPtr; 68 69 public CompilationUnitDeclaration( 70 ProblemReporter problemReporter, 71 CompilationResult compilationResult, 72 int sourceLength) { 73 74 this.problemReporter = problemReporter; 75 this.compilationResult = compilationResult; 76 77 sourceStart = 0; 79 sourceEnd = sourceLength - 1; 80 } 81 82 85 public void abort(int abortLevel, CategorizedProblem problem) { 86 87 switch (abortLevel) { 88 case AbortType : 89 throw new AbortType(this.compilationResult, problem); 90 case AbortMethod : 91 throw new AbortMethod(this.compilationResult, problem); 92 default : 93 throw new AbortCompilationUnit(this.compilationResult, problem); 94 } 95 } 96 97 100 public void analyseCode() { 101 102 if (ignoreFurtherInvestigation) 103 return; 104 try { 105 if (types != null) { 106 for (int i = 0, count = types.length; i < count; i++) { 107 types[i].analyseCode(scope); 108 } 109 } 110 propagateInnerEmulationForAllLocalTypes(); 112 } catch (AbortCompilationUnit e) { 113 this.ignoreFurtherInvestigation = true; 114 return; 115 } 116 } 117 118 122 public void cleanUp() { 123 if (this.types != null) { 124 for (int i = 0, max = this.types.length; i < max; i++) { 125 cleanUp(this.types[i]); 126 } 127 for (int i = 0, max = this.localTypeCount; i < max; i++) { 128 LocalTypeBinding localType = localTypes[i]; 129 localType.scope = null; localType.enclosingCase = null; 132 } 133 } 134 135 compilationResult.recoveryScannerData = null; 137 ClassFile[] classFiles = compilationResult.getClassFiles(); 138 for (int i = 0, max = classFiles.length; i < max; i++) { 139 ClassFile classFile = classFiles[i]; 141 classFile.referenceBinding = null; 143 classFile.innerClassesBindings = null; 144 } 145 } 146 private void cleanUp(TypeDeclaration type) { 147 if (type.memberTypes != null) { 148 for (int i = 0, max = type.memberTypes.length; i < max; i++){ 149 cleanUp(type.memberTypes[i]); 150 } 151 } 152 if (type.binding != null && type.binding.isAnnotationType()) 153 compilationResult.hasAnnotations = true; 154 if (type.binding != null) { 155 type.binding.scope = null; 157 } 158 } 159 160 public void checkUnusedImports(){ 161 162 if (this.scope.imports != null){ 163 for (int i = 0, max = this.scope.imports.length; i < max; i++){ 164 ImportBinding importBinding = this.scope.imports[i]; 165 ImportReference importReference = importBinding.reference; 166 if (importReference != null && ((importReference.bits & ASTNode.Used) == 0)){ 167 scope.problemReporter().unusedImport(importReference); 168 } 169 } 170 } 171 } 172 173 public CompilationResult compilationResult() { 174 return this.compilationResult; 175 } 176 177 183 public TypeDeclaration declarationOfType(char[][] typeName) { 184 185 for (int i = 0; i < this.types.length; i++) { 186 TypeDeclaration typeDecl = this.types[i].declarationOfType(typeName); 187 if (typeDecl != null) { 188 return typeDecl; 189 } 190 } 191 return null; 192 } 193 194 197 public void generateCode() { 198 199 if (ignoreFurtherInvestigation) { 200 if (types != null) { 201 for (int i = 0, count = types.length; i < count; i++) { 202 types[i].ignoreFurtherInvestigation = true; 203 types[i].generateCode(scope); 205 } 206 } 207 return; 208 } 209 if (this.isPackageInfo() && this.types != null && this.currentPackage!= null && this.currentPackage.annotations != null) { 210 types[0].annotations = this.currentPackage.annotations; 211 } 212 try { 213 if (types != null) { 214 for (int i = 0, count = types.length; i < count; i++) 215 types[i].generateCode(scope); 216 } 217 } catch (AbortCompilationUnit e) { 218 } 220 } 221 222 public char[] getFileName() { 223 224 return compilationResult.getFileName(); 225 } 226 227 public char[] getMainTypeName() { 228 229 if (compilationResult.compilationUnit == null) { 230 char[] fileName = compilationResult.getFileName(); 231 232 int start = CharOperation.lastIndexOf('/', fileName) + 1; 233 if (start == 0 || start < CharOperation.lastIndexOf('\\', fileName)) 234 start = CharOperation.lastIndexOf('\\', fileName) + 1; 235 236 int end = CharOperation.lastIndexOf('.', fileName); 237 if (end == -1) 238 end = fileName.length; 239 240 return CharOperation.subarray(fileName, start, end); 241 } else { 242 return compilationResult.compilationUnit.getMainTypeName(); 243 } 244 } 245 246 public boolean isEmpty() { 247 248 return (currentPackage == null) && (imports == null) && (types == null); 249 } 250 251 public boolean isPackageInfo() { 252 return CharOperation.equals(this.getMainTypeName(), TypeConstants.PACKAGE_INFO_NAME); 253 } 254 255 public boolean hasErrors() { 256 return this.ignoreFurtherInvestigation; 257 } 258 259 public StringBuffer print(int indent, StringBuffer output) { 260 261 if (currentPackage != null) { 262 printIndent(indent, output).append("package "); currentPackage.print(0, output, false).append(";\n"); } 265 if (imports != null) 266 for (int i = 0; i < imports.length; i++) { 267 printIndent(indent, output).append("import "); ImportReference currentImport = imports[i]; 269 if (currentImport.isStatic()) { 270 output.append("static "); } 272 currentImport.print(0, output).append(";\n"); } 274 275 if (types != null) { 276 for (int i = 0; i < types.length; i++) { 277 types[i].print(indent, output).append("\n"); } 279 } 280 return output; 281 } 282 283 286 public void propagateInnerEmulationForAllLocalTypes() { 287 288 isPropagatingInnerClassEmulation = true; 289 for (int i = 0, max = this.localTypeCount; i < max; i++) { 290 291 LocalTypeBinding localType = localTypes[i]; 292 if ((localType.scope.referenceType().bits & IsReachable) != 0) { 294 localType.updateInnerEmulationDependents(); 295 } 296 } 297 } 298 299 public void recordStringLiteral(StringLiteral literal) { 300 if (this.stringLiterals == null) { 301 this.stringLiterals = new StringLiteral[STRING_LITERALS_INCREMENT]; 302 this.stringLiteralsPtr = 0; 303 } else { 304 int stackLength = this.stringLiterals.length; 305 if (this.stringLiteralsPtr == stackLength) { 306 System.arraycopy( 307 this.stringLiterals, 308 0, 309 this.stringLiterals = new StringLiteral[stackLength + STRING_LITERALS_INCREMENT], 310 0, 311 stackLength); 312 } 313 } 314 this.stringLiterals[this.stringLiteralsPtr++] = literal; 315 } 316 317 321 public void record(LocalTypeBinding localType) { 322 323 if (this.localTypeCount == 0) { 324 this.localTypes = new LocalTypeBinding[5]; 325 } else if (this.localTypeCount == this.localTypes.length) { 326 System.arraycopy(this.localTypes, 0, (this.localTypes = new LocalTypeBinding[this.localTypeCount * 2]), 0, this.localTypeCount); 327 } 328 this.localTypes[this.localTypeCount++] = localType; 329 } 330 331 public void resolve() { 332 int startingTypeIndex = 0; 333 boolean isPackageInfo = isPackageInfo(); 334 if (this.types != null && isPackageInfo) { 335 final TypeDeclaration syntheticTypeDeclaration = types[0]; 337 if (syntheticTypeDeclaration.javadoc == null) { 339 syntheticTypeDeclaration.javadoc = new Javadoc(syntheticTypeDeclaration.declarationSourceStart, syntheticTypeDeclaration.declarationSourceStart); 340 } 341 syntheticTypeDeclaration.resolve(this.scope); 342 if (this.currentPackage!= null && this.currentPackage.annotations != null) { 344 resolveAnnotations(syntheticTypeDeclaration.staticInitializerScope, this.currentPackage.annotations, this.scope.fPackage); 345 } 346 350 if (this.javadoc != null) { 351 this.javadoc.resolve(syntheticTypeDeclaration.staticInitializerScope); 352 } 353 startingTypeIndex = 1; 354 } else { 355 if (this.javadoc != null) { 357 this.javadoc.resolve(this.scope); 358 } 359 } 360 if (this.currentPackage != null && this.currentPackage.annotations != null && !isPackageInfo) { 361 scope.problemReporter().invalidFileNameForPackageAnnotations(this.currentPackage.annotations[0]); 362 } 363 try { 364 if (types != null) { 365 for (int i = startingTypeIndex, count = types.length; i < count; i++) { 366 types[i].resolve(scope); 367 } 368 } 369 if (!this.compilationResult.hasErrors()) checkUnusedImports(); 370 reportNLSProblems(); 371 } catch (AbortCompilationUnit e) { 372 this.ignoreFurtherInvestigation = true; 373 return; 374 } 375 } 376 377 private void reportNLSProblems() { 378 if (this.nlsTags != null || this.stringLiterals != null) { 379 final int stringLiteralsLength = this.stringLiteralsPtr; 380 final int nlsTagsLength = this.nlsTags == null ? 0 : this.nlsTags.length; 381 if (stringLiteralsLength == 0) { 382 if (nlsTagsLength != 0) { 383 for (int i = 0; i < nlsTagsLength; i++) { 384 NLSTag tag = this.nlsTags[i]; 385 if (tag != null) { 386 scope.problemReporter().unnecessaryNLSTags(tag.start, tag.end); 387 } 388 } 389 } 390 } else if (nlsTagsLength == 0) { 391 if (this.stringLiterals.length != stringLiteralsLength) { 393 System.arraycopy(this.stringLiterals, 0, (stringLiterals = new StringLiteral[stringLiteralsLength]), 0, stringLiteralsLength); 394 } 395 Arrays.sort(this.stringLiterals, STRING_LITERAL_COMPARATOR); 396 for (int i = 0; i < stringLiteralsLength; i++) { 397 scope.problemReporter().nonExternalizedStringLiteral(this.stringLiterals[i]); 398 } 399 } else { 400 if (this.stringLiterals.length != stringLiteralsLength) { 402 System.arraycopy(this.stringLiterals, 0, (stringLiterals = new StringLiteral[stringLiteralsLength]), 0, stringLiteralsLength); 403 } 404 Arrays.sort(this.stringLiterals, STRING_LITERAL_COMPARATOR); 405 int indexInLine = 1; 406 int lastLineNumber = -1; 407 StringLiteral literal = null; 408 int index = 0; 409 int i = 0; 410 stringLiteralsLoop: for (; i < stringLiteralsLength; i++) { 411 literal = this.stringLiterals[i]; 412 final int literalLineNumber = literal.lineNumber; 413 if (lastLineNumber != literalLineNumber) { 414 indexInLine = 1; 415 lastLineNumber = literalLineNumber; 416 } else { 417 indexInLine++; 418 } 419 if (index < nlsTagsLength) { 420 nlsTagsLoop: for (; index < nlsTagsLength; index++) { 421 NLSTag tag = this.nlsTags[index]; 422 if (tag == null) continue nlsTagsLoop; 423 int tagLineNumber = tag.lineNumber; 424 if (literalLineNumber < tagLineNumber) { 425 scope.problemReporter().nonExternalizedStringLiteral(literal); 426 continue stringLiteralsLoop; 427 } else if (literalLineNumber == tagLineNumber) { 428 if (tag.index == indexInLine) { 429 this.nlsTags[index] = null; 430 index++; 431 continue stringLiteralsLoop; 432 } else { 433 nlsTagsLoop2: for (int index2 = index + 1; index2 < nlsTagsLength; index2++) { 434 NLSTag tag2 = this.nlsTags[index2]; 435 if (tag2 == null) continue nlsTagsLoop2; 436 int tagLineNumber2 = tag2.lineNumber; 437 if (literalLineNumber == tagLineNumber2) { 438 if (tag2.index == indexInLine) { 439 this.nlsTags[index2] = null; 440 continue stringLiteralsLoop; 441 } else { 442 continue nlsTagsLoop2; 443 } 444 } else { 445 scope.problemReporter().nonExternalizedStringLiteral(literal); 446 continue stringLiteralsLoop; 447 } 448 } 449 scope.problemReporter().nonExternalizedStringLiteral(literal); 450 continue stringLiteralsLoop; 451 } 452 } else { 453 scope.problemReporter().unnecessaryNLSTags(tag.start, tag.end); 454 continue nlsTagsLoop; 455 } 456 } 457 } 458 break stringLiteralsLoop; 460 } 461 for (; i < stringLiteralsLength; i++) { 462 scope.problemReporter().nonExternalizedStringLiteral(this.stringLiterals[i]); 463 } 464 if (index < nlsTagsLength) { 465 for (; index < nlsTagsLength; index++) { 466 NLSTag tag = this.nlsTags[index]; 467 if (tag != null) { 468 scope.problemReporter().unnecessaryNLSTags(tag.start, tag.end); 469 } 470 } 471 } 472 } 473 } 474 } 475 476 public void tagAsHavingErrors() { 477 ignoreFurtherInvestigation = true; 478 } 479 480 public void traverse( 481 ASTVisitor visitor, 482 CompilationUnitScope unitScope) { 483 484 if (ignoreFurtherInvestigation) 485 return; 486 try { 487 if (visitor.visit(this, this.scope)) { 488 if (this.types != null && isPackageInfo()) { 489 final TypeDeclaration syntheticTypeDeclaration = types[0]; 491 final MethodScope methodScope = syntheticTypeDeclaration.staticInitializerScope; 493 if (this.javadoc != null) { 494 this.javadoc.traverse(visitor, methodScope); 495 } 496 if (this.currentPackage != null) { 497 final Annotation[] annotations = this.currentPackage.annotations; 498 if (annotations != null) { 499 int annotationsLength = annotations.length; 500 for (int i = 0; i < annotationsLength; i++) { 501 annotations[i].traverse(visitor, methodScope); 502 } 503 } 504 } 505 } 506 if (this.currentPackage != null) { 507 this.currentPackage.traverse(visitor, this.scope); 508 } 509 if (imports != null) { 510 int importLength = imports.length; 511 for (int i = 0; i < importLength; i++) { 512 imports[i].traverse(visitor, this.scope); 513 } 514 } 515 if (types != null) { 516 int typesLength = types.length; 517 for (int i = 0; i < typesLength; i++) { 518 types[i].traverse(visitor, this.scope); 519 } 520 } 521 } 522 visitor.endVisit(this, this.scope); 523 } catch (AbortCompilationUnit e) { 524 } 526 } 527 } 528 | Popular Tags |