Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 116951 Details for
Bug 12044
[search] Should find constant references in .class files with source attached
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
[patch]
Patch proposed for 3.5M3
v21.txt (text/plain), 130.32 KB, created by
Frederic Fusier
on 2008-11-04 10:56:23 EST
(
hide
)
Description:
Patch proposed for 3.5M3
Filename:
MIME Type:
Creator:
Frederic Fusier
Created:
2008-11-04 10:56:23 EST
Size:
130.32 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.jdt.core >Index: search/org/eclipse/jdt/core/search/SearchDocument.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchDocument.java,v >retrieving revision 1.16 >diff -u -r1.16 SearchDocument.java >--- search/org/eclipse/jdt/core/search/SearchDocument.java 20 Oct 2008 19:04:26 -0000 1.16 >+++ search/org/eclipse/jdt/core/search/SearchDocument.java 4 Nov 2008 15:31:19 -0000 >@@ -93,7 +93,11 @@ > */ > public abstract char[] getCharContents(); > >- private String getContainerRelativePath() { >+ /** >+ * @nooverride This method is not intended to be re-implemented or extended by clients. >+ * @noreference This method is not intended to be referenced by clients. >+ */ >+ protected String getContainerRelativePath() { > if (this.containerRelativePath == null) > this.containerRelativePath = this.index.containerRelativePath(getPath()); > return this.containerRelativePath; >Index: search/org/eclipse/jdt/internal/core/search/processing/JobManager.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/processing/JobManager.java,v >retrieving revision 1.97 >diff -u -r1.97 JobManager.java >--- search/org/eclipse/jdt/internal/core/search/processing/JobManager.java 12 Sep 2008 13:17:49 -0000 1.97 >+++ search/org/eclipse/jdt/internal/core/search/processing/JobManager.java 4 Nov 2008 15:31:20 -0000 >@@ -17,10 +17,13 @@ > > public abstract class JobManager implements Runnable { > >- /* queue of jobs to execute */ >- protected IJob[] awaitingJobs = new IJob[10]; >- protected int jobStart = 0; >- protected int jobEnd = -1; >+ /* queues of jobs to execute */ >+ public static final int HIGH_PRIORITY = 1; >+ public static final int LOW_PRIORITY = 0; >+ protected static final int MAX_PRIORITY = HIGH_PRIORITY; >+ protected IJob[][] awaitingJobs = new IJob[MAX_PRIORITY+1][10]; >+ protected int[] jobStart = new int[MAX_PRIORITY+1]; >+ protected int[] jobEnd = new int[MAX_PRIORITY+1]; > protected boolean executing = false; > > /* background processing */ >@@ -37,6 +40,13 @@ > > private int awaitingClients = 0; > >+ public JobManager() { >+ for (int priorityIndex = 0; priorityIndex <= MAX_PRIORITY; priorityIndex++) { >+ this.jobStart[priorityIndex] = 0; >+ this.jobEnd[priorityIndex] = -1; >+ } >+ } >+ > /** > * Invoked exactly once, in background, before starting processing any job > */ >@@ -46,17 +56,52 @@ > /** > * Answer the amount of awaiting jobs. > */ >- public synchronized int awaitingJobsCount() { >- // pretend busy in case concurrent job attempts performing before activated >- return this.activated ? this.jobEnd - this.jobStart + 1 : 1; >+ public int awaitingJobsCount() { >+ return awaitingJobsCount(HIGH_PRIORITY); >+ } >+ >+ /** >+ * Answer the amount of awaiting jobs with a given priority (jobs with a lower priority are not considered). >+ */ >+ private synchronized int awaitingJobsCount(int maxPriority) { >+ if (!this.activated) { >+ // pretend busy in case concurrent job attempts performing before activated >+ return 1; >+ } >+ int count = 0; >+ for (int priorityIndex = 0; priorityIndex <= MAX_PRIORITY-maxPriority; priorityIndex++) { >+ int n = this.jobEnd[priorityIndex] - this.jobStart[priorityIndex] + 1; >+ if (VERBOSE) Util.verbose(" - jobs count for priority "+ (MAX_PRIORITY-priorityIndex) + " = " + n); //$NON-NLS-1$ //$NON-NLS-2$ >+ count += n; >+ } >+ return count; > } > /** > * Answers the first job in the queue, or null if there is no job available > * Until the job has completed, the job manager will keep answering the same job. > */ >- public synchronized IJob currentJob() { >- if (this.enableCount > 0 && this.jobStart <= this.jobEnd) >- return this.awaitingJobs[this.jobStart]; >+ public IJob currentJob() { >+ return currentJob(LOW_PRIORITY); >+ } >+ /** >+ * Answers the first job in the queue, or null if there is no job available >+ * Until the job has completed, the job manager will keep answering the same job. >+ */ >+ private synchronized IJob currentJob(int maxPriority) { >+ if (this.enableCount <= 0 || maxPriority < 0) >+ return null; >+ for (int priorityIndex = 0; priorityIndex <= MAX_PRIORITY-maxPriority; priorityIndex++) { >+ IJob job = currentJobForPriority(priorityIndex); >+ if (job != null) >+ return job; >+ } >+ return null; >+ } >+ >+ private IJob currentJobForPriority(int prorityIndex) { >+ int start = this.jobStart[prorityIndex]; >+ if (start <= this.jobEnd[prorityIndex]) >+ return this.awaitingJobs[prorityIndex][start]; > return null; > } > public synchronized void disable() { >@@ -65,86 +110,103 @@ > Util.verbose("DISABLING background indexing"); //$NON-NLS-1$ > } > /** >- * Remove the index from cache for a given project. >+ * Remove the jobs belonging to the given family. > * Passing null as a job family discards them all. > */ > public void discardJobs(String jobFamily) { >- > if (VERBOSE) > Util.verbose("DISCARD background job family - " + jobFamily); //$NON-NLS-1$ >- >- try { >- IJob currentJob; >- // cancel current job if it belongs to the given family >- synchronized(this){ >- currentJob = currentJob(); >- disable(); >- } >- if (currentJob != null && (jobFamily == null || currentJob.belongsTo(jobFamily))) { >- currentJob.cancel(); >- >- // wait until current active job has finished >- while (this.processingThread != null && this.executing){ >- try { >- if (VERBOSE) >- Util.verbose("-> waiting end of current background job - " + currentJob); //$NON-NLS-1$ >- Thread.sleep(50); >- } catch(InterruptedException e){ >- // ignore >- } >+ for (int priorityIndex = 0; priorityIndex <= MAX_PRIORITY; priorityIndex++) { >+ try { >+ IJob currentJob; >+ // cancel current job if it belongs to the given family >+ synchronized(this){ >+ currentJob = currentJobForPriority(priorityIndex); >+ disable(); > } >- } >- >- // flush and compact awaiting jobs >- int loc = -1; >- synchronized(this) { >- for (int i = this.jobStart; i <= this.jobEnd; i++) { >- currentJob = this.awaitingJobs[i]; >- if (currentJob != null) { // sanity check >- this.awaitingJobs[i] = null; >- if (!(jobFamily == null || currentJob.belongsTo(jobFamily))) { // copy down, compacting >- this.awaitingJobs[++loc] = currentJob; >- } else { >+ if (currentJob != null && (jobFamily == null || currentJob.belongsTo(jobFamily))) { >+ currentJob.cancel(); >+ >+ // wait until current active job has finished >+ while (this.processingThread != null && this.executing){ >+ try { > if (VERBOSE) >- Util.verbose("-> discarding background job - " + currentJob); //$NON-NLS-1$ >- currentJob.cancel(); >+ Util.verbose("-> waiting end of current background job - " + currentJob); //$NON-NLS-1$ >+ Thread.sleep(50); >+ } catch(InterruptedException e){ >+ // ignore >+ } >+ } >+ } >+ >+ // flush and compact awaiting jobs >+ int loc = -1; >+ synchronized(this) { >+ for (int i = this.jobStart[priorityIndex]; i <= this.jobEnd[priorityIndex]; i++) { >+ currentJob = this.awaitingJobs[priorityIndex][i]; >+ if (currentJob != null) { // sanity check >+ this.awaitingJobs[priorityIndex][i] = null; >+ if (!(jobFamily == null || currentJob.belongsTo(jobFamily))) { // copy down, compacting >+ this.awaitingJobs[priorityIndex][++loc] = currentJob; >+ } else { >+ if (VERBOSE) >+ Util.verbose("-> discarding background job - " + currentJob); //$NON-NLS-1$ >+ currentJob.cancel(); >+ } > } > } >+ this.jobStart[priorityIndex] = 0; >+ this.jobEnd[priorityIndex] = loc; > } >- this.jobStart = 0; >- this.jobEnd = loc; >+ } finally { >+ enable(); > } >- } finally { >- enable(); > } > if (VERBOSE) > Util.verbose("DISCARD DONE with background job family - " + jobFamily); //$NON-NLS-1$ > } >+ > public synchronized void enable() { > this.enableCount++; > if (VERBOSE) > Util.verbose("ENABLING background indexing"); //$NON-NLS-1$ > notifyAll(); // wake up the background thread if it is waiting (context must be synchronized) > } >- protected synchronized boolean isJobWaiting(IJob request) { >- for (int i = this.jobEnd; i > this.jobStart; i--) // don't check job at jobStart, as it may have already started >- if (request.equals(this.awaitingJobs[i])) return true; >+ protected boolean isJobWaiting(IJob request) { >+ return isJobWaiting(request, HIGH_PRIORITY); >+ } >+ protected synchronized boolean isJobWaiting(IJob request, int maxPriority) { >+ for (int priorityIndex = 0; priorityIndex <= MAX_PRIORITY-maxPriority; priorityIndex++) { >+ for (int i = this.jobEnd[priorityIndex]; i > this.jobStart[priorityIndex]; i--) // don't check job at jobStart, as it may have already started >+ if (request.equals(this.awaitingJobs[priorityIndex][i])) >+ return true; >+ } > return false; > } > /** > * Advance to the next available job, once the current one has been completed. > * Note: clients awaiting until the job count is zero are still waiting at this point. >+ * >+ * @return the priority of the moved job or a lower priority if there's no longer job in the queue > */ >- protected synchronized void moveToNextJob() { >- //if (!enabled) return; >- >- if (this.jobStart <= this.jobEnd) { >- this.awaitingJobs[this.jobStart++] = null; >- if (this.jobStart > this.jobEnd) { >- this.jobStart = 0; >- this.jobEnd = -1; >+ protected synchronized int moveToNextJob() { >+ for (int priorityIndex=0; priorityIndex <= MAX_PRIORITY; priorityIndex++) { >+ if (this.jobStart[priorityIndex] <= this.jobEnd[priorityIndex]) { >+ int priority = MAX_PRIORITY - priorityIndex; >+ this.awaitingJobs[priorityIndex][this.jobStart[priorityIndex]++] = null; >+ if (this.jobStart[priorityIndex] > this.jobEnd[priorityIndex]) { >+ // no more job in this queue... >+ this.jobStart[priorityIndex] = 0; >+ this.jobEnd[priorityIndex] = -1; >+ // ... so, move to a lower priority >+ if (priority > LOW_PRIORITY) priority--; >+ } >+ if (VERBOSE) Util.verbose("Move to next job (priority="+(priority)+')'); //$NON-NLS-1$ >+ return priority; > } > } >+ // no job to move on, use the lowest priority >+ return LOW_PRIORITY; > } > /** > * When idle, give chance to do something >@@ -157,19 +219,25 @@ > * Indeed since other jobs are performed in background, resource sharing might be > * an issue.Therefore, this functionality allows a given job to be run without > * colliding with background ones. >+ * <p> > * Note: multiple thread might attempt to perform concurrent jobs at the same time, > * and should synchronize (it is deliberately left to clients to decide whether > * concurrent jobs might interfere or not. In general, multiple read jobs are ok). >- * >+ *</p><p> > * Waiting policy can be: >- * IJobConstants.ForceImmediateSearch >- * IJobConstants.CancelIfNotReadyToSearch >- * IJobConstants.WaitUntilReadyToSearch >- * >+ * <ul> >+ * <li>{@link IJob#ForceImmediate}</li> >+ * <li>{@link IJob#CancelIfNotReady}</li> >+ * <li>{@link IJob#WaitUntilReady}</li> >+ * </ul> >+ *</p> > */ > public boolean performConcurrentJob(IJob searchJob, int waitingPolicy, IProgressMonitor progress) { >+ return performConcurrentJob(searchJob, waitingPolicy, HIGH_PRIORITY, progress); >+ } >+ public boolean performConcurrentJob(IJob searchJob, int waitingPolicy, int maxPriority, IProgressMonitor progress) { > if (VERBOSE) >- Util.verbose("STARTING concurrent job - " + searchJob); //$NON-NLS-1$ >+ Util.verbose("STARTING concurrent job - " + searchJob + "(priority="+maxPriority+')'); //$NON-NLS-1$ //$NON-NLS-2$ > > searchJob.ensureReadyToRun(); > >@@ -178,7 +246,7 @@ > int concurrentJobWork = 100; > if (progress != null) > progress.beginTask("", concurrentJobWork); //$NON-NLS-1$ >- if (awaitingJobsCount() > 0) { >+ if (awaitingJobsCount(maxPriority) > 0) { > switch (waitingPolicy) { > > case IJob.ForceImmediate : >@@ -225,10 +293,10 @@ > int lastJobsCount = totalWork; > float lastWorked = 0; > float totalWorked = 0; >- while ((awaitingJobsCount = awaitingJobsCount()) > 0) { >+ while ((awaitingJobsCount = awaitingJobsCount(maxPriority)) > 0) { > if (subProgress != null && subProgress.isCanceled()) > throw new OperationCanceledException(); >- IJob currentJob = currentJob(); >+ IJob currentJob = currentJob(maxPriority); > // currentJob can be null when jobs have been added to the queue but job manager is not enabled > if (currentJob != null && currentJob != previousJob) { > if (VERBOSE) >@@ -284,21 +352,24 @@ > } > public abstract String processName(); > >- public synchronized void request(IJob job) { >- >+ public void request(IJob job) { >+ request(job, HIGH_PRIORITY); >+ } >+ >+ public synchronized void request(IJob job, int priority) { > job.ensureReadyToRun(); >- >+ int priorityIndex = MAX_PRIORITY-priority; // reverse order > // append the job to the list of ones to process later on >- int size = this.awaitingJobs.length; >- if (++this.jobEnd == size) { // when growing, relocate jobs starting at position 0 >- this.jobEnd -= this.jobStart; >- System.arraycopy(this.awaitingJobs, this.jobStart, this.awaitingJobs = new IJob[size * 2], 0, this.jobEnd); >- this.jobStart = 0; >+ int size = this.awaitingJobs[priorityIndex].length; >+ if (++this.jobEnd[priorityIndex] == size) { // when growing, relocate jobs starting at position 0 >+ this.jobEnd[priorityIndex] -= this.jobStart[priorityIndex]; >+ System.arraycopy(this.awaitingJobs[priorityIndex], this.jobStart[priorityIndex], this.awaitingJobs[priorityIndex] = new IJob[size * 2], 0, this.jobEnd[priorityIndex]); >+ this.jobStart[priorityIndex] = 0; > } >- this.awaitingJobs[this.jobEnd] = job; >+ this.awaitingJobs[priorityIndex][this.jobEnd[priorityIndex]] = job; > if (VERBOSE) { > Util.verbose("REQUEST background job - " + job); //$NON-NLS-1$ >- Util.verbose("AWAITING JOBS count: " + awaitingJobsCount()); //$NON-NLS-1$ >+ Util.verbose("AWAITING JOBS count: " + awaitingJobsCount(LOW_PRIORITY)); //$NON-NLS-1$ > } > notifyAll(); // wake up the background thread if it is waiting > } >@@ -351,6 +422,7 @@ > } > } > this.progressJob = null; >+ int maxPriority = LOW_PRIORITY; // need the priority to get the job, default is the lowest one (i.e. any job will be kept) > while (this.processingThread != null) { > try { > IJob job; >@@ -359,7 +431,7 @@ > if (this.processingThread == null) continue; > > // must check for new job inside this sync block to avoid timing hole >- if ((job = currentJob()) == null) { >+ if ((job = currentJob(maxPriority)) == null) { > if (this.progressJob != null) { > this.progressJob.cancel(); > this.progressJob = null; >@@ -380,7 +452,7 @@ > continue; > } > if (VERBOSE) { >- Util.verbose(awaitingJobsCount() + " awaiting jobs"); //$NON-NLS-1$ >+ Util.verbose(awaitingJobsCount(LOW_PRIORITY) + " awaiting jobs"); //$NON-NLS-1$ > Util.verbose("STARTING background job - " + job); //$NON-NLS-1$ > } > try { >@@ -397,7 +469,7 @@ > this.executing = false; > if (VERBOSE) > Util.verbose("FINISHED background job - " + job); //$NON-NLS-1$ >- moveToNextJob(); >+ maxPriority = moveToNextJob(); > if (this.awaitingClients == 0) > Thread.sleep(50); > } >@@ -457,13 +529,16 @@ > // ignore > } > } >- public String toString() { >+ public synchronized String toString() { > StringBuffer buffer = new StringBuffer(10); > buffer.append("Enable count:").append(this.enableCount).append('\n'); //$NON-NLS-1$ >- int numJobs = this.jobEnd - this.jobStart + 1; >- buffer.append("Jobs in queue:").append(numJobs).append('\n'); //$NON-NLS-1$ >- for (int i = 0; i < numJobs && i < 15; i++) { >- buffer.append(i).append(" - job["+i+"]: ").append(this.awaitingJobs[this.jobStart+i]).append('\n'); //$NON-NLS-1$ //$NON-NLS-2$ >+ for (int priorityIndex = 0; priorityIndex <= MAX_PRIORITY; priorityIndex++) { >+ int numJobs = this.jobEnd[priorityIndex] - this.jobStart[priorityIndex] + 1; >+ buffer.append("Jobs in queue [").append(MAX_PRIORITY-priorityIndex).append("]:").append(numJobs).append('\n'); //$NON-NLS-1$ //$NON-NLS-2$ >+ for (int i = 0; i < numJobs && i < 15; i++) { >+ buffer.append(i).append(" - job[").append(i).append("]: ").append(this.awaitingJobs[priorityIndex][this.jobStart[priorityIndex]+i]).append('\n'); //$NON-NLS-1$ //$NON-NLS-2$ >+ } >+ > } > return buffer.toString(); > } >Index: search/org/eclipse/jdt/internal/core/search/indexing/IndexAllProject.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexAllProject.java,v >retrieving revision 1.87 >diff -u -r1.87 IndexAllProject.java >--- search/org/eclipse/jdt/internal/core/search/indexing/IndexAllProject.java 27 Jun 2008 16:03:49 -0000 1.87 >+++ search/org/eclipse/jdt/internal/core/search/indexing/IndexAllProject.java 4 Nov 2008 15:31:20 -0000 >@@ -77,7 +77,7 @@ > if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY && entry.getPath().equals(projectPath)) { > // the project is also a library folder (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=89815) > // ensure a job exists to index it as a binary folder >- this.manager.indexLibrary(projectPath, this.project); >+ this.manager.indexLibrary(entry, javaProject); > return true; > } > } >Index: search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java,v >retrieving revision 1.162 >diff -u -r1.162 IndexManager.java >--- search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java 3 Oct 2008 10:47:56 -0000 1.162 >+++ search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java 4 Nov 2008 15:31:20 -0000 >@@ -29,6 +29,7 @@ > import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable; > import org.eclipse.jdt.internal.compiler.util.SimpleSet; > import org.eclipse.jdt.internal.core.*; >+import org.eclipse.jdt.internal.core.DeltaProcessor.RootInfo; > import org.eclipse.jdt.internal.core.index.*; > import org.eclipse.jdt.internal.core.search.BasicSearchEngine; > import org.eclipse.jdt.internal.core.search.PatternSearchJob; >@@ -380,7 +381,7 @@ > for (int i = 0; i < entries.length; i++) { > IClasspathEntry entry= entries[i]; > if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) >- indexLibrary(entry.getPath(), project); >+ indexLibrary(entry, javaProject); > } > } catch(JavaModelException e){ // cannot retrieve classpath info > } >@@ -391,38 +392,67 @@ > request(request); > } > /** >- * Trigger addition of a library to an index >+ * Trigger addition to an index of a library defined by a classpath entry > * Note: the actual operation is performed in background > */ >-public void indexLibrary(IPath path, IProject requestingProject) { >+public void indexLibrary(IClasspathEntry classpathEntry, IJavaProject requestingProject) { >+ IPath path = classpathEntry.getPath(); >+ IndexRequest request = indexRequest(path); >+ if (request == null) return; >+ if (request instanceof AddJarFileToIndex) { >+ AddJarFileToIndex jarFileRequest = (AddJarFileToIndex) request; >+ jarFileRequest.setJavaProject(requestingProject); >+ jarFileRequest.setSourceMapper(classpathEntry); >+ } >+ if (!isJobWaiting(request)) { >+ request(request); >+ } >+} >+/** >+ * Trigger addition to an index of a library defined by a jar package fragment root >+ * Note: the actual operation is performed in background >+ */ >+public void indexPackageFragmentRoot(IPackageFragmentRoot fragmentRoot) { >+ IPath path = fragmentRoot.getPath(); >+ IndexRequest request = indexRequest(path); >+ if (request == null) return; >+ if (request instanceof AddJarFileToIndex) { >+ AddJarFileToIndex jarFileRequest = (AddJarFileToIndex) request; >+ jarFileRequest.setSourceMapper(fragmentRoot); >+ } >+ if (!isJobWaiting(request)) { >+ request(request); >+ } >+} >+private IndexRequest indexRequest(IPath path) { > // requestingProject is no longer used to cancel jobs but leave it here just in case >- if (JavaCore.getPlugin() == null) return; >+ if (JavaCore.getPlugin() == null) return null; > > Object target = JavaModel.getTarget(path, true); > IndexRequest request = null; >- if (target instanceof IFile) { >+ if (target instanceof IProject) { >+ IProject p = (IProject) target; >+ if (JavaProject.hasJavaNature(p)) >+ request = new IndexAllProject(p, this); >+ } else if (target instanceof IContainer) { >+ request = new IndexBinaryFolder((IContainer) target, this); >+ } else if (target instanceof IFile) { > request = new AddJarFileToIndex((IFile) target, this); > } else if (target instanceof File) { > request = new AddJarFileToIndex(path, this); >- } else if (target instanceof IContainer) { >- request = new IndexBinaryFolder((IContainer) target, this); >- } else { >- return; > } >- >- // check if the same request is not already in the queue >- if (!isJobWaiting(request)) >- request(request); >+ return request; > } > /** > * Index the content of the given source folder. > */ > public void indexSourceFolder(JavaProject javaProject, IPath sourceFolder, char[][] inclusionPatterns, char[][] exclusionPatterns) { > IProject project = javaProject.getProject(); >- if (this.jobEnd > this.jobStart) { >+ int priorityIndex = MAX_PRIORITY - HIGH_PRIORITY; >+ if (this.jobEnd[priorityIndex] > this.jobStart[priorityIndex]) { > // skip it if a job to index the project is already in the queue > IndexRequest request = new IndexAllProject(project, this); >- if (isJobWaiting(request)) return; >+ if (isJobWaiting(request, HIGH_PRIORITY)) return; > } > > request(new AddFolderToIndex(sourceFolder, project, inclusionPatterns, exclusionPatterns, this)); >@@ -440,10 +470,10 @@ > * Advance to the next available job, once the current one has been completed. > * Note: clients awaiting until the job count is zero are still waiting at this point. > */ >-protected synchronized void moveToNextJob() { >+protected synchronized int moveToNextJob() { > // remember that one job was executed, and we will need to save indexes at some point > this.needToSave = true; >- super.moveToNextJob(); >+ return super.moveToNextJob(); > } > /** > * No more job awaiting. >@@ -465,20 +495,19 @@ > Util.verbose("-> request to rebuild index: "+indexLocation+" path: "+containerPath); //$NON-NLS-1$ //$NON-NLS-2$ > > updateIndexState(indexLocation, REBUILDING_STATE); >- IndexRequest request = null; >- if (target instanceof IProject) { >- IProject p = (IProject) target; >- if (JavaProject.hasJavaNature(p)) >- request = new IndexAllProject(p, this); >- } else if (target instanceof IFolder) { >- request = new IndexBinaryFolder((IFolder) target, this); >- } else if (target instanceof IFile) { >- request = new AddJarFileToIndex((IFile) target, this); >- } else if (target instanceof File) { >- request = new AddJarFileToIndex(containerPath, this); >+ IndexRequest request = indexRequest(containerPath); >+ if (request == null) return; >+ if (request instanceof AddJarFileToIndex) { >+ DeltaProcessingState processingState = JavaModelManager.getDeltaState(); >+ RootInfo rootInfo = (RootInfo) processingState.roots.get(containerPath); >+ if (rootInfo != null) { >+ AddJarFileToIndex jarFileRequest = (AddJarFileToIndex) request; >+ jarFileRequest.setSourceMapper(rootInfo.getPackageFragmentRoot(null/*no resource hint*/)); >+ } > } >- if (request != null) >+ if (!isJobWaiting(request)) { > request(request); >+ } > } > /** > * Recreates the index for a given path, keeping the same read-write monitor. >@@ -510,6 +539,33 @@ > } > } > /** >+ * Resets the index for a given path. >+ * Returns true if the index was reset, false otherwise. >+ */ >+public synchronized boolean resetIndex(IPath containerPath) { >+ // only called to over write an existing cached index... >+ String containerPathString = containerPath.getDevice() == null ? containerPath.toString() : containerPath.toOSString(); >+ try { >+ // Path is already canonical >+ IPath indexLocation = computeIndexLocation(containerPath); >+ Index index = getIndex(indexLocation); >+ >+ if (VERBOSE) { >+ Util.verbose("-> reseting index: "+indexLocation+" for path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$ >+ } >+ index.reset(true/*reuse index file*/); >+ return true; >+ } catch (IOException e) { >+ // The file could not be created. Possible reason: the project has been deleted. >+ if (VERBOSE) { >+ Util.verbose("-> failed to reset index for path: "+containerPathString); //$NON-NLS-1$ >+ e.printStackTrace(); >+ } >+ return false; >+ } >+} >+ >+/** > * Trigger removal of a resource to an index > * Note: the actual operation is performed in background > */ >@@ -602,10 +658,11 @@ > */ > public void removeSourceFolderFromIndex(JavaProject javaProject, IPath sourceFolder, char[][] inclusionPatterns, char[][] exclusionPatterns) { > IProject project = javaProject.getProject(); >- if (this.jobEnd > this.jobStart) { >+ int priorityIndex = MAX_PRIORITY - HIGH_PRIORITY; >+ if (this.jobEnd[priorityIndex] > this.jobStart[priorityIndex]) { > // skip it if a job to index the project is already in the queue > IndexRequest request = new IndexAllProject(project, this); >- if (isJobWaiting(request)) return; >+ if (isJobWaiting(request, HIGH_PRIORITY)) return; > } > > request(new RemoveFolderFromIndex(sourceFolder, inclusionPatterns, exclusionPatterns, project, this)); >@@ -631,11 +688,13 @@ > } > synchronized (this) { > IPath containerPath = new Path(index.containerPath); >- if (this.jobEnd > this.jobStart) { >- for (int i = this.jobEnd; i > this.jobStart; i--) { // skip the current job >- IJob job = this.awaitingJobs[i]; >- if (job instanceof IndexRequest) >- if (((IndexRequest) job).containerPath.equals(containerPath)) return; >+ for (int priorityIndex = 0; priorityIndex <= MAX_PRIORITY; priorityIndex++) { >+ if (this.jobEnd[priorityIndex] > this.jobStart[priorityIndex]) { >+ for (int i = this.jobEnd[priorityIndex]; i > this.jobStart[priorityIndex]; i--) { // skip the current job >+ IJob job = this.awaitingJobs[priorityIndex][i]; >+ if (job instanceof IndexRequest) >+ if (((IndexRequest) job).containerPath.equals(containerPath)) return; >+ } > } > } > IPath indexLocation = computeIndexLocation(containerPath); >@@ -714,7 +773,7 @@ > }); > } > >-public String toString() { >+public synchronized String toString() { > StringBuffer buffer = new StringBuffer(10); > buffer.append(super.toString()); > buffer.append("In-memory indexes:\n"); //$NON-NLS-1$ >Index: search/org/eclipse/jdt/internal/core/search/indexing/AddJarFileToIndex.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddJarFileToIndex.java,v >retrieving revision 1.75 >diff -u -r1.75 AddJarFileToIndex.java >--- search/org/eclipse/jdt/internal/core/search/indexing/AddJarFileToIndex.java 27 Jun 2008 16:03:49 -0000 1.75 >+++ search/org/eclipse/jdt/internal/core/search/indexing/AddJarFileToIndex.java 4 Nov 2008 15:31:20 -0000 >@@ -10,10 +10,12 @@ > *******************************************************************************/ > package org.eclipse.jdt.internal.core.search.indexing; > >-import java.io.File; > import java.io.IOException; >-import java.net.URI; >+import java.util.ArrayList; > import java.util.Enumeration; >+import java.util.HashMap; >+import java.util.List; >+import java.util.Map; > import java.util.zip.ZipEntry; > import java.util.zip.ZipFile; > >@@ -22,12 +24,23 @@ > import org.eclipse.core.runtime.IPath; > import org.eclipse.core.runtime.IProgressMonitor; > import org.eclipse.core.runtime.Path; >+import org.eclipse.jdt.core.IClasspathEntry; >+import org.eclipse.jdt.core.IJavaElement; >+import org.eclipse.jdt.core.IJavaProject; >+import org.eclipse.jdt.core.IPackageFragmentRoot; >+import org.eclipse.jdt.core.JavaCore; >+import org.eclipse.jdt.core.JavaModelException; > import org.eclipse.jdt.core.search.IJavaSearchScope; > import org.eclipse.jdt.core.search.SearchEngine; > import org.eclipse.jdt.core.search.SearchParticipant; >+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader; >+import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException; > import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable; >+import org.eclipse.jdt.internal.compiler.util.SuffixConstants; > import org.eclipse.jdt.internal.compiler.util.Util; > import org.eclipse.jdt.internal.core.JavaModelManager; >+import org.eclipse.jdt.internal.core.PackageFragmentRoot; >+import org.eclipse.jdt.internal.core.SourceMapper; > import org.eclipse.jdt.internal.core.index.Index; > import org.eclipse.jdt.internal.core.search.JavaSearchDocument; > import org.eclipse.jdt.internal.core.search.processing.JobManager; >@@ -36,204 +49,368 @@ > > private static final char JAR_SEPARATOR = IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR.charAt(0); > IFile resource; >+ SourceMapper sourceMapper; >+ IPath sourcePath; >+ IJavaProject javaProject; >+ IPackageFragmentRoot packageFragmentRoot; >+ >+public AddJarFileToIndex(IFile resource, IndexManager manager) { >+ super(resource.getFullPath(), manager); >+ this.resource = resource; >+} >+public AddJarFileToIndex(IPath jarPath, IndexManager manager) { >+ // external JAR scenario - no resource >+ super(jarPath, manager); >+} >+ >+void setJavaProject(IJavaProject javaProject) { >+ this.javaProject = javaProject; >+} > >- public AddJarFileToIndex(IFile resource, IndexManager manager) { >- super(resource.getFullPath(), manager); >- this.resource = resource; >- } >- public AddJarFileToIndex(IPath jarPath, IndexManager manager) { >- // external JAR scenario - no resource >- super(jarPath, manager); >- } >- public boolean equals(Object o) { >- if (o instanceof AddJarFileToIndex) { >- if (this.resource != null) >- return this.resource.equals(((AddJarFileToIndex) o).resource); >- if (this.containerPath != null) >- return this.containerPath.equals(((AddJarFileToIndex) o).containerPath); >+void setSourceMapper(IClasspathEntry classpathEntry) { >+ if (this.javaProject != null) { >+ try { >+ IPackageFragmentRoot root= this.javaProject.findPackageFragmentRoot(classpathEntry.getPath()); >+ this.packageFragmentRoot = root; > } >- return false; >+ catch (JavaModelException jme) { >+ // ignore >+ } >+ } >+ this.sourcePath = classpathEntry.getSourceAttachmentPath(); >+ IPath rootPath = classpathEntry.getSourceAttachmentRootPath(); >+ if (this.packageFragmentRoot != null) { >+ try { >+ PackageFragmentRoot root = (PackageFragmentRoot) this.packageFragmentRoot; >+ if (this.sourcePath == null) { >+ this.sourcePath = root.sourceAttachmentPath(); >+ if (this.sourcePath == null) { >+ this.sourcePath = root.getPath(); >+ } >+ } >+ if (rootPath == null) { >+ rootPath = root.getSourceAttachmentRootPath(); >+ } >+ } catch (Exception e) { >+ // ignore >+ } >+ } >+ if (this.sourcePath != null) { >+ Map options = this.javaProject == null >+ ? JavaCore.getOptions() >+ : this.javaProject.getOptions(true); >+ this.sourceMapper = new SourceMapper( >+ this.sourcePath , >+ rootPath == null ? null : rootPath.toOSString(), >+ options); >+ } >+} >+ >+void setSourceMapper(IPackageFragmentRoot fragmentRoot) { >+ this.packageFragmentRoot = fragmentRoot; >+ if (this.javaProject == null) { >+ this.javaProject = fragmentRoot.getJavaProject(); > } >- public int hashCode() { >+ try { >+ this.sourcePath = ((PackageFragmentRoot)fragmentRoot).sourceAttachmentPath(); >+ if (this.sourcePath == null) { >+ this.sourcePath = fragmentRoot.getPath(); >+ } >+ IPath rootPath = ((PackageFragmentRoot)fragmentRoot).sourceAttachmentRootPath(); >+ this.sourceMapper = new SourceMapper( >+ this.sourcePath, >+ rootPath == null ? null : rootPath.toOSString(), >+ this.javaProject.getOptions(true)); >+ } catch (JavaModelException e) { >+ // skip >+ } >+} >+ >+public boolean equals(Object o) { >+ if (o instanceof AddJarFileToIndex) { > if (this.resource != null) >- return this.resource.hashCode(); >+ return this.resource.equals(((AddJarFileToIndex) o).resource); > if (this.containerPath != null) >- return this.containerPath.hashCode(); >- return -1; >+ return this.containerPath.equals(((AddJarFileToIndex) o).containerPath); > } >- public boolean execute(IProgressMonitor progressMonitor) { >+ return false; >+} >+public int hashCode() { >+ if (this.resource != null) >+ return this.resource.hashCode(); >+ if (this.containerPath != null) >+ return this.containerPath.hashCode(); >+ return -1; >+} >+public boolean execute(IProgressMonitor progressMonitor) { > >- if (this.isCancelled || progressMonitor != null && progressMonitor.isCanceled()) return true; >+ boolean verbose = true; //JobManager.VERBOSE; > >- try { >- // if index is already cached, then do not perform any check >- // MUST reset the IndexManager if a jar file is changed >- Index index = this.manager.getIndexForUpdate(this.containerPath, false, /*do not reuse index file*/ false /*do not create if none*/); >+ if (this.isCancelled || progressMonitor != null && progressMonitor.isCanceled()) return true; >+ >+ try { >+ // if index is already cached, then do not perform any check >+ // MUST reset the IndexManager if a jar file is changed >+ Index index = this.manager.getIndexForUpdate(this.containerPath, false, /*do not reuse index file*/ false /*do not create if none*/); >+ if (this.sourcePath == null) { // force reindexing if there's attached sources as there's no way to know if they have been changed or not > if (index != null) { >- if (JobManager.VERBOSE) >+ if (verbose) > org.eclipse.jdt.internal.core.util.Util.verbose("-> no indexing required (index already exists) for " + this.containerPath); //$NON-NLS-1$ > return true; > } >+ } > >+ if (index == null) { > index = this.manager.getIndexForUpdate(this.containerPath, true, /*reuse index file*/ true /*create if none*/); >- if (index == null) { >- if (JobManager.VERBOSE) >- org.eclipse.jdt.internal.core.util.Util.verbose("-> index could not be created for " + this.containerPath); //$NON-NLS-1$ >- return true; >- } >- ReadWriteMonitor monitor = index.monitor; >- if (monitor == null) { >- if (JobManager.VERBOSE) >- org.eclipse.jdt.internal.core.util.Util.verbose("-> index for " + this.containerPath + " just got deleted"); //$NON-NLS-1$//$NON-NLS-2$ >- return true; // index got deleted since acquired >- } >- index.separator = JAR_SEPARATOR; >- ZipFile zip = null; >- try { >- // this path will be a relative path to the workspace in case the zipfile in the workspace otherwise it will be a path in the >- // local file system >- Path zipFilePath = null; >- >- monitor.enterWrite(); // ask permission to write >- if (this.resource != null) { >- URI location = this.resource.getLocationURI(); >- if (location == null) return false; >- if (JavaModelManager.ZIP_ACCESS_VERBOSE) >- System.out.println("(" + Thread.currentThread() + ") [AddJarFileToIndex.execute()] Creating ZipFile on " + location.getPath()); //$NON-NLS-1$ //$NON-NLS-2$ >- File file = null; >- try { >- file = org.eclipse.jdt.internal.core.util.Util.toLocalFile(location, progressMonitor); >- } catch (CoreException e) { >- if (JobManager.VERBOSE) { >- org.eclipse.jdt.internal.core.util.Util.verbose("-> failed to index " + location.getPath() + " because of the following exception:"); //$NON-NLS-1$ //$NON-NLS-2$ >- e.printStackTrace(); >- } >- } >- if (file == null) { >- if (JobManager.VERBOSE) >- org.eclipse.jdt.internal.core.util.Util.verbose("-> failed to index " + location.getPath() + " because the file could not be fetched"); //$NON-NLS-1$ //$NON-NLS-2$ >- return false; >+ } >+ if (index == null) { >+ if (verbose) >+ org.eclipse.jdt.internal.core.util.Util.verbose("-> index could not be created for " + this.containerPath); //$NON-NLS-1$ >+ return true; >+ } >+ ReadWriteMonitor monitor = index.monitor; >+ if (monitor == null) { >+ if (verbose) >+ org.eclipse.jdt.internal.core.util.Util.verbose("-> index for " + this.containerPath + " just got deleted"); //$NON-NLS-1$//$NON-NLS-2$ >+ return true; // index got deleted since acquired >+ } >+ index.separator = JAR_SEPARATOR; >+ ZipFile zip = null; >+ JavaModelManager modelManager = JavaModelManager.getJavaModelManager(); >+ modelManager.cacheZipFiles(); >+ try { >+ // this path will be a relative path to the workspace in case the zipfile in the workspace otherwise it will be a path in the >+ // local file system >+ Path zipFilePath = null; >+ >+ monitor.enterWrite(); // ask permission to write >+ if (this.resource != null) { >+ IPath resourcePath = this.resource.getFullPath(); >+ if (JavaModelManager.ZIP_ACCESS_VERBOSE) >+ System.out.println("(" + Thread.currentThread() + ") [AddJarFileToIndex.execute()] Creating ZipFile on " + resourcePath); //$NON-NLS-1$ //$NON-NLS-2$ >+ try { >+ zip = modelManager.getZipFile(resourcePath); >+ } catch (CoreException ce) { >+ if (verbose) { >+ org.eclipse.jdt.internal.core.util.Util.verbose("-> failed to index " + resourcePath + " because of the following exception:"); //$NON-NLS-1$ //$NON-NLS-2$ >+ ce.printStackTrace(); > } >- zip = new ZipFile(file); >- zipFilePath = (Path) this.resource.getFullPath().makeRelative(); >- // absolute path relative to the workspace >- } else { >- if (JavaModelManager.ZIP_ACCESS_VERBOSE) >- System.out.println("(" + Thread.currentThread() + ") [AddJarFileToIndex.execute()] Creating ZipFile on " + this.containerPath); //$NON-NLS-1$ //$NON-NLS-2$ >- // external file -> it is ok to use toFile() >- zip = new ZipFile(this.containerPath.toFile()); >- zipFilePath = (Path) this.containerPath; >- // path is already canonical since coming from a library classpath entry >+ // jar file is invalid, remove corresponding index >+ this.manager.removeIndex(this.containerPath); >+ return false; > } >+ zipFilePath = (Path) resourcePath.makeRelative(); >+ // absolute path relative to the workspace > >- if (this.isCancelled) { >- if (JobManager.VERBOSE) >- org.eclipse.jdt.internal.core.util.Util.verbose("-> indexing of " + zip.getName() + " has been cancelled"); //$NON-NLS-1$ //$NON-NLS-2$ >+ // Get package fragment root if not already stored >+ if (this.packageFragmentRoot == null) { >+ IJavaElement javaElement = JavaCore.create(this.resource, this.javaProject); >+ if (javaElement.getElementType() == IJavaElement.PACKAGE_FRAGMENT_ROOT) { >+ this.packageFragmentRoot = (IPackageFragmentRoot) javaElement; >+ } >+ } >+ } else { >+ if (JavaModelManager.ZIP_ACCESS_VERBOSE) >+ System.out.println("(" + Thread.currentThread() + ") [AddJarFileToIndex.execute()] Creating ZipFile on " + this.containerPath); //$NON-NLS-1$ //$NON-NLS-2$ >+ // external file -> it is ok to use toFile() >+ try { >+ zip = modelManager.getZipFile(this.containerPath); >+ } catch (CoreException ce) { >+ if (verbose) { >+ org.eclipse.jdt.internal.core.util.Util.verbose("-> failed to index " + this.containerPath + " because of the following exception:"); //$NON-NLS-1$ //$NON-NLS-2$ >+ ce.printStackTrace(); >+ } >+ // jar file is invalid, remove corresponding index >+ this.manager.removeIndex(this.containerPath); > return false; > } >+ zipFilePath = (Path) this.containerPath; >+ // path is already canonical since coming from a library classpath entry >+ } > >- if (JobManager.VERBOSE) >- org.eclipse.jdt.internal.core.util.Util.verbose("-> indexing " + zip.getName()); //$NON-NLS-1$ >- long initialTime = System.currentTimeMillis(); >- >- String[] paths = index.queryDocumentNames(""); // all file names //$NON-NLS-1$ >- if (paths != null) { >- int max = paths.length; >- /* check integrity of the existing index file >- * if the length is equal to 0, we want to index the whole jar again >- * If not, then we want to check that there is no missing entry, if >- * one entry is missing then we recreate the index >- */ >- String EXISTS = "OK"; //$NON-NLS-1$ >- String DELETED = "DELETED"; //$NON-NLS-1$ >- SimpleLookupTable indexedFileNames = new SimpleLookupTable(max == 0 ? 33 : max + 11); >- for (int i = 0; i < max; i++) >- indexedFileNames.put(paths[i], DELETED); >- for (Enumeration e = zip.entries(); e.hasMoreElements();) { >- // iterate each entry to index it >- ZipEntry ze = (ZipEntry) e.nextElement(); >- String zipEntryName = ze.getName(); >- if (Util.isClassFileName(zipEntryName)) >- indexedFileNames.put(zipEntryName, EXISTS); >+ if (this.isCancelled) { >+ if (verbose) >+ org.eclipse.jdt.internal.core.util.Util.verbose("-> indexing of " + zip.getName() + " has been cancelled"); //$NON-NLS-1$ //$NON-NLS-2$ >+ return false; >+ } >+ >+ if (verbose) >+ org.eclipse.jdt.internal.core.util.Util.verbose("-> indexing " + zip.getName()); //$NON-NLS-1$ >+ long initialTime = System.currentTimeMillis(); >+ >+ String[] paths = index.queryDocumentNames(""); // all file names //$NON-NLS-1$ >+ if (paths != null) { >+ int max = paths.length; >+ /* check integrity of the existing index file >+ * if the length is equal to 0, we want to index the whole jar again >+ * If not, then we want to check that there is no missing entry, if >+ * one entry is missing then we recreate the index >+ */ >+ String EXISTS = "OK"; //$NON-NLS-1$ >+ String DELETED = "DELETED"; //$NON-NLS-1$ >+ SimpleLookupTable indexedFileNames = new SimpleLookupTable(max == 0 ? 33 : max + 11); >+ for (int i = 0; i < max; i++) >+ indexedFileNames.put(paths[i], DELETED); >+ for (Enumeration e = zip.entries(); e.hasMoreElements();) { >+ // iterate each entry to index it >+ ZipEntry ze = (ZipEntry) e.nextElement(); >+ String zipEntryName = ze.getName(); >+ if (Util.isClassFileName(zipEntryName)) >+ indexedFileNames.put(zipEntryName, EXISTS); >+ } >+ boolean needToReindex = indexedFileNames.elementSize != max; // a new file was added >+ if (!needToReindex) { >+ Object[] valueTable = indexedFileNames.valueTable; >+ for (int i = 0, l = valueTable.length; i < l; i++) { >+ if (valueTable[i] == DELETED) { >+ needToReindex = true; // a file was deleted so re-index >+ break; >+ } > } >- boolean needToReindex = indexedFileNames.elementSize != max; // a new file was added > if (!needToReindex) { >- Object[] valueTable = indexedFileNames.valueTable; >- for (int i = 0, l = valueTable.length; i < l; i++) { >- if (valueTable[i] == DELETED) { >- needToReindex = true; // a file was deleted so re-index >- break; >- } >- } >- if (!needToReindex) { >- if (JobManager.VERBOSE) >- org.eclipse.jdt.internal.core.util.Util.verbose("-> no indexing required (index is consistent with library) for " //$NON-NLS-1$ >- + zip.getName() + " (" //$NON-NLS-1$ >- + (System.currentTimeMillis() - initialTime) + "ms)"); //$NON-NLS-1$ >- this.manager.saveIndex(index); // to ensure its placed into the saved state >- return true; >- } >+ if (verbose) >+ org.eclipse.jdt.internal.core.util.Util.verbose("-> no indexing required (index is consistent with library) for " //$NON-NLS-1$ >+ + zip.getName() + " (" //$NON-NLS-1$ >+ + (System.currentTimeMillis() - initialTime) + "ms)"); //$NON-NLS-1$ >+ this.manager.saveIndex(index); // to ensure its placed into the saved state >+ return true; > } > } >+ } > >- // Index the jar for the first time or reindex the jar in case the previous index file has been corrupted >- // index already existed: recreate it so that we forget about previous entries >- SearchParticipant participant = SearchEngine.getDefaultSearchParticipant(); >- index = this.manager.recreateIndex(this.containerPath); >- if (index == null) { >- // failed to recreate index, see 73330 >- this.manager.removeIndex(this.containerPath); >- return false; >- } >- index.separator = JAR_SEPARATOR; >+ // Index the jar for the first time or re-index the jar in case the previous index file has been corrupted >+ // index already existed: reset it so that we forget about previous entries >+ // without changing the instance (which may have been stored locally by callers) >+ SearchParticipant participant = SearchEngine.getDefaultSearchParticipant(); >+ if (!this.manager.resetIndex(this.containerPath)) { >+ // failed to recreate index, see 73330 >+ this.manager.removeIndex(this.containerPath); >+ return false; >+ } >+ index.separator = JAR_SEPARATOR; > >+ // Read zip entries >+ Map sources = this.sourcePath == null ? null : new HashMap(); >+ if (this.sourcePath != null && this.containerPath.toString().equals(this.sourcePath.toString())) { >+ >+ // if sources are in the jar itself index both class and source entries in sequence >+ List classFileNames = new ArrayList(); >+ for (Enumeration e = zip.entries(); e.hasMoreElements();) { >+ if (this.isCancelled) { >+ if (verbose) >+ org.eclipse.jdt.internal.core.util.Util.verbose("-> indexing of " + zip.getName() + " has been cancelled"); //$NON-NLS-1$ //$NON-NLS-2$ >+ return false; >+ } >+ ZipEntry ze = (ZipEntry) e.nextElement(); >+ String zeName = ze.getName(); >+ if (Util.isClassFileName(zeName)) { >+ final byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getZipEntryByteContent(ze, zip); >+ JavaSearchDocument searchDocument = new JavaSearchDocument(ze, zipFilePath, classFileBytes, participant); >+ this.manager.indexDocument(searchDocument, participant, index, this.containerPath); >+// if (classFileNames.remove(zeName)) { >+// String javaFileName = zeName.substring(0, zeName.length()-SuffixConstants.SUFFIX_class.length) + SuffixConstants.SUFFIX_STRING_java; >+// sources.put(zeName, javaFileName); >+// } else { >+ classFileNames.add(zeName); >+// } >+ } >+ else if (Util.isJavaFileName(zeName)) { >+ String classFileName = zeName.substring(0, zeName.length()-SuffixConstants.SUFFIX_java.length) + SuffixConstants.SUFFIX_STRING_class; >+ if (classFileNames.remove(classFileName)) { >+ int idx = classFileName.lastIndexOf('/'); >+ String sourceName = zeName.substring(idx+1); >+ sources.put(classFileName, sourceName); >+// } else { >+// classFileNames.add(classFileName); >+ } >+ } >+ } >+ } else { >+ // common case where there's no sources or they are in another location > for (Enumeration e = zip.entries(); e.hasMoreElements();) { > if (this.isCancelled) { >- if (JobManager.VERBOSE) >+ if (verbose) > org.eclipse.jdt.internal.core.util.Util.verbose("-> indexing of " + zip.getName() + " has been cancelled"); //$NON-NLS-1$ //$NON-NLS-2$ > return false; > } > >- // iterate each entry to index it >+ // only look at the class file entries > ZipEntry ze = (ZipEntry) e.nextElement(); >- if (Util.isClassFileName(ze.getName())) { >+ String zeName = ze.getName(); >+ if (Util.isClassFileName(zeName)) { >+ >+ // read class file contents > final byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getZipEntryByteContent(ze, zip); >- JavaSearchDocument entryDocument = new JavaSearchDocument(ze, zipFilePath, classFileBytes, participant); >- this.manager.indexDocument(entryDocument, participant, index, this.containerPath); >+ String documentPath = zipFilePath + IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR + ze; >+ ClassFileReader classFileReader; >+ try { >+ classFileReader = new ClassFileReader(classFileBytes, documentPath.toCharArray()); >+ } catch (ClassFormatException e1) { >+ // invalid class file >+ continue; >+ } >+ >+ // index the class file >+ JavaSearchDocument searchDocument = new JavaSearchDocument(ze, zipFilePath, classFileBytes, participant); >+ searchDocument.classFileReader = classFileReader; >+ this.manager.indexDocument(searchDocument, participant, index, this.containerPath); >+ >+ // store source name if any >+ if (this.sourcePath != null) { >+ char[] sourceFileName = classFileReader.sourceFileName(); >+ if (sourceFileName == null) { >+ // try by changing the file extension to .java >+ sourceFileName = (zeName.substring(0, zeName.length()-SuffixConstants.SUFFIX_java.length) + SuffixConstants.SUFFIX_STRING_class).toCharArray(); >+ } >+ if (sourceFileName != null) { >+ String sourceName = new String(sourceFileName); >+ if (classFileReader.getInnerSourceName() == null && classFileReader.getEnclosingTypeName() == null) { >+ // only store source for top level types >+ sources.put(zeName, sourceName); >+ } >+ } >+ } > } > } >+ } >+ if (sources == null || sources.size() == 0) { >+ // save index of jar file with attached source will be done while indexing source >+ // otherwise there will be a problem during the merge of the source index >+ // which contains only names and field references > this.manager.saveIndex(index); >- if (JobManager.VERBOSE) >- org.eclipse.jdt.internal.core.util.Util.verbose("-> done indexing of " //$NON-NLS-1$ >- + zip.getName() + " (" //$NON-NLS-1$ >- + (System.currentTimeMillis() - initialTime) + "ms)"); //$NON-NLS-1$ >- } finally { >- if (zip != null) { >- if (JavaModelManager.ZIP_ACCESS_VERBOSE) >- System.out.println("(" + Thread.currentThread() + ") [AddJarFileToIndex.execute()] Closing ZipFile " + zip); //$NON-NLS-1$ //$NON-NLS-2$ >- zip.close(); >- } >- monitor.exitWrite(); // free write lock >- } >- } catch (IOException e) { >- if (JobManager.VERBOSE) { >- org.eclipse.jdt.internal.core.util.Util.verbose("-> failed to index " + this.containerPath + " because of the following exception:"); //$NON-NLS-1$ //$NON-NLS-2$ >- e.printStackTrace(); >+ } else { >+ // create request to index stored sources >+ AddSourceZipToIndex zipToIndex = new AddSourceZipToIndex(this, zipFilePath, sources); >+ this.manager.request(zipToIndex, JobManager.LOW_PRIORITY); > } >- this.manager.removeIndex(this.containerPath); >- return false; >+ >+ if (verbose) >+ org.eclipse.jdt.internal.core.util.Util.verbose("-> done indexing of " //$NON-NLS-1$ >+ + zip.getName() + " (" //$NON-NLS-1$ >+ + (System.currentTimeMillis() - initialTime) + "ms)"); //$NON-NLS-1$ >+ } finally { >+ modelManager.flushZipFiles(); >+ monitor.exitWrite(); // free write lock > } >- return true; >- } >- public String getJobFamily() { >- if (this.resource != null) >- return super.getJobFamily(); >- return this.containerPath.toOSString(); // external jar >- } >- protected Integer updatedIndexState() { >- return IndexManager.REBUILDING_STATE; >- } >- public String toString() { >- return "indexing " + this.containerPath.toString(); //$NON-NLS-1$ >+ } catch (IOException e) { >+ if (verbose) { >+ org.eclipse.jdt.internal.core.util.Util.verbose("-> failed to index " + this.containerPath + " because of the following exception:"); //$NON-NLS-1$ //$NON-NLS-2$ >+ e.printStackTrace(); >+ } >+ this.manager.removeIndex(this.containerPath); >+ return false; > } >+ return true; >+} >+public String getJobFamily() { >+ if (this.resource != null) >+ return super.getJobFamily(); >+ return this.containerPath.toOSString(); // external jar >+} >+protected Integer updatedIndexState() { >+ return IndexManager.REBUILDING_STATE; >+} >+public String toString() { >+ return "indexing " + this.containerPath.toString(); //$NON-NLS-1$ >+} > } >Index: search/org/eclipse/jdt/internal/core/search/indexing/BinaryIndexer.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/BinaryIndexer.java,v >retrieving revision 1.68 >diff -u -r1.68 BinaryIndexer.java >--- search/org/eclipse/jdt/internal/core/search/indexing/BinaryIndexer.java 27 Jun 2008 16:03:49 -0000 1.68 >+++ search/org/eclipse/jdt/internal/core/search/indexing/BinaryIndexer.java 4 Nov 2008 15:31:20 -0000 >@@ -27,6 +27,7 @@ > import org.eclipse.jdt.internal.compiler.lookup.TagBits; > import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; > import org.eclipse.jdt.internal.compiler.util.SuffixConstants; >+import org.eclipse.jdt.internal.core.search.JavaSearchDocument; > import org.eclipse.jdt.internal.core.util.Util; > > public class BinaryIndexer extends AbstractIndexer implements SuffixConstants { >@@ -616,11 +617,29 @@ > public void indexDocument() { > try { > final byte[] contents = this.document.getByteContents(); >- // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=107124 > // contents can potentially be null if a IOException occurs while retrieving the contents >- if (contents == null) return; >+ // (see see https://bugs.eclipse.org/bugs/show_bug.cgi?id=107124) >+ // or when there's an attached source (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=12044) >+ ClassFileReader reader = null; >+ if (this.document instanceof JavaSearchDocument) { >+ JavaSearchDocument javaSearchDocument = (JavaSearchDocument) this.document; >+ if (contents == null) { >+ if (javaSearchDocument.sourcePath != null) { >+ char[] source = javaSearchDocument.getCharContents(); >+ if (source.length != 0) { >+ // the source exists, then prefer to index it instead of the class file >+ SourceIndexer sourceIndexer = new SourceIndexer(this.document); >+ sourceIndexer.indexDocument(); >+ } >+ } >+ return; >+ } >+ reader = javaSearchDocument.classFileReader; >+ } > final String path = this.document.getPath(); >- ClassFileReader reader = new ClassFileReader(contents, path == null ? null : path.toCharArray()); >+ if (reader == null) { >+ reader = new ClassFileReader(contents, path == null ? null : path.toCharArray()); >+ } > > // first add type references > char[] className = replace('/', '.', reader.getName()); // looks like java/lang/String >Index: search/org/eclipse/jdt/internal/core/search/indexing/SourceIndexer.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/SourceIndexer.java,v >retrieving revision 1.45 >diff -u -r1.45 SourceIndexer.java >--- search/org/eclipse/jdt/internal/core/search/indexing/SourceIndexer.java 18 Sep 2008 07:53:32 -0000 1.45 >+++ search/org/eclipse/jdt/internal/core/search/indexing/SourceIndexer.java 4 Nov 2008 15:31:20 -0000 >@@ -16,6 +16,7 @@ > import org.eclipse.core.runtime.Path; > import org.eclipse.jdt.core.JavaCore; > import org.eclipse.jdt.core.search.SearchDocument; >+import org.eclipse.jdt.internal.compiler.ISourceElementRequestor; > import org.eclipse.jdt.internal.compiler.SourceElementParser; > import org.eclipse.jdt.internal.compiler.util.SuffixConstants; > import org.eclipse.jdt.internal.core.JavaModelManager; >@@ -42,8 +43,14 @@ > } > public void indexDocument() { > // Create a new Parser >- SourceIndexerRequestor requestor = new SourceIndexerRequestor(this); > String documentPath = this.document.getPath(); >+ ISourceElementRequestor requestor; >+ if (documentPath.endsWith(SUFFIX_STRING_class)) { >+ // specific case of attached source, use a reduced requestor >+ requestor = new AttachedSourceIndexerRequestor(this); >+ } else { >+ requestor = new SourceIndexerRequestor(this); >+ } > SourceElementParser parser = this.document.getParser(); > if (parser == null) { > IPath path = new Path(documentPath); >Index: model/org/eclipse/jdt/internal/core/DeltaProcessor.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java,v >retrieving revision 1.330 >diff -u -r1.330 DeltaProcessor.java >--- model/org/eclipse/jdt/internal/core/DeltaProcessor.java 9 Oct 2008 08:13:07 -0000 1.330 >+++ model/org/eclipse/jdt/internal/core/DeltaProcessor.java 4 Nov 2008 15:31:18 -0000 >@@ -862,8 +862,9 @@ > continue; > } > for (int j = 0; j < entries.length; j++){ >- if (entries[j].getEntryKind() == IClasspathEntry.CPE_LIBRARY) { >- IPath entryPath = entries[j].getPath(); >+ IClasspathEntry entry = entries[j]; >+ if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) { >+ IPath entryPath = entry.getPath(); > > if (!archivePathsToRefresh.contains(entryPath)) continue; // not supposed to be refreshed > >@@ -902,7 +903,7 @@ > // first remove the index so that it is forced to be re-indexed > this.manager.indexManager.removeIndex(entryPath); > // then index the jar >- this.manager.indexManager.indexLibrary(entryPath, project.getProject()); >+ this.manager.indexManager.indexLibrary(entry, javaProject); > } else { > externalArchivesStatus.put(entryPath, EXTERNAL_JAR_UNCHANGED); > } >@@ -913,7 +914,7 @@ > externalArchivesStatus.put(entryPath, EXTERNAL_JAR_ADDED); > this.state.getExternalLibTimeStamps().put(entryPath, new Long(newTimeStamp)); > // index the new jar >- this.manager.indexManager.indexLibrary(entryPath, project.getProject()); >+ this.manager.indexManager.indexLibrary(entry, javaProject); > } > } > } else { // internal JAR >@@ -2503,13 +2504,13 @@ > switch (delta.getKind()) { > case IResourceDelta.ADDED: > // index the new jar >- indexManager.indexLibrary(jarPath, root.getJavaProject().getProject()); >+ indexManager.indexPackageFragmentRoot(root); > break; > case IResourceDelta.CHANGED: > // first remove the index so that it is forced to be re-indexed > indexManager.removeIndex(jarPath); > // then index the jar >- indexManager.indexLibrary(jarPath, root.getJavaProject().getProject()); >+ indexManager.indexPackageFragmentRoot(root); > break; > case IResourceDelta.REMOVED: > // the jar was physically removed: remove the index >Index: model/org/eclipse/jdt/internal/core/SourceMapper.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java,v >retrieving revision 1.139 >diff -u -r1.139 SourceMapper.java >--- model/org/eclipse/jdt/internal/core/SourceMapper.java 29 Aug 2008 18:53:24 -0000 1.139 >+++ model/org/eclipse/jdt/internal/core/SourceMapper.java 4 Nov 2008 15:31:19 -0000 >@@ -10,7 +10,6 @@ > *******************************************************************************/ > package org.eclipse.jdt.internal.core; > >-import java.io.IOException; > import java.util.ArrayList; > import java.util.Collections; > import java.util.Comparator; >@@ -24,7 +23,6 @@ > import java.util.zip.ZipFile; > > import org.eclipse.core.resources.IContainer; >-import org.eclipse.core.resources.IFile; > import org.eclipse.core.resources.IFolder; > import org.eclipse.core.resources.IResource; > import org.eclipse.core.resources.ResourcesPlugin; >@@ -897,43 +895,70 @@ > } else { > newFullName = name; > } >- return this.findSource(newFullName); >+ return org.eclipse.jdt.internal.core.util.Util.findSource(this.sourcePath, newFullName); > } > >- public char[] findSource(String fullName) { >- char[] source = null; >- Object target = JavaModel.getTarget(this.sourcePath, true); >- if (target instanceof IContainer) { >- IResource res = ((IContainer)target).findMember(fullName); >- if (res instanceof IFile) { >- try { >- source = org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray((IFile)res); >- } catch (JavaModelException e) { >- // ignore >- } >- } >- } else { >- // try to get the entry >- ZipEntry entry = null; >- ZipFile zip = null; >- JavaModelManager manager = JavaModelManager.getJavaModelManager(); >- try { >- zip = manager.getZipFile(this.sourcePath); >- entry = zip.getEntry(fullName); >- if (entry != null) { >- // now read the source code >- source = readSource(entry, zip); >+ /** >+ * Locates and returns the source file path for the given (binary) type, in this >+ * SourceMapper's ZIP file, or returns <code>null</code> if source file >+ * cannot be found. >+ * The given simpleSourceFileName is the .java file name (without the enclosing >+ * folder) used to create the given type (e.g. "A.java" for x/y/A$Inner.class) >+ * >+ * @see #findSource(IType, String) >+ */ >+ public String findSourceFilePath(IType type, String simpleSourceFileName) { >+ long time = 0; >+ if (VERBOSE) { >+ time = System.currentTimeMillis(); >+ } >+ PackageFragment pkgFrag = (PackageFragment) type.getPackageFragment(); >+ String name = org.eclipse.jdt.internal.core.util.Util.concatWith(pkgFrag.names, simpleSourceFileName, '/'); >+ >+ String sourceFilePath = null; >+ >+ if (this.rootPath != null) { >+ sourceFilePath = findSourceFilePath(this.rootPath, name); >+ } >+ >+ if (sourceFilePath == null) { >+ computeAllRootPaths(type); >+ if (this.rootPaths != null) { >+ loop: for (Iterator iterator = this.rootPaths.iterator(); iterator.hasNext(); ) { >+ String currentRootPath = (String) iterator.next(); >+ if (!currentRootPath.equals(this.rootPath)) { >+ sourceFilePath = findSourceFilePath(currentRootPath, name); >+ if (sourceFilePath != null) { >+ // remember right root path >+ this.rootPath = currentRootPath; >+ break loop; >+ } >+ } > } >- } catch (CoreException e) { >- return null; >- } finally { >- manager.closeZipFile(zip); // handle null case > } > } >- return source; >+ if (VERBOSE) { >+ System.out.println("spent " + (System.currentTimeMillis() - time) + "ms for " + type.getElementName()); //$NON-NLS-1$ //$NON-NLS-2$ >+ } >+ return sourceFilePath; > } > >- >+ private String findSourceFilePath(String currentRootPath, String name) { >+ String newFullName; >+ if (!currentRootPath.equals(IPackageFragmentRoot.DEFAULT_PACKAGEROOT_PATH)) { >+ if (currentRootPath.endsWith("/")) { //$NON-NLS-1$ >+ newFullName = currentRootPath + name; >+ } else { >+ newFullName = currentRootPath + '/' + name; >+ } >+ } else { >+ newFullName = name; >+ } >+ if (org.eclipse.jdt.internal.core.util.Util.findSource(this.sourcePath, newFullName, false/* do not get contents */) != null) { >+ return newFullName; >+ } >+ return null; >+ } > > /** > * Returns the SourceRange for the name of the given element, or >@@ -1245,17 +1270,6 @@ > this.typeDepth = -1; > } > } >- private char[] readSource(ZipEntry entry, ZipFile zip) { >- try { >- byte[] bytes = Util.getZipEntryByteContent(entry, zip); >- if (bytes != null) { >- return Util.bytesToChar(bytes, this.encoding); >- } >- } catch (IOException e) { >- // ignore >- } >- return null; >- } > > /** > * Sets the mapping for this method to its parameter names. >Index: model/org/eclipse/jdt/internal/core/ClasspathChange.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathChange.java,v >retrieving revision 1.22 >diff -u -r1.22 ClasspathChange.java >--- model/org/eclipse/jdt/internal/core/ClasspathChange.java 9 Oct 2008 08:13:07 -0000 1.22 >+++ model/org/eclipse/jdt/internal/core/ClasspathChange.java 4 Nov 2008 15:31:18 -0000 >@@ -457,6 +457,8 @@ > > int newLength = newResolvedClasspath.length; > int oldLength = this.oldResolvedClasspath.length; >+ >+ // First, look at removed classpath entries > for (int i = 0; i < oldLength; i++) { > int index = classpathContains(newResolvedClasspath, this.oldResolvedClasspath[i]); > if (index == -1) { >@@ -487,20 +489,22 @@ > } > } > >+ // Then, look at created or changed classpath entries > for (int i = 0; i < newLength; i++) { >- int index = classpathContains(this.oldResolvedClasspath, newResolvedClasspath[i]); >+ IClasspathEntry entry = newResolvedClasspath[i]; >+ int index = classpathContains(this.oldResolvedClasspath, entry); > if (index == -1) { > // remote projects are not indexed in this project >- if (newResolvedClasspath[i].getEntryKind() == IClasspathEntry.CPE_PROJECT){ >+ if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT){ > continue; > } > >- // Request indexing >- int entryKind = newResolvedClasspath[i].getEntryKind(); >+ // Request indexing for the removed classpath entry >+ int entryKind = entry.getEntryKind(); > switch (entryKind) { > case IClasspathEntry.CPE_LIBRARY: > boolean pathHasChanged = true; >- IPath newPath = newResolvedClasspath[i].getPath(); >+ IPath newPath = entry.getPath(); > for (int j = 0; j < oldLength; j++) { > IClasspathEntry oldEntry = this.oldResolvedClasspath[j]; > if (oldEntry.getPath().equals(newPath)) { >@@ -509,11 +513,10 @@ > } > } > if (pathHasChanged) { >- indexManager.indexLibrary(newPath, this.project.getProject()); >+ indexManager.indexLibrary(entry, this.project); > } > break; > case IClasspathEntry.CPE_SOURCE: >- IClasspathEntry entry = newResolvedClasspath[i]; > IPath path = entry.getPath(); > char[][] inclusionPatterns = ((ClasspathEntry)entry).fullInclusionPatternChars(); > char[][] exclusionPatterns = ((ClasspathEntry)entry).fullExclusionPatternChars(); >@@ -521,6 +524,18 @@ > break; > } > } >+ // since bug 12044, source attached are indexed instead of class files >+ // hence needs to verify whether the source attachment has changed or not >+ else if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) { >+ IPath srcPath = entry.getSourceAttachmentPath(); >+ IPath oldSrcPath = this.oldResolvedClasspath[index].getSourceAttachmentPath(); >+ Util.verbose("Classpath entry src change from "+oldSrcPath+" to "+srcPath); >+ if (srcPath == null && oldSrcPath != null) { >+ indexManager.removeIndex(entry.getPath()); >+ } else if (srcPath != null && !srcPath.equals(oldSrcPath)) { >+ indexManager.indexLibrary(entry, this.project); >+ } >+ } > } > } > >Index: model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java,v >retrieving revision 1.133 >diff -u -r1.133 PackageFragmentRoot.java >--- model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java 27 Jun 2008 16:03:50 -0000 1.133 >+++ model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java 4 Nov 2008 15:31:18 -0000 >@@ -573,7 +573,16 @@ > */ > public IPath getSourceAttachmentPath() throws JavaModelException { > if (getKind() != K_BINARY) return null; >+ return sourceAttachmentPath(); >+} > >+/** >+ * @see IPackageFragmentRoot#getSourceAttachmentPath() >+ * Returns the same result but without opening the package fragment root. >+ * However, no verification is done on the package fragment root kind, hence >+ * provides an unpredictable result if it is not a {@link IPackageFragmentRoot#K_BINARY}. >+ */ >+public IPath sourceAttachmentPath() throws JavaModelException { > // 1) look source attachment property (set iff attachSource(...) was called > IPath path = getPath(); > String serverPathString= Util.getSourceAttachmentProperty(path); >@@ -618,7 +627,16 @@ > */ > public IPath getSourceAttachmentRootPath() throws JavaModelException { > if (getKind() != K_BINARY) return null; >+ return sourceAttachmentRootPath(); >+} > >+/** >+ * @see IPackageFragmentRoot#getSourceAttachmentRootPath() >+ * Returns the same result but without opening the package fragment root. >+ * However, no verification is done on the package fragment root kind, hence >+ * provides an unpredictable result if it is not a {@link IPackageFragmentRoot#K_BINARY}. >+ */ >+public IPath sourceAttachmentRootPath() throws JavaModelException { > // 1) look source attachment property (set iff attachSource(...) was called > IPath path = getPath(); > String serverPathString= Util.getSourceAttachmentProperty(path); >Index: model/org/eclipse/jdt/internal/core/util/Util.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Util.java,v >retrieving revision 1.125 >diff -u -r1.125 Util.java >--- model/org/eclipse/jdt/internal/core/util/Util.java 23 Oct 2008 13:56:41 -0000 1.125 >+++ model/org/eclipse/jdt/internal/core/util/Util.java 4 Nov 2008 15:31:19 -0000 >@@ -61,6 +61,7 @@ > import org.eclipse.jdt.internal.core.Annotation; > import org.eclipse.jdt.internal.core.ClassFile; > import org.eclipse.jdt.internal.core.JavaElement; >+import org.eclipse.jdt.internal.core.JavaModel; > import org.eclipse.jdt.internal.core.JavaModelManager; > import org.eclipse.jdt.internal.core.Member; > import org.eclipse.jdt.internal.core.MemberValuePair; >@@ -725,6 +726,72 @@ > return null; > } > >+ /** >+ * Find source of the file name supposed to be located in the given source path or null >+ * if the corresponding file was not found. >+ * >+ * @param sourcePath The path of the container. May be a zip file or a folder >+ * @param fileName The full name of the file (e.g. java/lang/Object.java) >+ * @return The contents of the file or <code>null</code> if the file was not found. >+ */ >+ public static char[] findSource(IPath sourcePath, String fileName) { >+ return (char[]) findSource(sourcePath, fileName, true/*get contents*/); >+ } >+ >+ /** >+ * Find the file supposed to be located in the given source path >+ * or null if the corresponding file was not found. >+ * >+ * @param sourcePath The path of the container. May be a zip file or a folder >+ * @param fileName The full name of the file (e.g. java/lang/Object.java) >+ * @param contents Indicates whether the method returns the file or its contents >+ * @return If the file was found then returns a {@link IResource} or a >+ * {@link ZipEntry} if no contents was required, <code>char[]</code> otherwise. >+ * Returns <code>null</code> if the file was not found. >+ */ >+ public static Object findSource(IPath sourcePath, String fileName, boolean contents) { >+ Object target = JavaModel.getTarget(sourcePath, true); >+ if (target instanceof IContainer) { >+ IResource res = ((IContainer)target).findMember(fileName); >+ if (res instanceof IFile) { >+ if (contents) { >+ try { >+ return org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray((IFile)res); >+ } catch (JavaModelException e) { >+ // skip >+ } >+ return null; >+ } >+ return res; >+ } >+ } else { >+ // try to get the entry >+ ZipEntry entry = null; >+ ZipFile zip = null; >+ JavaModelManager manager = JavaModelManager.getJavaModelManager(); >+ try { >+ zip = manager.getZipFile(sourcePath); >+ entry = zip.getEntry(fileName); >+ if (entry != null) { >+ if (contents) { >+ try { >+ return org.eclipse.jdt.internal.compiler.util.Util.getZipEntryCharContent(entry, zip, null/*default charset encoding*/); >+ } catch (IOException e) { >+ // skip >+ } >+ return null; >+ } >+ return entry; >+ } >+ } catch (CoreException e) { >+ return null; >+ } finally { >+ manager.closeZipFile(zip); // handle null case >+ } >+ } >+ return null; >+ } >+ > public static IClassFileAttribute getAttribute(IClassFileReader classFileReader, char[] attributeName) { > IClassFileAttribute[] attributes = classFileReader.getAttributes(); > for (int i = 0, max = attributes.length; i < max; i++) { >Index: search/org/eclipse/jdt/internal/core/index/Index.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/Index.java,v >retrieving revision 1.31 >diff -u -r1.31 Index.java >--- search/org/eclipse/jdt/internal/core/index/Index.java 27 Jun 2008 16:04:14 -0000 1.31 >+++ search/org/eclipse/jdt/internal/core/index/Index.java 4 Nov 2008 15:31:19 -0000 >@@ -172,6 +172,16 @@ > public void remove(String containerRelativePath) { > this.memoryIndex.remove(containerRelativePath); > } >+/** >+ * Reset memory and disk indexes. >+ * >+ * @throws IOException >+ */ >+public void reset(boolean reuseExistingFile) throws IOException { >+ this.memoryIndex = new MemoryIndex(); >+ this.diskIndex = new DiskIndex(this.diskIndex.indexFile.getCanonicalPath()); >+ this.diskIndex.initialize(reuseExistingFile); >+} > public void save() throws IOException { > // must own the write lock of the monitor > if (!hasChanged()) return; >Index: search/org/eclipse/jdt/internal/core/index/DiskIndex.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/DiskIndex.java,v >retrieving revision 1.67 >diff -u -r1.67 DiskIndex.java >--- search/org/eclipse/jdt/internal/core/index/DiskIndex.java 27 Jun 2008 16:04:14 -0000 1.67 >+++ search/org/eclipse/jdt/internal/core/index/DiskIndex.java 4 Nov 2008 15:31:19 -0000 >@@ -46,7 +46,7 @@ > private int streamEnd; // used when writing data from the streamBuffer to the file > char separator = Index.DEFAULT_SEPARATOR; > >-public static final String SIGNATURE= "INDEX VERSION 1.125"; //$NON-NLS-1$ >+public static final String SIGNATURE= "INDEX VERSION 1.126.1"; //$NON-NLS-1$ > private static final char[] SIGNATURE_CHARS = SIGNATURE.toCharArray(); > public static boolean DEBUG = false; > >@@ -616,6 +616,7 @@ > try { > if (size < 0) { // DEBUG > System.err.println("-------------------- DEBUG --------------------"); //$NON-NLS-1$ >+ System.err.println("thread = "+Thread.currentThread()); //$NON-NLS-1$ > System.err.println("file = "+this.indexFile); //$NON-NLS-1$ > System.err.println("offset = "+offset); //$NON-NLS-1$ > System.err.println("size = "+size); //$NON-NLS-1$ >@@ -626,6 +627,7 @@ > // DEBUG > oom.printStackTrace(); > System.err.println("-------------------- DEBUG --------------------"); //$NON-NLS-1$ >+ System.err.println("thread = "+Thread.currentThread()); //$NON-NLS-1$ > System.err.println("file = "+this.indexFile); //$NON-NLS-1$ > System.err.println("offset = "+offset); //$NON-NLS-1$ > System.err.println("size = "+size); //$NON-NLS-1$ >Index: search/org/eclipse/jdt/internal/core/search/JavaSearchDocument.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchDocument.java,v >retrieving revision 1.16 >diff -u -r1.16 JavaSearchDocument.java >--- search/org/eclipse/jdt/internal/core/search/JavaSearchDocument.java 27 Jun 2008 16:04:09 -0000 1.16 >+++ search/org/eclipse/jdt/internal/core/search/JavaSearchDocument.java 4 Nov 2008 15:31:20 -0000 >@@ -16,9 +16,13 @@ > import org.eclipse.core.runtime.IPath; > import org.eclipse.core.runtime.Path; > import org.eclipse.jdt.core.JavaModelException; >+import org.eclipse.jdt.core.compiler.CharOperation; > import org.eclipse.jdt.core.search.IJavaSearchScope; > import org.eclipse.jdt.core.search.SearchDocument; > import org.eclipse.jdt.core.search.SearchParticipant; >+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader; >+import org.eclipse.jdt.internal.compiler.util.SuffixConstants; >+import org.eclipse.jdt.internal.core.search.indexing.IIndexConstants; > import org.eclipse.jdt.internal.core.search.processing.JobManager; > import org.eclipse.jdt.internal.core.util.Util; > >@@ -27,6 +31,10 @@ > private IFile file; > protected byte[] byteContents; > protected char[] charContents; >+ public IPath sourcePath; // path of the folder or the zip file containing the attached source >+ private String relativeSourcePath; // relative path from the source path >+ private String containerRelativePath; // same as SearchDocument >+ public ClassFileReader classFileReader; // may be set by by the AddJarFileToIndex > > public JavaSearchDocument(String documentPath, SearchParticipant participant) { > super(documentPath, participant); >@@ -35,9 +43,15 @@ > super(zipFilePath + IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR + zipEntry.getName(), participant); > this.byteContents = contents; > } >+ public JavaSearchDocument(String documentPath, IPath sourcePath, String filePath, SearchParticipant participant) { >+ this(documentPath, participant); >+ this.relativeSourcePath = filePath; >+ this.sourcePath = sourcePath; >+ } > > public byte[] getByteContents() { > if (this.byteContents != null) return this.byteContents; >+ if (this.sourcePath != null) return null; > try { > return Util.getResourceContentsAsByteArray(getFile()); > } catch (JavaModelException e) { >@@ -49,14 +63,21 @@ > } > public char[] getCharContents() { > if (this.charContents != null) return this.charContents; >+ >+ // The source may be found through an attachment >+ if (this.sourcePath != null) { >+ return Util.findSource(this.sourcePath, this.relativeSourcePath); >+ } >+ >+ // Get file contents > try { > return Util.getResourceContentsAsCharArray(getFile()); > } catch (JavaModelException e) { > if (BasicSearchEngine.VERBOSE || JobManager.VERBOSE) { // used during search and during indexing > e.printStackTrace(); > } >- return null; > } >+ return null; > } > public String getEncoding() { > // Return the encoding of the associated file >@@ -83,4 +104,90 @@ > public String toString() { > return "SearchDocument for " + getPath(); //$NON-NLS-1$ > } >+ >+ /** >+ * Override the super implementation to change the document path >+ * if there's an attached source and the enclosing type names >+ * >+ * @see SearchDocument#addIndexEntry(char[], char[]) >+ */ >+ public void addIndexEntry(char[] category, char[] key) { >+ this.containerRelativePath = null; >+ if (this.sourcePath != null) { >+ switch (category[0]) { >+ case 's': >+ if (CharOperation.equals(IIndexConstants.SUPER_REF, category)) { >+ // decode the key to get enclosing type names (see SuperTypeReferencePattern.decodeIndexKey(char[]) >+ int slash = CharOperation.indexOf(IIndexConstants.SEPARATOR, key); >+ slash = CharOperation.indexOf(IIndexConstants.SEPARATOR, key, slash+1); >+ slash = CharOperation.indexOf(IIndexConstants.SEPARATOR, key, slash+1); >+ if (key[slash+1] != IIndexConstants.SEPARATOR) { >+ // there's enclosing types >+ int end = CharOperation.indexOf(IIndexConstants.SEPARATOR, key, slash+1); >+ String relativePath = getContainerRelativePath(); >+ char[] enclosingTypes = CharOperation.subarray(key, slash+1, end); >+ int length = enclosingTypes.length; >+ if (length != 1 || enclosingTypes[length-1] != '0') { >+ // neither an anonymous nor a local type >+ this.containerRelativePath = relativePath.substring(0, relativePath.length()-SuffixConstants.SUFFIX_STRING_class.length()) >+ + '$' + new String(enclosingTypes) + SuffixConstants.SUFFIX_STRING_class; >+ } >+ } >+ } >+ break; >+ case 't': >+ if (CharOperation.equals(IIndexConstants.TYPE_DECL, category)) { >+ // decode the key to get enclosing type names (see TypeDeclarationPattern.decodeIndexKey(char[]) >+ int end = key.length-1; >+ if (key[end] == 'S') { >+ end -= 2; >+ } >+ end -= 3; >+ if (key[end] != IIndexConstants.SEPARATOR) { >+ // there's enclosing types >+ int slash = CharOperation.lastIndexOf(IIndexConstants.SEPARATOR, key, 0, end); >+ String relativePath = getContainerRelativePath(); >+ char[] enclosingTypes = CharOperation.subarray(key, slash+1, end); >+ int length = enclosingTypes.length; >+ if (length != 1 || enclosingTypes[length-1] != '0') { >+ // neither an anonymous nor a local type >+ this.containerRelativePath = relativePath.substring(0, relativePath.length()-SuffixConstants.SUFFIX_STRING_class.length()) >+ + '$' + new String(enclosingTypes) + SuffixConstants.SUFFIX_STRING_class; >+ } >+ } >+ } >+ break; >+ } >+ } >+ super.addIndexEntry(category, key); >+ } >+ >+ /** >+ * Override the super implementation to take the changed document relative path >+ * if any. Reset this relative path to avoid any unwanted side effect. >+ * >+ * @see SearchDocument#getContainerRelativePath() >+ */ >+ protected String getContainerRelativePath() { >+ if (this.containerRelativePath == null) { >+ return super.getContainerRelativePath(); >+ } >+ String path = this.containerRelativePath; >+ this.containerRelativePath = null; >+ return path; >+ } >+ >+ /** >+ * Override the super implementation not to remove all entries when there's an >+ * attached source. Attached source indexing is not complete, hence previous >+ * entries set by the binary indexer need to be kept. >+ * >+ * @see SearchDocument#removeAllIndexEntries() >+ */ >+ public void removeAllIndexEntries() { >+ if (this.sourcePath != null) { >+ return; >+ } >+ super.removeAllIndexEntries(); >+ } > } >Index: search/org/eclipse/jdt/internal/core/search/BasicSearchEngine.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/BasicSearchEngine.java,v >retrieving revision 1.57 >diff -u -r1.57 BasicSearchEngine.java >--- search/org/eclipse/jdt/internal/core/search/BasicSearchEngine.java 31 Oct 2008 16:53:33 -0000 1.57 >+++ search/org/eclipse/jdt/internal/core/search/BasicSearchEngine.java 4 Nov 2008 15:31:20 -0000 >@@ -30,6 +30,7 @@ > import org.eclipse.jdt.internal.core.*; > import org.eclipse.jdt.internal.core.search.indexing.*; > import org.eclipse.jdt.internal.core.search.matching.*; >+import org.eclipse.jdt.internal.core.search.processing.JobManager; > import org.eclipse.jdt.internal.core.util.Messages; > import org.eclipse.jdt.internal.core.util.Util; > >@@ -206,6 +207,7 @@ > indexManager.performConcurrentJob( > new PatternSearchJob(pattern, participant, scope, pathCollector), > IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH, >+ JobManager.LOW_PRIORITY, // any search will wait for attached sources indexing to be finished > monitor==null ? null : new SubProgressMonitor(monitor, 50)); > if (monitor != null && monitor.isCanceled()) throw new OperationCanceledException(); > >Index: compiler/org/eclipse/jdt/internal/compiler/util/Util.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Util.java,v >retrieving revision 1.68 >diff -u -r1.68 Util.java >--- compiler/org/eclipse/jdt/internal/compiler/util/Util.java 27 Jun 2008 16:04:05 -0000 1.68 >+++ compiler/org/eclipse/jdt/internal/compiler/util/Util.java 4 Nov 2008 15:31:18 -0000 >@@ -22,6 +22,9 @@ > import java.util.StringTokenizer; > import java.util.zip.ZipEntry; > import java.util.zip.ZipFile; >+ >+import org.eclipse.core.resources.ResourcesPlugin; >+import org.eclipse.core.runtime.CoreException; > import org.eclipse.jdt.core.compiler.CharOperation; > import org.eclipse.jdt.internal.compiler.ClassFile; > import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; >@@ -450,10 +453,9 @@ > } > /** > * Returns the contents of the given zip entry as a byte array. >- * @throws IOException if a problem occured reading the zip entry. >+ * @throws IOException if a problem occurred reading the zip entry. > */ >- public static byte[] getZipEntryByteContent(ZipEntry ze, ZipFile zip) >- throws IOException { >+ public static byte[] getZipEntryByteContent(ZipEntry ze, ZipFile zip) throws IOException { > > InputStream stream = null; > try { >@@ -470,6 +472,26 @@ > } > } > } >+ /** >+ * Returns the contents of the given zip entry as a char array. >+ * @throws IOException if a problem occurred reading the zip entry or while >+ * converting the bytes array to chars. >+ */ >+ public static char[] getZipEntryCharContent(ZipEntry entry, ZipFile zip, String encoding) throws IOException { >+ byte[] bytes = getZipEntryByteContent(entry, zip); >+ if (bytes != null) { >+ String charEncoding = encoding; >+ try { >+ if (encoding == null) { >+ charEncoding = ResourcesPlugin.getWorkspace().getRoot().getDefaultCharset(); >+ } >+ } catch (CoreException e) { >+ // use no encoding >+ } >+ return bytesToChar(bytes, charEncoding); >+ } >+ return null; >+ } > > /** > * Returns whether the given name is potentially a zip archive file name >Index: search/org/eclipse/jdt/internal/core/search/indexing/AddSourceZipToIndex.java >=================================================================== >RCS file: search/org/eclipse/jdt/internal/core/search/indexing/AddSourceZipToIndex.java >diff -N search/org/eclipse/jdt/internal/core/search/indexing/AddSourceZipToIndex.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ search/org/eclipse/jdt/internal/core/search/indexing/AddSourceZipToIndex.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,185 @@ >+/******************************************************************************* >+ * Copyright (c) 2000, 2008 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jdt.internal.core.search.indexing; >+ >+import java.io.IOException; >+import java.util.Iterator; >+import java.util.Map; >+ >+import org.eclipse.core.runtime.IPath; >+import org.eclipse.core.runtime.IProgressMonitor; >+import org.eclipse.core.runtime.Path; >+import org.eclipse.jdt.core.IJavaProject; >+import org.eclipse.jdt.core.IPackageFragment; >+import org.eclipse.jdt.core.IPackageFragmentRoot; >+import org.eclipse.jdt.core.IType; >+import org.eclipse.jdt.core.JavaModelException; >+import org.eclipse.jdt.core.compiler.CharOperation; >+import org.eclipse.jdt.core.search.IJavaSearchScope; >+import org.eclipse.jdt.core.search.SearchEngine; >+import org.eclipse.jdt.core.search.SearchParticipant; >+import org.eclipse.jdt.internal.compiler.SourceElementParser; >+import org.eclipse.jdt.internal.core.JavaModelManager; >+import org.eclipse.jdt.internal.core.PackageFragmentRoot; >+import org.eclipse.jdt.internal.core.SourceMapper; >+import org.eclipse.jdt.internal.core.index.Index; >+import org.eclipse.jdt.internal.core.search.JavaSearchDocument; >+import org.eclipse.jdt.internal.core.search.processing.JobManager; >+import org.eclipse.jdt.internal.core.util.HashtableOfArrayToObject; >+ >+class AddSourceZipToIndex extends IndexRequest { >+ >+ private static final char JAR_SEPARATOR = IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR.charAt(0); >+ SourceMapper sourceMapper; >+ IPath sourcePath; >+ Map sources; >+ IPackageFragmentRoot packageFragmentRoot; >+ private HashtableOfArrayToObject packageHandles = new HashtableOfArrayToObject(); >+ IPath zipFilePath; >+ private IJavaProject javaProject; >+ >+public AddSourceZipToIndex(AddJarFileToIndex jarFileToIndex, IPath zipPath, Map sources) { >+ // external JAR scenario - no resource >+ super(jarFileToIndex.containerPath, jarFileToIndex.manager); >+ this.sourcePath = jarFileToIndex.sourcePath; >+ this.sources = sources; >+ this.zipFilePath = zipPath; >+ this.sourceMapper = jarFileToIndex.sourceMapper; >+ this.packageFragmentRoot = jarFileToIndex.packageFragmentRoot; >+ this.javaProject = jarFileToIndex.javaProject; >+} >+ >+private IType createType(String classFilePath) throws JavaModelException { >+ String[] simpleNames = new Path(classFilePath).segments(); >+ String[] pkgName; >+ int length = simpleNames.length-1; >+ if (length > 0) { >+ pkgName = new String[length]; >+ System.arraycopy(simpleNames, 0, pkgName, 0, length); >+ } else { >+ pkgName = CharOperation.NO_STRINGS; >+ } >+ IPackageFragment pkgFragment= (IPackageFragment) this.packageHandles.get(pkgName); >+ if (pkgFragment == null) { >+ pkgFragment= ((PackageFragmentRoot)this.packageFragmentRoot).getPackageFragment(pkgName); >+ this.packageHandles.put(pkgName, pkgFragment); >+ } >+ return pkgFragment.getClassFile(simpleNames[length]).getType(); >+} >+ >+public boolean equals(Object o) { >+ if (o instanceof AddSourceZipToIndex) { >+ if (this.sourcePath != null) { >+ return this.sourcePath.toOSString().equals(((AddSourceZipToIndex) o).sourcePath.toOSString()); >+ } >+ } >+ return false; >+} >+public int hashCode() { >+ if (this.sourcePath != null) >+ return this.sourcePath.hashCode(); >+ return -1; >+} >+public boolean execute(IProgressMonitor progressMonitor) { >+ >+ if (this.isCancelled || progressMonitor != null && progressMonitor.isCanceled()) return true; >+ boolean verbose = true; //JobManager.VERBOSE; >+ >+ try { >+ // always reuse existing index as there's no way to know whether sources has changed or not... >+ Index index = this.manager.getIndexForUpdate(this.containerPath, true, /*reuse index file*/ true /*create if none*/); >+ if (index == null) { >+ if (verbose) >+ org.eclipse.jdt.internal.core.util.Util.verbose("-> index could not be created for sources in " + this.containerPath); //$NON-NLS-1$ >+ return true; >+ } >+ ReadWriteMonitor monitor = index.monitor; >+ if (monitor == null) { >+ if (verbose) >+ org.eclipse.jdt.internal.core.util.Util.verbose("-> index for sources in " + this.containerPath + " just got deleted"); //$NON-NLS-1$//$NON-NLS-2$ >+ return true; // index got deleted since acquired >+ } >+ index.separator = JAR_SEPARATOR; >+ >+ JavaModelManager modelManager = JavaModelManager.getJavaModelManager(); >+ SourceElementParser parser = this.manager.getSourceElementParser(this.javaProject, null/*requestor will be set by indexer*/); >+ modelManager.cacheZipFiles(); >+ try { >+ monitor.enterWrite(); // ask permission to write (TODO see if this lock is necessary) >+ if (this.isCancelled) { >+ if (verbose) >+ org.eclipse.jdt.internal.core.util.Util.verbose("-> indexing source files in " + this.sourcePath.toString() + " has been cancelled"); //$NON-NLS-1$ //$NON-NLS-2$ >+ return false; >+ } >+ >+ if (verbose) >+ org.eclipse.jdt.internal.core.util.Util.verbose("-> indexing source files in " + this.sourcePath.toString()); //$NON-NLS-1$ >+ long initialTime = System.currentTimeMillis(); >+ >+ // Index the jar for the first time or reindex the jar in case the previous index file has been corrupted >+ // index already existed: recreate it so that we forget about previous entries >+ SearchParticipant participant = SearchEngine.getDefaultSearchParticipant(); >+ index.separator = JAR_SEPARATOR; >+ >+ // Index each attached source of the list >+ Iterator classFileNames = this.sources.keySet().iterator(); >+ String documentPrefix = this.zipFilePath.toString() + IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR; >+ while (classFileNames.hasNext()) { >+ String classFileName = (String) classFileNames.next(); >+ String sourceName = (String) this.sources.get(classFileName); >+ >+ // first get type >+ IType type = null; >+ try { >+ if (this.packageFragmentRoot != null) { >+ type = createType(classFileName); >+ } >+ } catch (JavaModelException jme) { >+ // ignore >+ } >+ if (type != null) { >+ // get path of the attached source file >+ String sourceFilePath = this.sourceMapper.findSourceFilePath(type, sourceName); >+ if (sourceFilePath != null) { >+ // index the document using the top level class file for its name >+ String documentPath = documentPrefix + classFileName; >+ JavaSearchDocument searchDocument = new JavaSearchDocument(documentPath, this.sourcePath, sourceFilePath, participant); >+ searchDocument.setParser(parser); >+ this.manager.indexDocument(searchDocument, participant, index, this.containerPath); >+ } >+ } >+ } >+ this.manager.saveIndex(index); >+ if (verbose) >+ org.eclipse.jdt.internal.core.util.Util.verbose("-> done indexing source files of " //$NON-NLS-1$ >+ + this.sourcePath.toString() + " (" //$NON-NLS-1$ >+ + (System.currentTimeMillis() - initialTime) + "ms)"); //$NON-NLS-1$ >+ } finally { >+ modelManager.flushZipFiles(); >+ monitor.exitWrite(); // free write lock >+ } >+ } catch (IOException e) { >+ if (verbose) { >+ org.eclipse.jdt.internal.core.util.Util.verbose("-> failed to index sources in " + this.containerPath + " because of the following exception:"); //$NON-NLS-1$ //$NON-NLS-2$ >+ e.printStackTrace(); >+ } >+ this.manager.removeIndex(this.containerPath); >+ return false; >+ } >+ return true; >+} >+protected Integer updatedIndexState() { >+ return IndexManager.REBUILDING_STATE; >+} >+public String toString() { >+ return "indexing " + this.sourcePath.toString(); //$NON-NLS-1$ >+} >+} >Index: search/org/eclipse/jdt/internal/core/search/indexing/AttachedSourceIndexerRequestor.java >=================================================================== >RCS file: search/org/eclipse/jdt/internal/core/search/indexing/AttachedSourceIndexerRequestor.java >diff -N search/org/eclipse/jdt/internal/core/search/indexing/AttachedSourceIndexerRequestor.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ search/org/eclipse/jdt/internal/core/search/indexing/AttachedSourceIndexerRequestor.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,144 @@ >+/******************************************************************************* >+ * Copyright (c) 2000, 2008 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jdt.internal.core.search.indexing; >+ >+import org.eclipse.jdt.core.compiler.CategorizedProblem; >+import org.eclipse.jdt.internal.compiler.ISourceElementRequestor; >+import org.eclipse.jdt.internal.compiler.ast.Expression; >+import org.eclipse.jdt.internal.compiler.ast.ImportReference; >+ >+/** >+ * This class is used by the JavaParserIndexer. When parsing the java file, the requestor >+ * recognizes the java elements (methods, fields, ...) and add them to an index. >+ */ >+public class AttachedSourceIndexerRequestor implements ISourceElementRequestor, IIndexConstants { >+ SourceIndexer indexer; >+ >+public AttachedSourceIndexerRequestor(SourceIndexer indexer) { >+ this.indexer = indexer; >+} >+/** >+ * @see ISourceElementRequestor#acceptAnnotationTypeReference(char[][], int, int) >+ */ >+public void acceptAnnotationTypeReference(char[][] typeName, int sourceStart, int sourceEnd) { >+ // already done while indexing the associated class file >+} >+/** >+ * @see ISourceElementRequestor#acceptAnnotationTypeReference(char[], int) >+ */ >+public void acceptAnnotationTypeReference(char[] simpleTypeName, int sourcePosition) { >+ // already done while indexing the associated class file >+} >+/** >+ * @see ISourceElementRequestor#acceptConstructorReference(char[], int, int) >+ */ >+public void acceptConstructorReference(char[] typeName, int argCount, int sourcePosition) { >+ // already done while indexing the associated class file >+} >+/** >+ * @see ISourceElementRequestor#acceptFieldReference(char[], int) >+ */ >+public void acceptFieldReference(char[] fieldName, int sourcePosition) { >+ this.indexer.addFieldReference(fieldName); >+} >+/** >+ * @see ISourceElementRequestor#acceptImport(int, int, char[][], boolean, int) >+ */ >+public void acceptImport(int declarationStart, int declarationEnd, char[][] tokens, boolean onDemand, int modifiers) { >+ // already done while indexing the associated class file >+} >+/** >+ * @see ISourceElementRequestor#acceptLineSeparatorPositions(int[]) >+ */ >+public void acceptLineSeparatorPositions(int[] positions) { >+ // already done while indexing the associated class file >+} >+/** >+ * @see ISourceElementRequestor#acceptMethodReference(char[], int, int) >+ */ >+public void acceptMethodReference(char[] methodName, int argCount, int sourcePosition) { >+ // already done while indexing the associated class file >+} >+/** >+ * @see ISourceElementRequestor#acceptPackage(ImportReference) >+ */ >+public void acceptPackage(ImportReference importReference) { >+ // already done while indexing the associated class file >+} >+/** >+ * @see ISourceElementRequestor#acceptProblem(CategorizedProblem) >+ */ >+public void acceptProblem(CategorizedProblem problem) { >+ // already done while indexing the associated class file >+} >+/** >+ * @see ISourceElementRequestor#acceptTypeReference(char[][], int, int) >+ */ >+public void acceptTypeReference(char[][] typeName, int sourceStart, int sourceEnd) { >+ // already done while indexing the associated class file >+} >+/** >+ * @see ISourceElementRequestor#acceptTypeReference(char[], int) >+ */ >+public void acceptTypeReference(char[] simpleTypeName, int sourcePosition) { >+ // already done while indexing the associated class file >+} >+/** >+ * @see ISourceElementRequestor#acceptUnknownReference(char[][], int, int) >+ */ >+public void acceptUnknownReference(char[][] name, int sourceStart, int sourceEnd) { >+ for (int i = 0; i < name.length; i++) { >+ this.indexer.addNameReference(name[i]); >+ } >+} >+/** >+ * @see ISourceElementRequestor#acceptUnknownReference(char[], int) >+ */ >+public void acceptUnknownReference(char[] name, int sourcePosition) { >+ this.indexer.addNameReference(name); >+} >+public void enterCompilationUnit() { >+ // do nothing >+} >+public void enterConstructor(MethodInfo methodInfo) { >+ // do nothing >+} >+public void enterField(FieldInfo fieldInfo) { >+ // do nothing >+} >+public void enterInitializer(int declarationStart, int modifiers) { >+ // do nothing >+} >+public void enterMethod(MethodInfo methodInfo) { >+ // do nothing >+} >+public void enterType(TypeInfo typeInfo) { >+ // do nothing >+} >+public void exitCompilationUnit(int declarationEnd) { >+ // do nothing >+} >+public void exitConstructor(int declarationEnd) { >+ // do nothing >+} >+public void exitField(int initializationStart, int declarationEnd, int declarationSourceEnd) { >+ // do nothing >+} >+public void exitInitializer(int declarationEnd) { >+ // do nothing >+} >+public void exitMethod(int declarationEnd, Expression defaultValue) { >+ // do nothing >+} >+public void exitType(int declarationEnd) { >+ // do nothing >+} >+} >#P org.eclipse.jdt.core.tests.model >Index: src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java,v >retrieving revision 1.227 >diff -u -r1.227 AbstractJavaModelTests.java >--- src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java 23 Oct 2008 13:56:38 -0000 1.227 >+++ src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java 4 Nov 2008 15:31:22 -0000 >@@ -436,8 +436,11 @@ > protected void addLibraryEntry(String path, boolean exported) throws JavaModelException { > addLibraryEntry(this.currentProject, new Path(path), null, null, null, null, exported); > } >+ protected void addLibraryEntry(IJavaProject project, String path) throws JavaModelException { >+ addLibraryEntry(project, new Path(path), null, null, null, null, false); >+ } > protected void addLibraryEntry(IJavaProject project, String path, boolean exported) throws JavaModelException { >- addLibraryEntry(project, new Path(path), exported); >+ addLibraryEntry(project, new Path(path), null, null, null, null, exported); > } > protected void addLibraryEntry(IJavaProject project, IPath path, boolean exported) throws JavaModelException { > addLibraryEntry(project, path, null, null, null, null, exported); >@@ -2872,4 +2875,24 @@ > } catch (CoreException e) { > } > } >+ >+ /** >+ * Following method might be carefully used while debugging tests when it's necessary >+ * to be sure that all indexing jobs are finished (including low priority ones) >+ * @deprecated To get a warning when used... >+ */ >+ public static void waitUntilAllIndexesReady() { >+ // dummy query for waiting until the indexes are ready >+ SearchEngine engine = new SearchEngine(); >+ IJavaSearchScope scope = SearchEngine.createWorkspaceScope(); >+ try { >+ SearchPattern pattern = SearchPattern.createPattern("!@$#!@", IJavaSearchConstants.FIELD, IJavaSearchConstants.REFERENCES, SearchPattern.R_EXACT_MATCH); >+ SearchRequestor requestor = new SearchRequestor() { >+ public void acceptSearchMatch(SearchMatch match) throws CoreException { >+ } >+ }; >+ engine.search(pattern, new SearchParticipant[] { SearchEngine.getDefaultSearchParticipant() }, scope, requestor, null); >+ } catch (CoreException e) { >+ } >+ } > } >Index: src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java,v >retrieving revision 1.162 >diff -u -r1.162 JavaSearchBugsTests.java >--- src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java 23 Oct 2008 17:39:32 -0000 1.162 >+++ src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java 4 Nov 2008 15:31:23 -0000 >@@ -130,6 +130,191 @@ > } > > /** >+ * @bug 12044: [search] Reference to package is not found in qualified annotation >+ * @test Ensure that references to package are also found in qualified annotation >+ * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=12044" >+ */ >+private String[] sourcesBug12044() throws CoreException { >+ return new String[] { >+ "Def.java", >+ "public class Def {\n" + >+ " public static final int ONE = 1;\n" + >+ " public static final int TWO = 2;\n" + >+ " public static final int THREE = 3;\n" + >+ "}\n", >+ "Ref.java", >+ "public class Ref {\n" + >+ " class Sub {\n" + >+ " int x = Def.ONE;\n" + >+ " int getX() {\n" + >+ " return x;\n" + >+ " }\n" + >+ " }\n" + >+ " void foo(Sub sub) {\n" + >+ " switch (sub.getX()) {\n" + >+ " case Def.ONE:\n" + >+ " break;\n" + >+ " case Def.TWO:\n" + >+ " break;\n" + >+ " case Def.THREE:\n" + >+ " break;\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }; >+} >+//static { TESTS_PREFIX = "testBug12044"; } >+public void testBug12044_no_src() throws CoreException, IOException { >+ IJavaProject javaProject = null; >+ try { >+ javaProject = createJavaProject("b012044", new String[] { "src" }, new String[] {"JCL15_LIB" }, "bin", "1.5"); >+ String jarPath = getWorkspacePath()+"b012044"+File.separator+"b012044.jar"; >+ createJar(sourcesBug12044(), jarPath); >+ refresh(javaProject); >+ String resourcePath = "/b012044/b012044.jar"; >+ addLibraryEntry(javaProject, resourcePath); >+ IClassFile classFile = getClassFile("b012044", resourcePath, "", "Def.class"); >+ IField field = classFile.getType().getField("ONE"); >+ IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaElement[] { javaProject } ); >+ this.resultCollector.showJarFile(); >+ search(field, ALL_OCCURRENCES, scope); >+ assertSearchResults( >+ "b012044.jar|Def.class Def.ONE [No source] EXACT_MATCH" >+ ); >+ } >+ finally { >+ if (javaProject != null) { >+ deleteProject(javaProject); >+ } >+ } >+} >+// jar with sources inside >+public void testBug12044_src_in_jar() throws CoreException, IOException { >+ IJavaProject javaProject = null; >+ try { >+ javaProject = createJavaProject("b012044", new String[] { "src" }, new String[] {"JCL15_LIB" }, "bin", "1.5"); >+ String path = getWorkspacePath()+"b012044"+File.separator+"b012044"; >+ String jarPath = path+".jar"; >+ Util.createJar(sourcesBug12044(), null, jarPath, null/*no classpath*/, "1.4", true/*include sources*/); >+ refresh(javaProject); >+ String resourcePath = "/b012044/b012044.jar"; >+ addLibraryEntry(javaProject, resourcePath); >+ IClassFile classFile = getClassFile("b012044", resourcePath, "", "Def.class"); >+ IField field = classFile.getType().getField("ONE"); >+ IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaElement[] { javaProject } ); >+ this.resultCollector.showJarFile(); >+ search(field, ALL_OCCURRENCES, scope); >+ assertSearchResults( >+ "b012044.jar|Def.class Def.ONE EXACT_MATCH\n" + >+ "b012044.jar|Ref.class void Ref.foo(Ref.Sub) EXACT_MATCH\n" + >+ "b012044.jar|Ref$Sub.class Ref$Sub.x EXACT_MATCH" >+ ); >+ } >+ finally { >+ if (javaProject != null) { >+ deleteProject(javaProject); >+ } >+ } >+} >+// jar with sources in another zip file >+public void testBug12044_src_in_zip() throws CoreException, IOException { >+ IJavaProject javaProject = null; >+ try { >+ javaProject = createJavaProject("b012044", new String[] { "src" }, new String[] {"JCL15_LIB" }, "bin", "1.5"); >+ String path = getWorkspacePath()+"b012044"+File.separator+"b012044"; >+ String jarPath = path+".jar"; >+ createJar(sourcesBug12044(), jarPath); >+ String zipPath = path+".zip"; >+ Util.createSourceZip(sourcesBug12044(), zipPath); >+ refresh(javaProject); >+ String resourcePath = "/b012044/b012044.jar"; >+ String resourceZipPath = "/b012044/b012044.zip"; >+ addLibraryEntry(javaProject, resourcePath, resourceZipPath); >+ IClassFile classFile = getClassFile("b012044", resourcePath, "", "Def.class"); >+ IField field = classFile.getType().getField("ONE"); >+ IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaElement[] { javaProject } ); >+ this.resultCollector.showJarFile(); >+ search(field, ALL_OCCURRENCES, scope); >+ assertSearchResults( >+ "b012044.jar|Def.class Def.ONE EXACT_MATCH\n" + >+ "b012044.jar|Ref.class void Ref.foo(Ref.Sub) EXACT_MATCH\n" + >+ "b012044.jar|Ref$Sub.class Ref$Sub.x EXACT_MATCH" >+ ); >+ } >+ finally { >+ if (javaProject != null) { >+ deleteProject(javaProject); >+ } >+ } >+} >+public void testBug12044_src_in_zip_string_pattern() throws CoreException, IOException { >+ IJavaProject javaProject = null; >+ try { >+ javaProject = createJavaProject("b012044", new String[] { "src" }, new String[] {"JCL15_LIB" }, "bin", "1.5"); >+ String path = getWorkspacePath()+"b012044"+File.separator+"b012044"; >+ String jarPath = path+".jar"; >+ createJar(sourcesBug12044(), jarPath); >+ String zipPath = path+".zip"; >+ Util.createSourceZip(sourcesBug12044(), zipPath); >+ refresh(javaProject); >+ String resourcePath = "/b012044/b012044.jar"; >+ String resourceZipPath = "/b012044/b012044.zip"; >+ addLibraryEntry(javaProject, resourcePath, resourceZipPath); >+ IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaElement[] { javaProject } ); >+ this.resultCollector.showJarFile(); >+ search("ONE", FIELD, ALL_OCCURRENCES, scope); >+ assertSearchResults( >+ "b012044.jar|Def.class Def.ONE EXACT_MATCH\n" + >+ "b012044.jar|Ref.class void Ref.foo(Ref.Sub) EXACT_MATCH\n" + >+ "b012044.jar|Ref$Sub.class Ref$Sub.x EXACT_MATCH" >+ ); >+ } >+ finally { >+ if (javaProject != null) { >+ deleteProject(javaProject); >+ } >+ } >+} >+// jar with sources in a folder >+public void testBug12044_src_in_folder() throws CoreException, IOException { >+ IJavaProject javaProject = null, javaProjectBis = null; >+ try { >+ javaProject = createJavaProject("b012044", new String[] { "src" }, new String[] {"JCL15_LIB" }, "bin", "1.5"); >+ String[] sources = sourcesBug12044(); >+ for (int i=0; i<sources.length;) { >+ createFile("/b012044/src/"+sources[i++], sources[i++]); >+ } >+ refresh(javaProject); >+ javaProject.getProject().build(IncrementalProjectBuilder.FULL_BUILD , null); >+ waitForAutoBuild(); >+ javaProjectBis = createJavaProject("b012044_bis", new String[] { "src" }, new String[] {"JCL15_LIB" }, "bin", "1.5"); >+ String jarPath = getWorkspacePath()+"b012044_bis"+File.separator+"b012044.jar"; >+ createJar(sourcesBug12044(), jarPath); >+ refresh(javaProjectBis); >+ String resourcePath = "/b012044_bis/b012044.jar"; >+ addLibraryEntry(javaProjectBis, resourcePath, "/b012044/src"); >+ IClassFile classFile = getClassFile("b012044_bis", resourcePath, "", "Def.class"); >+ IField field = classFile.getType().getField("ONE"); >+ IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaElement[] { javaProjectBis } ); >+ this.resultCollector.showJarFile(); >+ search(field, ALL_OCCURRENCES, scope); >+ assertSearchResults( >+ "b012044.jar|Def.class Def.ONE EXACT_MATCH\n" + >+ "b012044.jar|Ref.class void Ref.foo(Ref.Sub) EXACT_MATCH\n" + >+ "b012044.jar|Ref$Sub.class Ref$Sub.x EXACT_MATCH" >+ ); >+ } >+ finally { >+ if (javaProject != null) { >+ deleteProject(javaProject); >+ } >+ if (javaProjectBis != null) { >+ deleteProject(javaProjectBis); >+ } >+ } >+} >+ >+/** > * @bug 41018: Method reference not found > * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=41018" > */ >@@ -6329,7 +6514,31 @@ > "lib/b124469.jar void test.M.foo() EXACT_MATCH\n" + > "lib/b124469.jar void test.M.foo() EXACT_MATCH\n" + > "lib/b124469.jar void test.M.foo() EXACT_MATCH\n" + >- "lib/b124469.jar void test.M.foo() EXACT_MATCH" >+ "lib/b124469.jar void test.M.foo() EXACT_MATCH\n" + >+ "lib/b124469.jar void test.P.foo(int) EXACT_MATCH\n" + >+ "lib/b124469.jar void test.P.foo(int) EXACT_MATCH\n" + >+ "lib/b124469.jar void test.P.foo(int) EXACT_MATCH\n" + >+ "lib/b124469.jar void test.P.foo(int) EXACT_MATCH\n" + >+ "lib/b124469.jar void test.P.foo(int) EXACT_MATCH\n" + >+ "lib/b124469.jar void test.P.foo(int) EXACT_MATCH\n" + >+ "lib/b124469.jar void test.P.foo(int) EXACT_MATCH\n" + >+ "lib/b124469.jar void test.P.foo(int) EXACT_MATCH\n" + >+ "lib/b124469.jar void test.P.foo(int) EXACT_MATCH\n" + >+ "lib/b124469.jar void test.P.foo(int) EXACT_MATCH\n" + >+ "lib/b124469.jar void test.P.foo(int) EXACT_MATCH\n" + >+ "lib/b124469.jar void test.P.foo(int) EXACT_MATCH\n" + >+ "lib/b124469.jar void test.V.foo() EXACT_MATCH\n" + >+ "lib/b124469.jar void test.V.foo() EXACT_MATCH\n" + >+ "lib/b124469.jar void test.V.foo() EXACT_MATCH\n" + >+ "lib/b124469.jar void test.V.foo() EXACT_MATCH\n" + >+ "lib/b124469.jar void test.V.foo() EXACT_MATCH\n" + >+ "lib/b124469.jar void test.V.foo() EXACT_MATCH\n" + >+ "lib/b124469.jar void test.V.foo() EXACT_MATCH\n" + >+ "lib/b124469.jar void test.V.foo() EXACT_MATCH\n" + >+ "lib/b124469.jar void test.V.foo() EXACT_MATCH\n" + >+ "lib/b124469.jar void test.V.foo() EXACT_MATCH\n" + >+ "lib/b124469.jar void test.V.foo() EXACT_MATCH\n" + >+ "lib/b124469.jar void test.V.foo() EXACT_MATCH" > ); > } > public void testBug124469b() throws CoreException { >@@ -6399,7 +6608,9 @@ > IField field = type.getField("CP"); > search(field, REFERENCES); > assertSearchResults( >- "" // expected no result as parameters annotations are not stored in class file >+ "lib/b124469.jar void test.P.foo(int) EXACT_MATCH\n" + >+ "lib/b124469.jar void test.P.foo(int) EXACT_MATCH\n" + >+ "lib/b124469.jar void test.P.foo(int) EXACT_MATCH" > ); > } > public void testBug124469i() throws CoreException { >@@ -6407,7 +6618,9 @@ > IField field = type.getField("CV"); > search(field, REFERENCES); > assertSearchResults( >- "" // expected no result as parameters annotations are not stored in class file >+ "lib/b124469.jar void test.V.foo() EXACT_MATCH\n" + >+ "lib/b124469.jar void test.V.foo() EXACT_MATCH\n" + >+ "lib/b124469.jar void test.V.foo() EXACT_MATCH" > ); > } > public void testBug124469j() throws CoreException { >@@ -6454,7 +6667,12 @@ > IField field = type.getField("CAP"); > search(field, REFERENCES); > assertSearchResults( >- "" // expected no result as parameters annotations are not stored in class file >+ "lib/b124469.jar void test.P.foo(int) EXACT_MATCH\n" + >+ "lib/b124469.jar void test.P.foo(int) EXACT_MATCH\n" + >+ "lib/b124469.jar void test.P.foo(int) EXACT_MATCH\n" + >+ "lib/b124469.jar void test.P.foo(int) EXACT_MATCH\n" + >+ "lib/b124469.jar void test.P.foo(int) EXACT_MATCH\n" + >+ "lib/b124469.jar void test.P.foo(int) EXACT_MATCH" > ); > } > public void testBug124469n() throws CoreException { >@@ -6462,7 +6680,12 @@ > IField field = type.getField("CAV"); > search(field, REFERENCES); > assertSearchResults( >- "" // expected no result as parameters annotations are not stored in class file >+ "lib/b124469.jar void test.V.foo() EXACT_MATCH\n" + >+ "lib/b124469.jar void test.V.foo() EXACT_MATCH\n" + >+ "lib/b124469.jar void test.V.foo() EXACT_MATCH\n" + >+ "lib/b124469.jar void test.V.foo() EXACT_MATCH\n" + >+ "lib/b124469.jar void test.V.foo() EXACT_MATCH\n" + >+ "lib/b124469.jar void test.V.foo() EXACT_MATCH" > ); > } > >Index: src/org/eclipse/jdt/core/tests/model/JavaSearchScopeTests.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchScopeTests.java,v >retrieving revision 1.21 >diff -u -r1.21 JavaSearchScopeTests.java >--- src/org/eclipse/jdt/core/tests/model/JavaSearchScopeTests.java 31 Oct 2008 16:53:34 -0000 1.21 >+++ src/org/eclipse/jdt/core/tests/model/JavaSearchScopeTests.java 4 Nov 2008 15:31:24 -0000 >@@ -1025,7 +1025,8 @@ > > // Index the output location as it is a library for the project > IndexManager indexManager = JavaModelManager.getIndexManager(); >- indexManager.indexLibrary(new Path("/P1/bin"), project.getProject()); >+ IPackageFragmentRoot root = project.getPackageFragmentRoot(getWorkspaceRoot().findMember("/P1/bin")); >+ indexManager.indexPackageFragmentRoot(root); > waitUntilIndexesReady(); > > // Search for all types >#P org.eclipse.jdt.core.tests.compiler >Index: src/org/eclipse/jdt/core/tests/junit/extension/TestCase.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/junit/extension/TestCase.java,v >retrieving revision 1.39 >diff -u -r1.39 TestCase.java >--- src/org/eclipse/jdt/core/tests/junit/extension/TestCase.java 27 Jun 2008 16:04:47 -0000 1.39 >+++ src/org/eclipse/jdt/core/tests/junit/extension/TestCase.java 4 Nov 2008 15:31:25 -0000 >@@ -239,6 +239,28 @@ > throw new ComparisonFailure(formatted.toString(), expected, actual); > } > } >+ >+// Set components traces >+public static final int SEARCH_TRACE = 0x0001; >+public static final int INDEX_TRACE = 0x0002; >+public static final int INDEX_DEBUG = 0x0004; >+public static final int SELECT_TRACE = 0x0010; >+public static void setTrace(int flag, boolean on) { >+ if ((flag & SEARCH_TRACE) == SEARCH_TRACE) { >+ org.eclipse.jdt.internal.core.search.BasicSearchEngine.VERBOSE = on; >+ } >+ if ((flag & INDEX_TRACE) == INDEX_TRACE) { >+ org.eclipse.jdt.internal.core.search.processing.JobManager.VERBOSE = on; >+ } >+ if ((flag & INDEX_DEBUG) == INDEX_DEBUG) { >+ org.eclipse.jdt.internal.core.index.DiskIndex.DEBUG = on; >+ } >+ if ((flag & SELECT_TRACE) == SELECT_TRACE) { >+ org.eclipse.jdt.internal.codeassist.SelectionEngine.DEBUG = on; >+ } >+ >+} >+ > /** > * Same method as {@link #assertEquals(Object, Object)} if the flag > * {@link #abortOnFailure} has been set to <code>true</code>. >Index: src/org/eclipse/jdt/core/tests/compiler/regression/Requestor.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/Requestor.java,v >retrieving revision 1.21 >diff -u -r1.21 Requestor.java >--- src/org/eclipse/jdt/core/tests/compiler/regression/Requestor.java 27 Jun 2008 16:04:44 -0000 1.21 >+++ src/org/eclipse/jdt/core/tests/compiler/regression/Requestor.java 4 Nov 2008 15:31:25 -0000 >@@ -20,6 +20,7 @@ > import org.eclipse.jdt.internal.compiler.ClassFile; > import org.eclipse.jdt.internal.compiler.CompilationResult; > import org.eclipse.jdt.internal.compiler.ICompilerRequestor; >+import org.eclipse.jdt.internal.compiler.util.SuffixConstants; > > public class Requestor extends Assert implements ICompilerRequestor { > public boolean hasErrors = false; >@@ -30,6 +31,7 @@ > public ICompilerRequestor clientRequestor; > public boolean showCategory = false; > public boolean showWarningToken = false; >+ public boolean writeSource = false; > > public Requestor(boolean forceOutputGeneration, ICompilerRequestor clientRequestor, boolean showCategory, boolean showWarningToken) { > this.forceOutputGeneration = forceOutputGeneration; >@@ -52,10 +54,12 @@ > for (int i = 0, fileCount = classFiles.length; i < fileCount; i++) { > // retrieve the key and the corresponding classfile > ClassFile classFile = classFiles[i]; >- String relativeName = >- new String(classFile.fileName()).replace('/', File.separatorChar) + ".class"; >+ String relativeName = new String(classFile.fileName()).replace('/', File.separatorChar); > try { >- org.eclipse.jdt.internal.compiler.util.Util.writeToDisk(true, this.outputPath, relativeName, classFile); >+ org.eclipse.jdt.internal.compiler.util.Util.writeToDisk(true, this.outputPath, relativeName+SuffixConstants.SUFFIX_STRING_class, classFile); >+ if (this.writeSource && !classFile.isNestedType) { >+ Util.writeToFile(unitResult.compilationUnit.getContents(), this.outputPath+File.separator+relativeName+SuffixConstants.SUFFIX_STRING_java); >+ } > } catch(IOException e) { > e.printStackTrace(); > } >Index: src/org/eclipse/jdt/core/tests/util/Util.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/Util.java,v >retrieving revision 1.74 >diff -u -r1.74 Util.java >--- src/org/eclipse/jdt/core/tests/util/Util.java 23 Oct 2008 13:56:34 -0000 1.74 >+++ src/org/eclipse/jdt/core/tests/util/Util.java 4 Nov 2008 15:31:25 -0000 >@@ -155,6 +155,9 @@ > compile(pathsAndContents, options, null, outputPath); > } > public static void compile(String[] pathsAndContents, Map options, String[] classpath, String outputPath) { >+ compile(pathsAndContents, options, classpath, outputPath, false/*do not write sources*/); >+} >+public static void compile(String[] pathsAndContents, Map options, String[] classpath, String outputPath, boolean writeSource) { > IProblemFactory problemFactory = new DefaultProblemFactory(Locale.getDefault()); > Requestor requestor = > new Requestor( >@@ -163,6 +166,7 @@ > false, /* show category */ > false /* show warning token*/); > requestor.outputPath = outputPath.endsWith(File.separator) ? outputPath : outputPath + File.separator; >+ requestor.writeSource = writeSource; > > String[] classLibs = getJavaClassLibs(); > if (classpath != null) { >@@ -336,11 +340,14 @@ > createJar(pathsAndContents, null, options, null, jarPath); > } > public static void createJar(String[] pathsAndContents, String[] extraPathsAndContents, Map options, String[] classpath, String jarPath) throws IOException { >+ createJar(pathsAndContents, extraPathsAndContents, options, classpath, jarPath, false/*do not write source*/); >+} >+public static void createJar(String[] pathsAndContents, String[] extraPathsAndContents, Map options, String[] classpath, String jarPath, boolean writeSource) throws IOException { > String classesPath = getOutputDirectory() + File.separator + "classes"; > File classesDir = new File(classesPath); > flushDirectoryContent(classesDir); > if (pathsAndContents != null) { >- compile(pathsAndContents, options, classpath, classesPath); >+ compile(pathsAndContents, options, classpath, classesPath, writeSource); > } > if (extraPathsAndContents != null) { > for (int i = 0, l = extraPathsAndContents == null ? 0 : extraPathsAndContents.length; i < l; /* inc in loop */) { >@@ -358,7 +365,10 @@ > createJar(javaPathsAndContents, extraPathsAndContents, jarPath, null/*no classpath*/, compliance); > } > public static void createJar(String[] javaPathsAndContents, String[] extraPathsAndContents, String jarPath, String[] classpath, String compliance) throws IOException { >- createJar(javaPathsAndContents, extraPathsAndContents, getCompileOptions(compliance), classpath, jarPath); >+ createJar(javaPathsAndContents, extraPathsAndContents, getCompileOptions(compliance), classpath, jarPath, false/*do not write source*/); >+} >+public static void createJar(String[] javaPathsAndContents, String[] extraPathsAndContents, String jarPath, String[] classpath, String compliance, boolean writeSource) throws IOException { >+ createJar(javaPathsAndContents, extraPathsAndContents, getCompileOptions(compliance), classpath, jarPath, writeSource); > } > public static void createSourceZip(String[] pathsAndContents, String zipPath) throws IOException { > String sourcesPath = getOutputDirectory() + File.separator + "sources"; >@@ -1255,6 +1265,26 @@ > System.out.println(); > return false; > } >+public static void writeToFile(char[] contents, String destinationFilePath) { >+ File destFile = new File(destinationFilePath); >+ FileOutputStream output = null; >+ try { >+ output = new FileOutputStream(destFile); >+ PrintWriter writer = new PrintWriter(output); >+ writer.print(contents); >+ writer.flush(); >+ } catch (IOException e) { >+ e.printStackTrace(); >+ return; >+ } finally { >+ if (output != null) { >+ try { >+ output.close(); >+ } catch (IOException e2) { >+ } >+ } >+ } >+} > public static void writeToFile(String contents, String destinationFilePath) { > File destFile = new File(destinationFilePath); > FileOutputStream output = null; >#P org.eclipse.jdt.core.tests.performance >Index: src/org/eclipse/jdt/core/tests/performance/FullSourceWorkspaceTests.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.performance/src/org/eclipse/jdt/core/tests/performance/FullSourceWorkspaceTests.java,v >retrieving revision 1.51 >diff -u -r1.51 FullSourceWorkspaceTests.java >--- src/org/eclipse/jdt/core/tests/performance/FullSourceWorkspaceTests.java 3 Oct 2008 12:36:18 -0000 1.51 >+++ src/org/eclipse/jdt/core/tests/performance/FullSourceWorkspaceTests.java 4 Nov 2008 15:31:26 -0000 >@@ -628,6 +628,16 @@ > dirLength = directories.length; > } > >+ // Init JRE_LIB variable >+ System.out.println("Set JRE classpath variables:"); >+ IPath jreLibPath = getJRE(); >+ JavaCore.setClasspathVariable("JRE_LIB", jreLibPath, null); >+ System.out.println(" - JRE_LIB: "+JavaCore.getClasspathVariable("JRE_LIB")); >+ IPath jreSrcPath = jreLibPath.removeLastSegments(3).append("src.zip"); >+ assertTrue("Cannot find sources path "+jreSrcPath+" for lib "+jreLibPath, jreSrcPath.toFile().exists()); >+ JavaCore.setClasspathVariable("JRE_SRC", jreSrcPath, null); >+ System.out.println(" - JRE_SRC: "+JavaCore.getClasspathVariable("JRE_SRC")); >+ > // Init environment with existing porjects > System.out.print("Create and open projects in environment..."); > start = System.currentTimeMillis(); >@@ -642,24 +652,10 @@ > } > System.out.println("("+(System.currentTimeMillis()-start)+"ms)"); > >- // Init JRE_LIB variable >- String[] jdkLibs = Util.getJavaClassLibs(); >- int length = jdkLibs.length; >- String jdkLib = null; >- for (int i=0; i<length; i++) { >- if (jdkLibs[i].endsWith("rt.jar")) { >- jdkLib = jdkLibs[i]; >- break; >- } >- } >- if (jdkLib == null) { >- throw new RuntimeException("Cannot set JRE_LIB classpath variable as the rt.jar lib was not found!!!"); >- } >- > // Set classpaths (workaround bug 73253 Project references not set on project open) > System.out.print("Set projects classpaths..."); > ALL_PROJECTS = JavaCore.create(workspaceRoot).getJavaProjects(); >- length = ALL_PROJECTS.length; >+ int length = ALL_PROJECTS.length; > for (int i = 0; i < length; i++) { > String projectName = ALL_PROJECTS[i].getElementName(); > if (BIG_PROJECT_NAME.equals(projectName)) continue; // will be set later >@@ -683,6 +679,18 @@ > PARSER_WORKING_COPY = (ICompilationUnit) element.getParent(); > } > >+ protected IPath getJRE() throws IOException { >+ String[] jdkLibs = Util.getJavaClassLibs(); >+ int length = jdkLibs.length; >+ for (int i=0; i<length; i++) { >+ if (jdkLibs[i].endsWith("rt.jar")) { >+ String jdkLib = new File(jdkLibs[i]).getCanonicalPath(); >+ return new Path(jdkLib); >+ } >+ } >+ throw new RuntimeException("Cannot find rt.jar file!"); >+ } >+ > /* > * Create JUnit project and add it to the workspace > * >Index: src/org/eclipse/jdt/core/tests/performance/FullSourceWorkspaceCompleteSearchTests.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.performance/src/org/eclipse/jdt/core/tests/performance/FullSourceWorkspaceCompleteSearchTests.java,v >retrieving revision 1.6 >diff -u -r1.6 FullSourceWorkspaceCompleteSearchTests.java >--- src/org/eclipse/jdt/core/tests/performance/FullSourceWorkspaceCompleteSearchTests.java 9 Sep 2008 13:28:49 -0000 1.6 >+++ src/org/eclipse/jdt/core/tests/performance/FullSourceWorkspaceCompleteSearchTests.java 4 Nov 2008 15:31:26 -0000 >@@ -15,16 +15,16 @@ > > import junit.framework.*; > >-import org.eclipse.core.runtime.CoreException; >-import org.eclipse.core.runtime.IProgressMonitor; >-import org.eclipse.jdt.core.IClassFile; >-import org.eclipse.jdt.core.IField; >-import org.eclipse.jdt.core.IJavaElement; >-import org.eclipse.jdt.core.IMethod; >-import org.eclipse.jdt.core.IType; >+import org.eclipse.core.resources.IProject; >+import org.eclipse.core.resources.IResource; >+import org.eclipse.core.resources.IWorkspaceRoot; >+import org.eclipse.core.resources.ResourcesPlugin; >+import org.eclipse.core.runtime.*; >+import org.eclipse.jdt.core.*; > import org.eclipse.jdt.core.search.*; > import org.eclipse.jdt.core.tests.model.AbstractJavaModelTests; > import org.eclipse.jdt.internal.core.search.processing.IJob; >+import org.eclipse.jdt.internal.core.search.processing.JobManager; > > /** > * Performance test suite which covers all main search requests: >@@ -39,6 +39,7 @@ > // Tests counters > private static int TESTS_COUNT = 0; > private final static int ITERATIONS_COUNT = 0; >+ private final static int WARMUP_COUNT = 2; > > // Log file streams > private static PrintStream[] LOG_STREAMS = new PrintStream[DIM_NAMES.length]; >@@ -143,7 +144,7 @@ > // nothing to cancel > } > public void ensureReadyToRun() { >- // always ready to do nothing >+// INDEX_MANAGER.getIndexes(locations, progressMonitor) > } > /** > * Execute the current job, answer whether it was successful. >@@ -209,6 +210,95 @@ > } > > /** >+ * Performance tests for search: Indexing one project (JDT/Core). >+ */ >+public void testONLY_IndexingJdkSources() throws Exception { >+ tagAsSummary("Indexing JDT/Core project", true); // put in fingerprint >+ >+ // Wait for indexes >+ waitUntilAllIndexesReady(); >+ >+ // Find JRE_LIB entry >+ IClasspathEntry[] entries = JDT_CORE_PROJECT.getRawClasspath(); >+ int index = -1; >+ for (int i=0; i<entries.length; i++) { >+ IClasspathEntry entry = entries[i]; >+ if (entry.getPath().toString().equals("JRE_LIB")) { >+ index = i; >+ break; >+ } >+ } >+ IPath jreLibPath = entries[index].getPath(); >+ >+ // Warm-up >+ System.out.println("\n==================== WARMUP ====================\n"); >+ IWorkspaceRoot wkspRoot = ResourcesPlugin.getWorkspace().getRoot(); >+// setTrace(INDEX_TRACE, true); >+ for (int i=0 ; i<WARMUP_COUNT; i++) { >+ System.out.println(" - loop "+(i+1)); >+ // Reset entry source attachment path >+ entries[index] = JavaCore.newVariableEntry(jreLibPath, null, null); >+ JDT_CORE_PROJECT.setRawClasspath(entries, null); >+ wkspRoot.refreshLocal(IResource.DEPTH_INFINITE, null); >+ AbstractJavaModelTests.waitForManualRefresh(); >+// Thread.sleep(1000); >+ waitUntilAllIndexesReady(); >+ // Set entry source attachment path >+ entries[index] = JavaCore.newVariableEntry(jreLibPath, new Path("JRE_SRC"), null); >+ JDT_CORE_PROJECT.setRawClasspath(entries, null); >+ wkspRoot.refreshLocal(IResource.DEPTH_INFINITE, null); >+// Thread.sleep(1000); >+ AbstractJavaModelTests.waitForManualRefresh(); >+ waitUntilAllIndexesReady(); >+ } >+// setTrace(INDEX_TRACE, false); >+ >+ // Measures >+ System.out.println("\n==================== MEASURES ====================\n"); >+ for (int i=0; i<MEASURES_COUNT; i++) { >+ runGc(); >+ // Reset entry source attachment path >+ entries[index] = JavaCore.newVariableEntry(jreLibPath, null, null); >+ JDT_CORE_PROJECT.setRawClasspath(entries, null); >+ wkspRoot.refreshLocal(IResource.DEPTH_INFINITE, null); >+ AbstractJavaModelTests.waitForManualRefresh(); >+ waitUntilAllIndexesReady(); >+ INDEX_MANAGER.request(new Measuring(true/*start measuring*/)); //, JobManager.LOW_PRIORITY); >+ // Set entry source attachment path >+ entries[index] = JavaCore.newVariableEntry(jreLibPath, new Path("JRE_SRC"), null); >+ JDT_CORE_PROJECT.setRawClasspath(entries, null); >+ wkspRoot.refreshLocal(IResource.DEPTH_INFINITE, null); >+ AbstractJavaModelTests.waitForManualRefresh(); >+ waitUntilAllIndexesReady(); >+ INDEX_MANAGER.request(new Measuring(false /*end measuring*/)); //, JobManager.LOW_PRIORITY); >+ waitUntilAllIndexesReady(); >+ } >+ >+ // Commit >+ commitMeasurements(); >+ assertPerformance(); >+} >+ >+/** >+ * Following method might be carefully used while debugging tests when it's necessary >+ * to be sure that all indexing jobs are finished (including low priority ones) >+ */ >+private void waitUntilAllIndexesReady() { >+ // dummy query for waiting until the indexes are ready >+ SearchEngine engine = new SearchEngine(); >+ IJavaSearchScope scope = SearchEngine.createWorkspaceScope(); >+ try { >+ SearchPattern pattern = SearchPattern.createPattern("!@$#!@", IJavaSearchConstants.FIELD, IJavaSearchConstants.REFERENCES, SearchPattern.R_EXACT_MATCH); >+ SearchRequestor requestor = new SearchRequestor() { >+ public void acceptSearchMatch(SearchMatch match) throws CoreException { >+ } >+ }; >+ engine.search(pattern, new SearchParticipant[] { SearchEngine.getDefaultSearchParticipant() }, scope, requestor, null); >+ } catch (CoreException e) { >+ } >+} >+ >+/** > * Performance tests for search types in workspace: > * <ul> > * <li>declarations using string pattern</i>
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 12044
:
115133
|
115139
|
115140
|
115157
|
115271
|
115273
|
116951
|
118501