1 11 12 13 package org.eclipse.jdt.apt.core.internal; 14 15 import java.util.ArrayList ; 16 import java.util.Collection ; 17 import java.util.Collections ; 18 import java.util.HashMap ; 19 import java.util.HashSet ; 20 import java.util.Iterator ; 21 import java.util.LinkedHashSet ; 22 import java.util.List ; 23 import java.util.Map ; 24 import java.util.Set ; 25 26 import org.eclipse.core.resources.IFile; 27 import org.eclipse.core.resources.IWorkspace; 28 import org.eclipse.core.resources.IWorkspaceRunnable; 29 import org.eclipse.core.resources.ResourcesPlugin; 30 import org.eclipse.core.runtime.CoreException; 31 import org.eclipse.core.runtime.IProgressMonitor; 32 import org.eclipse.jdt.apt.core.env.Phase; 33 import org.eclipse.jdt.apt.core.internal.env.AbstractCompilationEnv; 34 import org.eclipse.jdt.apt.core.internal.env.BuildEnv; 35 import org.eclipse.jdt.apt.core.internal.env.EclipseRoundCompleteEvent; 36 import org.eclipse.jdt.apt.core.internal.env.ReconcileEnv; 37 import org.eclipse.jdt.apt.core.internal.env.AbstractCompilationEnv.EnvCallback; 38 import org.eclipse.jdt.apt.core.internal.generatedfile.GeneratedFileManager; 39 import org.eclipse.jdt.apt.core.internal.util.FactoryPath; 40 import org.eclipse.jdt.core.ICompilationUnit; 41 import org.eclipse.jdt.core.IJavaProject; 42 import org.eclipse.jdt.core.compiler.BuildContext; 43 import org.eclipse.jdt.core.compiler.CategorizedProblem; 44 import org.eclipse.jdt.core.compiler.ReconcileContext; 45 46 import com.sun.mirror.apt.AnnotationProcessor; 47 import com.sun.mirror.apt.AnnotationProcessorFactory; 48 import com.sun.mirror.apt.AnnotationProcessorListener; 49 import com.sun.mirror.apt.RoundCompleteListener; 50 import com.sun.mirror.declaration.AnnotationTypeDeclaration; 51 52 public class APTDispatchRunnable implements IWorkspaceRunnable 53 { 54 60 private final class ReconcileEnvCallback implements EnvCallback { 61 private final ReconcileContext _context; 62 private final GeneratedFileManager _gfm; 63 64 private ReconcileEnvCallback(ReconcileContext context, 65 GeneratedFileManager gfm) { 66 _context = context; 67 _gfm = gfm; 68 } 69 70 public void run(AbstractCompilationEnv env) { 71 ReconcileEnv reconcileEnv = (ReconcileEnv)env; 73 74 try { 76 dispatchToFileBasedProcessor(reconcileEnv); 77 } catch (Throwable t) { 78 AptPlugin.log(t, "Processor failure during reconcile"); } 80 81 ICompilationUnit parentWC = _context.getWorkingCopy(); 86 Set <IFile> newlyGeneratedFiles = reconcileEnv.getAllGeneratedFiles(); 87 _gfm.deleteObsoleteTypesAfterReconcile(parentWC, newlyGeneratedFiles); 88 89 final List <? extends CategorizedProblem> problemList = reconcileEnv.getProblems(); 91 final int numProblems = problemList.size(); 92 if (numProblems > 0) { 93 final CategorizedProblem[] aptCatProblems = new CategorizedProblem[numProblems]; 94 _context.putProblems( 95 AptPlugin.APT_COMPILATION_PROBLEM_MARKER, problemList 96 .toArray(aptCatProblems)); 97 } 98 99 reconcileEnv.close(); 102 } 103 } 104 105 private static final BuildContext[] NO_FILES_TO_PROCESS = new BuildContext[0]; 106 private BuildContext[] _filesWithAnnotation = null; 107 private BuildContext[] _filesWithoutAnnotation = null; 108 private Map <IFile, CategorizedProblem[]> _problemRecorder = null; 109 private final AptProject _aptProject; 110 private final Map <AnnotationProcessorFactory, FactoryPath.Attributes> _factories; 111 112 private final Set <AnnotationProcessorFactory> _dispatchedBatchFactories; 113 114 private Set <AnnotationProcessorFactory> _currentDispatchBatchFactories = Collections.emptySet(); 115 private final boolean _isFullBuild; 116 117 118 public static Set <AnnotationProcessorFactory> runAPTDuringBuild( 119 BuildContext[] filesWithAnnotations, 120 BuildContext[] filesWithoutAnnotations, 121 Map <IFile, CategorizedProblem[]> problemRecorder, 122 AptProject aptProject, 123 Map <AnnotationProcessorFactory, FactoryPath.Attributes> factories, 124 Set <AnnotationProcessorFactory> dispatchedBatchFactories, 125 boolean isFullBuild){ 126 127 if( filesWithAnnotations == null ){ 128 filesWithAnnotations = NO_FILES_TO_PROCESS; 129 } 130 APTDispatchRunnable runnable = 133 new APTDispatchRunnable( 134 filesWithAnnotations, 135 filesWithoutAnnotations, 136 problemRecorder, 137 aptProject, factories, 138 dispatchedBatchFactories, isFullBuild ); 139 IWorkspace workspace = ResourcesPlugin.getWorkspace(); 140 try { 141 workspace.run(runnable, aptProject.getJavaProject().getResource(), IWorkspace.AVOID_UPDATE, null); 142 } 143 catch (CoreException ce) { 144 AptPlugin.log(ce, "Could not run APT"); } 146 return runnable._currentDispatchBatchFactories; 147 } 148 149 public static void runAPTDuringReconcile( 150 ReconcileContext reconcileContext, 151 AptProject aptProject, 152 Map <AnnotationProcessorFactory, FactoryPath.Attributes> factories) 153 { 154 APTDispatchRunnable runnable = new APTDispatchRunnable( aptProject, factories ); 158 runnable.reconcile(reconcileContext, aptProject.getJavaProject()); 159 } 160 161 162 private APTDispatchRunnable( 163 BuildContext[] filesWithAnnotation, 164 BuildContext[] filesWithoutAnnotation, 165 Map <IFile, CategorizedProblem[]> problemRecorder, 166 AptProject aptProject, 167 Map <AnnotationProcessorFactory, FactoryPath.Attributes> factories, 168 Set <AnnotationProcessorFactory> dispatchedBatchFactories, 169 boolean isFullBuild) 170 { 171 assert filesWithAnnotation != null : "missing files"; _filesWithAnnotation = filesWithAnnotation; 173 _filesWithoutAnnotation = filesWithoutAnnotation; 174 _problemRecorder = problemRecorder; 175 _aptProject = aptProject; 176 _factories = factories; 177 _dispatchedBatchFactories = dispatchedBatchFactories; 178 _isFullBuild = isFullBuild; 179 } 180 181 private APTDispatchRunnable( 182 AptProject aptProject, 183 Map <AnnotationProcessorFactory, FactoryPath.Attributes> factories) 184 { 185 _aptProject = aptProject; 186 _factories = factories; 187 _isFullBuild = false; 188 _dispatchedBatchFactories = Collections.emptySet(); 191 } 192 193 private void reconcile(final ReconcileContext reconcileContext, 194 IJavaProject javaProject) 195 { 196 if (_factories.size() == 0) { 197 if (AptPlugin.DEBUG) 198 trace("apt leaving project " + javaProject.getProject() + " early because there are no factories", null); 201 return; 203 } 204 205 GeneratedFileManager gfm = _aptProject.getGeneratedFileManager(); 208 gfm.reconcileStarted(); 209 EnvCallback callback = new ReconcileEnvCallback(reconcileContext, gfm); 210 AbstractCompilationEnv.newReconcileEnv(reconcileContext, callback); 211 212 } 213 214 public void run(IProgressMonitor monitor) 215 { 216 build(); 217 } 218 219 228 private boolean shouldBuild() 229 { 230 if( (_factories == null || _factories.size() == 0) && _dispatchedBatchFactories.isEmpty() ) 231 return false; 232 233 int totalFiles = _filesWithAnnotation == null ? 0 : _filesWithAnnotation.length; 234 return totalFiles > 0 || !_dispatchedBatchFactories.isEmpty(); 237 } 238 239 private void build(){ 240 241 if ( !shouldBuild() ) 242 { 243 if ( AptPlugin.DEBUG ) 245 { 246 String msg; 247 if ( (_factories == null || _factories.size() == 0) && _dispatchedBatchFactories.isEmpty() ) 248 msg = "no AnnotationProcessoryFactory instances registered."; else 250 msg = "no files to dispatch to."; trace( "run(): leaving project " + _aptProject.getJavaProject().getProject() + " early because there are " + msg, null); 254 } 255 cleanupAllGeneratedFiles(); 256 } 257 else 258 { 259 assert _filesWithAnnotation != null : 260 "should never be invoked unless we are in build mode!"; 262 EnvCallback buildCallback = new EnvCallback() { 263 public void run(AbstractCompilationEnv env) { 264 build((BuildEnv)env); 265 } 266 }; 267 268 BuildEnv.newBuildEnv( 271 _filesWithAnnotation, 272 _filesWithoutAnnotation, 273 _aptProject.getJavaProject(), 274 buildCallback); 275 } 276 } 277 278 282 private boolean hasBatchFactory() 283 { 284 for( FactoryPath.Attributes attr : _factories.values() ){ 285 if( attr.runInBatchMode() ) 286 return true; 287 } 288 return false; 289 290 } 291 292 300 private boolean shouldDispatchToBatchProcessor(final AbstractCompilationEnv processorEnv ) 301 { 302 return ( _isFullBuild && processorEnv.getPhase() == Phase.BUILD && hasBatchFactory() ); 303 } 304 305 private void runAPTInFileBasedMode(final BuildEnv processorEnv) 306 { 307 final BuildContext[] cpResults = processorEnv.getFilesWithAnnotation(); 308 final GeneratedFileManager gfm = _aptProject.getGeneratedFileManager(); 309 for (BuildContext curResult : cpResults ) { 310 processorEnv.beginFileProcessing(curResult); 311 dispatchToFileBasedProcessor(processorEnv); 312 reportResult( 313 curResult, 314 processorEnv.getAllGeneratedFiles(), 315 processorEnv.getModifiedGeneratedFiles(), 316 processorEnv.getProblems(), 317 processorEnv.getTypeDependencies(), 318 gfm, 319 processorEnv); 320 processorEnv.completedFileProcessing(); 321 } 322 } 323 324 335 private void reportResult( 336 BuildContext curResult, 337 Set <IFile> java5GeneratedFiles, 338 Set <IFile> modifiedGeneratedFiles, 339 List <? extends CategorizedProblem> problems, 340 Set <String > deps, 341 GeneratedFileManager gfm, 342 BuildEnv processorEnv) 343 { 344 Set <IFile> allGeneratedFiles = null; 346 Set <IFile> java6GeneratedFiles = AptCompilationParticipant.getInstance().getJava6GeneratedFiles(); 347 if (java5GeneratedFiles == null || java5GeneratedFiles.isEmpty()) { 348 if (java6GeneratedFiles.isEmpty()) { 349 allGeneratedFiles = Collections.emptySet(); 350 } 351 else { 352 allGeneratedFiles = java6GeneratedFiles; 353 } 354 } 355 else { 356 if (java6GeneratedFiles.isEmpty()) { 357 allGeneratedFiles = java5GeneratedFiles; 358 } 359 else { 360 allGeneratedFiles = new HashSet <IFile>(java6GeneratedFiles); 361 allGeneratedFiles.addAll(java5GeneratedFiles); 362 } 363 } 364 365 final List <IFile> deletedFiles = new ArrayList <IFile>(); 367 IFile parentFile = curResult.getFile(); 368 cleanupNoLongerGeneratedFiles( 369 parentFile, 370 allGeneratedFiles, 371 gfm, 372 processorEnv, 373 deletedFiles); 374 int numNewFiles = modifiedGeneratedFiles.size(); 376 if( numNewFiles > 0 ){ 377 final IFile[] newFilesArray = new IFile[numNewFiles]; 378 curResult.recordAddedGeneratedFiles(modifiedGeneratedFiles.toArray(newFilesArray)); 379 } 380 381 int numDeletedFiles = deletedFiles.size(); 383 if(numDeletedFiles > 0){ 384 final IFile[] deletedFilesArray = new IFile[numDeletedFiles]; 385 curResult.recordDeletedGeneratedFiles(deletedFiles.toArray(deletedFilesArray)); 386 } 387 388 final int numProblems = problems.size(); 390 if( numProblems > 0 ){ 391 final CategorizedProblem[] catProblemsArray = new CategorizedProblem[numProblems]; 392 curResult.recordNewProblems(problems.toArray(catProblemsArray)); 393 _problemRecorder.put(curResult.getFile(), catProblemsArray); 396 } 397 398 final int numDeps = deps.size(); 400 if( numDeps > 0 ){ 401 final String [] depsArray = new String [numDeps]; 402 curResult.recordDependencies(deps.toArray(depsArray)); 403 } 404 } 405 406 407 413 private void runAPTInMixedMode(final BuildEnv processorEnv) 414 { 415 final BuildContext[] cpResults = processorEnv.getFilesWithAnnotation(); 416 final Map <BuildContext, Set <AnnotationTypeDeclaration>> file2AnnotationDecls = 417 new HashMap <BuildContext, Set <AnnotationTypeDeclaration>>(cpResults.length * 4/3 + 1); 418 final Map <String , AnnotationTypeDeclaration> annotationDecls = 419 processorEnv.getAllAnnotationTypes(file2AnnotationDecls); 420 421 if (annotationDecls.isEmpty() && _dispatchedBatchFactories.isEmpty() ) 422 { 423 if ( AptPlugin.DEBUG ) 424 trace( "runAPT: leaving early because annotationDecls is empty", processorEnv); 426 return; 427 } 428 429 if( AptPlugin.DEBUG ) 430 trace( "annotations found " + annotationDecls.keySet(), processorEnv); 432 final Map <AnnotationProcessorFactory, Set <AnnotationTypeDeclaration>> fileFactory2Annos = 434 new HashMap <AnnotationProcessorFactory, Set <AnnotationTypeDeclaration>>( _factories.size() * 4/3 + 1 ); 435 436 final Map <AnnotationProcessorFactory, Set <AnnotationTypeDeclaration>> batchFactory2Annos = 438 new HashMap <AnnotationProcessorFactory, Set <AnnotationTypeDeclaration>>( _factories.size() * 4/3 + 1 ); 439 440 for( Map.Entry <AnnotationProcessorFactory, FactoryPath.Attributes> entry : _factories.entrySet() ){ 441 AnnotationProcessorFactory factory = entry.getKey(); 442 Set <AnnotationTypeDeclaration> annotationTypes = getFactorySupportedAnnotations(factory, annotationDecls); 443 if( annotationTypes != null ){ 444 445 boolean batch = entry.getValue().runInBatchMode(); 446 Map <AnnotationProcessorFactory, Set <AnnotationTypeDeclaration> > factory2Annos = 447 batch ? batchFactory2Annos : fileFactory2Annos; 448 if( annotationTypes.size() == 0 ){ 449 annotationTypes = new HashSet <AnnotationTypeDeclaration>(annotationDecls.values()); 451 factory2Annos.put(factory, annotationTypes); 452 annotationDecls.clear(); 453 break; 454 } 455 else{ 456 factory2Annos.put(factory, annotationTypes); 457 } 458 } 459 if( annotationDecls.isEmpty() ) 460 break; 461 } 462 463 if( ! annotationDecls.isEmpty() ){ 464 } 466 467 if( !batchFactory2Annos.isEmpty() || 470 (_dispatchedBatchFactories != null && !_dispatchedBatchFactories.isEmpty()) ){ 471 472 processorEnv.beginBatchProcessing(); 473 if( !batchFactory2Annos.isEmpty()){ 474 _currentDispatchBatchFactories = new LinkedHashSet <AnnotationProcessorFactory>(); 479 for(AnnotationProcessorFactory factory : _factories.keySet() ){ 480 final Set <AnnotationTypeDeclaration> annotationTypes = batchFactory2Annos.get(factory); 481 if( annotationTypes == null ) continue; 482 final AnnotationProcessor processor = 483 factory.getProcessorFor(annotationTypes, processorEnv); 484 if( processor != null ){ 485 if ( AptPlugin.DEBUG ) 486 trace( "runAPT: invoking batch processor " + processor.getClass().getName(), processorEnv); 488 _currentDispatchBatchFactories.add(factory); 489 processorEnv.setCurrentProcessorFactory(factory); 490 processor.process(); 491 processorEnv.setCurrentProcessorFactory(null); 492 } 493 } 494 } 495 for( AnnotationProcessorFactory prevRoundFactory : _dispatchedBatchFactories ){ 498 if(_currentDispatchBatchFactories.contains(prevRoundFactory)) 499 continue; 500 final AnnotationProcessor processor = 501 prevRoundFactory.getProcessorFor(Collections.<AnnotationTypeDeclaration>emptySet(), processorEnv); 502 if( processor != null ){ 503 if ( AptPlugin.DEBUG ) 504 trace( "runAPT: invoking batch processor " + processor.getClass().getName(), processorEnv); 506 processorEnv.setCurrentProcessorFactory(prevRoundFactory); 507 processor.process(); 508 processorEnv.setCurrentProcessorFactory(null); 509 } 510 } 511 512 BuildContext firstResult = null; 521 if( cpResults.length > 0 ) 522 firstResult = cpResults[0]; 523 else{ 524 final BuildContext[] others = processorEnv.getFilesWithoutAnnotation(); 525 if(others != null && others.length > 0 ) 526 firstResult = others[0]; 527 } 528 529 assert firstResult != null : "don't know where to report results"; if(firstResult != null ){ 532 final GeneratedFileManager gfm = _aptProject.getGeneratedFileManager(); 533 reportResult( 534 firstResult, processorEnv.getAllGeneratedFiles(), 536 processorEnv.getModifiedGeneratedFiles(), 537 processorEnv.getProblems(), processorEnv.getTypeDependencies(), gfm, 540 processorEnv); 541 } 542 processorEnv.completedBatchProcessing(); 543 } 544 545 if( !fileFactory2Annos.isEmpty() ){ 547 for(BuildContext curResult : cpResults ){ 548 final Set <AnnotationTypeDeclaration> annotationTypesInFile = file2AnnotationDecls.get(curResult); 549 if( annotationTypesInFile == null || annotationTypesInFile.isEmpty() ) 550 continue; 551 for(AnnotationProcessorFactory factory : _factories.keySet() ){ 552 final Set <AnnotationTypeDeclaration> annotationTypesForFactory = fileFactory2Annos.get(factory); 553 if( annotationTypesForFactory == null || annotationTypesForFactory.isEmpty() ) 554 continue; 555 final Set <AnnotationTypeDeclaration> intersect = setIntersect(annotationTypesInFile, annotationTypesForFactory); 556 if( intersect != null && !intersect.isEmpty() ){ 557 processorEnv.beginFileProcessing(curResult); 558 final AnnotationProcessor processor = 559 factory.getProcessorFor(intersect, processorEnv); 560 if( processor != null ){ 561 if ( AptPlugin.DEBUG ) 562 trace( "runAPT: invoking file-based processor " + processor.getClass().getName(), processorEnv ); 564 processorEnv.setCurrentProcessorFactory(factory); 565 processor.process(); 566 processorEnv.setCurrentProcessorFactory(null); 567 } 568 } 569 } 570 571 final GeneratedFileManager gfm = _aptProject.getGeneratedFileManager(); 572 reportResult( 573 curResult, 574 processorEnv.getAllGeneratedFiles(), 575 processorEnv.getModifiedGeneratedFiles(), 576 processorEnv.getProblems(), 577 processorEnv.getTypeDependencies(), 578 gfm, 579 processorEnv); 580 processorEnv.completedFileProcessing(); 581 } 582 } 583 } 584 585 private void dispatchToFileBasedProcessor( 586 final AbstractCompilationEnv processorEnv){ 587 588 Map <String , AnnotationTypeDeclaration> annotationDecls = processorEnv.getAnnotationTypes(); 589 for( Map.Entry <AnnotationProcessorFactory, FactoryPath.Attributes> entry : _factories.entrySet() ){ 590 if( entry.getValue().runInBatchMode() ) continue; 591 AnnotationProcessorFactory factory = entry.getKey(); 592 Set <AnnotationTypeDeclaration> factoryDecls = getFactorySupportedAnnotations(factory, annotationDecls); 593 if( factoryDecls != null ){ 594 if(factoryDecls.size() == 0 ){ 595 factoryDecls = new HashSet <AnnotationTypeDeclaration>(annotationDecls.values()); 596 annotationDecls.clear(); 597 } 598 } 599 if (factoryDecls != null && factoryDecls.size() > 0) { 600 final AnnotationProcessor processor = factory 601 .getProcessorFor(factoryDecls, processorEnv); 602 if (processor != null) 603 { 604 if ( AptPlugin.DEBUG ) { 605 trace( "runAPT: invoking file-based processor " + processor.getClass().getName() + " on " + processorEnv.getFile(), processorEnv); 607 } 608 processorEnv.setCurrentProcessorFactory(factory); 609 processor.process(); 610 processorEnv.setCurrentProcessorFactory(null); 611 } 612 } 613 614 if (annotationDecls.isEmpty()) 615 break; 616 } 617 if( ! annotationDecls.isEmpty() ){ 618 } 620 } 621 622 628 private Set <AnnotationProcessorFactory> build(final BuildEnv processorEnv) 629 { 630 try { 631 boolean mixedModeDispatch = shouldDispatchToBatchProcessor(processorEnv); 632 if( mixedModeDispatch ){ 633 runAPTInMixedMode(processorEnv); 634 } 635 else{ 636 runAPTInFileBasedMode(processorEnv); 637 } 638 639 final Set <AnnotationProcessorListener> listeners = processorEnv 641 .getProcessorListeners(); 642 EclipseRoundCompleteEvent event = null; 643 for (AnnotationProcessorListener listener : listeners) { 644 if (listener instanceof RoundCompleteListener) { 645 if (event == null) 646 event = new EclipseRoundCompleteEvent(processorEnv); 647 final RoundCompleteListener rcListener = (RoundCompleteListener) listener; 648 rcListener.roundComplete(event); 649 } 650 } 651 if( _filesWithoutAnnotation != null ){ 652 cleanupAllGeneratedFilesFrom(_filesWithoutAnnotation); 653 } 654 655 656 } 658 catch (Error t) { 659 if (t.getClass().getName().startsWith("junit.framework")) throw t; 663 AptPlugin.logWarning(t, "Unexpected failure running APT on the file(s): " + getFileNamesForPrinting(processorEnv)); } 665 catch (Throwable t) { 666 AptPlugin.logWarning(t, "Unexpected failure running APT on the file(s): " + getFileNamesForPrinting(processorEnv)); } 668 finally { 669 processorEnv.close(); 670 _aptProject.getGeneratedFileManager().writeState(); 671 } 672 673 return Collections.emptySet(); 674 } 675 676 681 private Set <AnnotationTypeDeclaration> setIntersect(Set <AnnotationTypeDeclaration> one, Set <AnnotationTypeDeclaration> two ){ 682 Set <AnnotationTypeDeclaration> intersect = null; 683 for( AnnotationTypeDeclaration obj : one ){ 684 if( two.contains(obj) ){ 685 if( intersect == null ) 686 intersect = new HashSet <AnnotationTypeDeclaration>(); 687 intersect.add(obj); 688 } 689 } 690 return intersect; 691 } 692 693 private void cleanupAllGeneratedFiles(){ 694 cleanupAllGeneratedFilesFrom(_filesWithAnnotation); 695 cleanupAllGeneratedFilesFrom(_filesWithoutAnnotation); 696 } 697 698 private void cleanupAllGeneratedFilesFrom(BuildContext[] cpResults){ 699 if (cpResults == null) { 700 return; 701 } 702 final Set <IFile> deleted = new HashSet <IFile>(); 703 GeneratedFileManager gfm = _aptProject.getGeneratedFileManager(); 704 Set <IFile> java6GeneratedFiles = AptCompilationParticipant.getInstance().getJava6GeneratedFiles(); 705 for( BuildContext cpResult : cpResults){ 706 final IFile parentFile = cpResult.getFile(); 707 cleanupNoLongerGeneratedFiles( 708 parentFile, 709 java6GeneratedFiles, 710 gfm, 711 null, 712 deleted); 713 714 if( deleted.size() > 0 ){ 715 final IFile[] deletedFilesArray = new IFile[deleted.size()]; 716 cpResult.recordDeletedGeneratedFiles(deleted.toArray(deletedFilesArray)); 717 } 718 } 719 } 720 721 741 private void cleanupNoLongerGeneratedFiles( 742 IFile parentFile, 743 Set <IFile> newGeneratedFiles, 744 GeneratedFileManager gfm, 745 BuildEnv processorEnv, 746 Collection <IFile> deleted) 747 { 748 deleted.addAll(gfm.deleteObsoleteFilesAfterBuild(parentFile, newGeneratedFiles)); 749 } 750 751 759 private static Set <AnnotationTypeDeclaration> getFactorySupportedAnnotations( 760 final AnnotationProcessorFactory factory, 761 final Map <String , AnnotationTypeDeclaration> declarations) 762 763 { 764 final Collection <String > supportedTypes = factory 765 .supportedAnnotationTypes(); 766 767 if (supportedTypes == null || supportedTypes.size() == 0) 768 return Collections.emptySet(); 769 770 final Set <AnnotationTypeDeclaration> fDecls = new HashSet <AnnotationTypeDeclaration>(); 771 772 for (Iterator <String > it = supportedTypes.iterator(); it.hasNext();) { 773 final String typeName = it.next(); 774 if (typeName.equals("*")) { fDecls.addAll(declarations.values()); 776 declarations.clear(); 777 778 AptPlugin.logWarning(null, "Processor Factory " + factory + " claimed all annotations (*), which prevents any following factories from being dispatched."); 782 } else if (typeName.endsWith("*")) { final String prefix = typeName.substring(0, 784 typeName.length() - 2); 785 for (Iterator <Map.Entry <String , AnnotationTypeDeclaration>> entries = declarations 786 .entrySet().iterator(); entries.hasNext();) { 787 final Map.Entry <String , AnnotationTypeDeclaration> entry = entries 788 .next(); 789 final String key = entry.getKey(); 790 if (key.startsWith(prefix)) { 791 fDecls.add(entry.getValue()); 792 entries.remove(); 793 } 794 } 795 } else { 796 final AnnotationTypeDeclaration decl = declarations 797 .get(typeName); 798 if (decl != null) { 799 fDecls.add(decl); 800 declarations.remove(typeName); 801 } 802 } 803 } 804 return fDecls.isEmpty() ? null : fDecls; 805 } 806 807 private static void trace( String s, AbstractCompilationEnv processorEnv ) 808 { 809 if (AptPlugin.DEBUG) 810 { 811 if (processorEnv != null) { 812 s = "[ phase = " + processorEnv.getPhase() + ", file = " + getFileNamesForPrinting(processorEnv) +" ] " + s; } 814 AptPlugin.trace( s ); 815 } 816 } 817 818 private static String getFileNamesForPrinting(final AbstractCompilationEnv env){ 819 if( env instanceof ReconcileEnv ){ 820 return env.getFile().getName(); 821 } 822 else{ 823 return getFileNamesForPrinting((BuildEnv)env); 824 } 825 } 826 827 831 private static String getFileNamesForPrinting(final BuildEnv processorEnv){ 832 final IFile file = processorEnv.getFile(); 833 if( file != null ) 834 return file.getName(); 835 final BuildContext[] results = processorEnv.getFilesWithAnnotation(); 836 final int len = results.length; 837 switch( len ) 838 { 839 case 0: 840 return "no file(s)"; case 1: 842 return results[0].getFile().getName(); 843 default: 844 StringBuilder sb = new StringBuilder (); 845 boolean firstItem = true; 846 for (BuildContext curResult : results) { 847 if (firstItem) { 848 firstItem = false; 849 } 850 else { 851 sb.append(", "); } 853 sb.append(curResult.getFile().getName()); 854 } 855 return sb.toString(); 856 } 857 } 858 } 859 | Popular Tags |