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 = {
6163 IMarker .MESSAGE ,
6264 IMarker .SEVERITY ,
@@ -292,7 +294,7 @@ protected void compile(SourceFile[] units) {
292294 }
293295
294296 int unitsLength = units .length ;
295- this .compiledAllAtOnce = unitsLength <= MAX_AT_ONCE ;
297+ this .compiledAllAtOnce = MAX_AT_ONCE == 0 || unitsLength <= MAX_AT_ONCE ;
296298 if (this .compiledAllAtOnce ) {
297299 // do them all now
298300 if (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
672674 if (!this .keepStoringProblemMarkers ) return ; // only want the one error recorded on this source file
673675
674- IResource resource = sourceFile .resource ;
675676 HashSet 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 ++) {
677678 CategorizedProblem problem = problems [i ];
678679 int 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
681685 if (id == IProblem .IsClassPathCorrect ) {
682686 String missingClassfileName = problem .getArguments ()[0 ];
@@ -706,6 +710,38 @@ protected void storeProblemsFor(SourceFile sourceFile, CategorizedProblem[] prob
706710 boolean managedProblem = false ;
707711 if (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+ }
709745 IMarker marker = resource .createMarker (markerType );
710746
711747 String [] attributeNames = JAVA_PROBLEM_MARKER_ATTRIBUTE_NAMES ;
@@ -729,8 +765,7 @@ protected void storeProblemsFor(SourceFile sourceFile, CategorizedProblem[] prob
729765 allValues [index ++] = problem .isError () ? S_ERROR : S_WARNING ; // severity
730766 allValues [index ++] = new Integer (id ); // ID
731767 allValues [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
734769 allValues [index ++] = new Integer (problem .getSourceLineNumber ()); // line
735770 allValues [index ++] = Util .getProblemArgumentsForMarker (problem .getArguments ()); // arguments
736771 allValues [index ++] = new Integer (problem .getCategoryID ()); // category ID
@@ -835,7 +870,7 @@ protected void writeClassFileContents(ClassFile classFile, IFile file, String qu
835870 if (JavaBuilder .DEBUG )
836871 System .out .println ("Writing changed class file " + file .getName ());//$NON-NLS-1$
837872 if (!file .isDerived ())
838- file .setDerived (true );
873+ file .setDerived (true , null );
839874 file .setContents (input , true , false , null );
840875 } else {
841876 // Default implementation just writes out the bytes for the new class file...
0 commit comments