11/*******************************************************************************
2- * Copyright (c) 2000,2008 IBM Corporation and others.
2+ * Copyright (c) 2000,2013 IBM Corporation and others.
33 * All rights reserved. This program and the accompanying materials
44 * are made available under the terms of the Eclipse Public License v1.0
55 * which accompanies this distribution, and is available at
2525import org .eclipse .jdt .internal .compiler .util .SimpleSet ;
2626import org .eclipse .jdt .internal .compiler .util .SuffixConstants ;
2727import org .eclipse .jdt .internal .core .JavaModelManager ;
28+ import org .eclipse .jdt .internal .core .PackageFragment ;
2829import org .eclipse .jdt .internal .core .util .Messages ;
2930import org .eclipse .jdt .internal .core .util .Util ;
3031
@@ -56,7 +57,8 @@ public abstract class AbstractImageBuilder implements ICompilerRequestor, ICompi
5657protected boolean keepStoringProblemMarkers ;
5758protected SimpleSet filesWithAnnotations =null ;
5859
59- public static int MAX_AT_ONCE =2000 ;// best compromise between space used and speed
60+ //2000 is best compromise between space used and speed
61+ public static int MAX_AT_ONCE =Integer .getInteger (JavaModelManager .MAX_COMPILED_UNITS_AT_ONCE ,2000 ).intValue ();
6062public final static String []JAVA_PROBLEM_MARKER_ATTRIBUTE_NAMES = {
6163IMarker .MESSAGE ,
6264IMarker .SEVERITY ,
@@ -292,7 +294,7 @@ protected void compile(SourceFile[] units) {
292294}
293295
294296int unitsLength =units .length ;
295- this .compiledAllAtOnce =unitsLength <=MAX_AT_ONCE ;
297+ this .compiledAllAtOnce =MAX_AT_ONCE == 0 || unitsLength <=MAX_AT_ONCE ;
296298if (this .compiledAllAtOnce ) {
297299// do them all now
298300if (JavaBuilder .DEBUG )
@@ -671,12 +673,14 @@ protected void storeProblemsFor(SourceFile sourceFile, CategorizedProblem[] prob
671673// but still try to compile as many source files as possible to help the case when the base libraries are in source
672674if (!this .keepStoringProblemMarkers )return ;// only want the one error recorded on this source file
673675
674- IResource resource =sourceFile .resource ;
675676HashSet managedMarkerTypes =JavaModelManager .getJavaModelManager ().compilationParticipants .managedMarkerTypes ();
676- for (int i =0 ,l =problems .length ;i <l ;i ++) {
677+ problems : for (int i =0 ,l =problems .length ;i <l ;i ++) {
677678CategorizedProblem problem =problems [i ];
678679int id =problem .getID ();
679-
680+ // we may use a different resource for certain problems such as IProblem.MissingNonNullByDefaultAnnotationOnPackage
681+ // but at the start of the next problem we should reset it to the source file's resource
682+ IResource resource =sourceFile .resource ;
683+
680684// handle missing classfile situation
681685if (id ==IProblem .IsClassPathCorrect ) {
682686String missingClassfileName =problem .getArguments ()[0 ];
@@ -706,6 +710,38 @@ protected void storeProblemsFor(SourceFile sourceFile, CategorizedProblem[] prob
706710boolean managedProblem =false ;
707711if (IJavaModelMarker .JAVA_MODEL_PROBLEM_MARKER .equals (markerType )
708712|| (managedProblem =managedMarkerTypes .contains (markerType ))) {
713+ if (id ==IProblem .MissingNonNullByDefaultAnnotationOnPackage && !(CharOperation .equals (sourceFile .getMainTypeName (),TypeConstants .PACKAGE_INFO_NAME ))) {
714+ // for this kind of problem, marker needs to be created on the package instead of on the source file
715+ // see bug 372012
716+ char []fileName =sourceFile .getFileName ();
717+ int pkgEnd =CharOperation .lastIndexOf ('/' ,fileName );
718+ if (pkgEnd == -1 )
719+ pkgEnd =CharOperation .lastIndexOf (File .separatorChar ,fileName );
720+ PackageFragment pkg =null ;
721+ if (pkgEnd != -1 )
722+ pkg = (PackageFragment )Util .getPackageFragment (sourceFile .getFileName (),pkgEnd , -1 /*no jar separator for java files*/ );
723+
724+ if (pkg !=null ) {
725+ try {
726+ IMarker []existingMarkers =pkg .resource ().findMarkers (IJavaModelMarker .JAVA_MODEL_PROBLEM_MARKER ,false ,IResource .DEPTH_ZERO );
727+ int len =existingMarkers .length ;
728+ for (int j =0 ;j <len ;j ++) {
729+ if (((Integer )existingMarkers [j ].getAttribute (IJavaModelMarker .ID )).intValue () ==IProblem .MissingNonNullByDefaultAnnotationOnPackage ) {
730+ continue problems ;// marker already present
731+ }
732+ }
733+ }catch (CoreException e ) {
734+ // marker retrieval failed, cannot do much
735+ if (JavaModelManager .VERBOSE ) {
736+ e .printStackTrace ();
737+ }
738+ }
739+ IResource tempRes =pkg .resource ();
740+ if (tempRes !=null ) {
741+ resource =tempRes ;
742+ }
743+ }
744+ }
709745IMarker marker =resource .createMarker (markerType );
710746
711747String []attributeNames =JAVA_PROBLEM_MARKER_ATTRIBUTE_NAMES ;
@@ -729,8 +765,7 @@ protected void storeProblemsFor(SourceFile sourceFile, CategorizedProblem[] prob
729765allValues [index ++] =problem .isError () ?S_ERROR :S_WARNING ;// severity
730766allValues [index ++] =new Integer (id );// ID
731767allValues [index ++] =new Integer (problem .getSourceStart ());// start
732- int end =problem .getSourceEnd ();
733- allValues [index ++] =new Integer (end >0 ?end +1 :end );// end
768+ allValues [index ++] =new Integer (problem .getSourceEnd () +1 );// end
734769allValues [index ++] =new Integer (problem .getSourceLineNumber ());// line
735770allValues [index ++] =Util .getProblemArgumentsForMarker (problem .getArguments ());// arguments
736771allValues [index ++] =new Integer (problem .getCategoryID ());// category ID
@@ -835,7 +870,7 @@ protected void writeClassFileContents(ClassFile classFile, IFile file, String qu
835870if (JavaBuilder .DEBUG )
836871System .out .println ("Writing changed class file " +file .getName ());//$NON-NLS-1$
837872if (!file .isDerived ())
838- file .setDerived (true );
873+ file .setDerived (true , null );
839874file .setContents (input ,true ,false ,null );
840875}else {
841876// Default implementation just writes out the bytes for the new class file...