View | Details | Raw Unified | Return to bug 182930 | Differences between
and this patch

Collapse All | Expand All

(-)model/org/eclipse/jdt/internal/core/JavaProject.java (+5 lines)
Lines 66-71 Link Here
66
import org.eclipse.jdt.internal.compiler.util.ObjectVector;
66
import org.eclipse.jdt.internal.compiler.util.ObjectVector;
67
import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
67
import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
68
import org.eclipse.jdt.internal.core.JavaModelManager.PerProjectInfo;
68
import org.eclipse.jdt.internal.core.JavaModelManager.PerProjectInfo;
69
import org.eclipse.jdt.internal.core.JavaProjectElementInfo.ProjectCache;
69
import org.eclipse.jdt.internal.core.builder.JavaBuilder;
70
import org.eclipse.jdt.internal.core.builder.JavaBuilder;
70
import org.eclipse.jdt.internal.core.eval.EvaluationContextWrapper;
71
import org.eclipse.jdt.internal.core.eval.EvaluationContextWrapper;
71
import org.eclipse.jdt.internal.core.util.MementoTokenizer;
72
import org.eclipse.jdt.internal.core.util.MementoTokenizer;
Lines 1809-1814 Link Here
1809
	public IProject getProject() {
1810
	public IProject getProject() {
1810
		return this.project;
1811
		return this.project;
1811
	}
1812
	}
1813
	
1814
	public ProjectCache getProjectCache() throws JavaModelException {
1815
		return ((JavaProjectElementInfo) getElementInfo()).getProjectCache(this);
1816
	}
1812
1817
1813
	/**
1818
	/**
1814
	 * @see IJavaProject
1819
	 * @see IJavaProject
(-)model/org/eclipse/jdt/internal/core/JavaProjectElementInfo.java (-43 / +88 lines)
Lines 37-46 Link Here
37
	static final IPackageFragmentRoot[] NO_ROOTS = new IPackageFragmentRoot[0];
37
	static final IPackageFragmentRoot[] NO_ROOTS = new IPackageFragmentRoot[0];
38
38
39
	static class ProjectCache {
39
	static class ProjectCache {
40
		ProjectCache(IPackageFragmentRoot[] allPkgFragmentRootsCache, HashtableOfArrayToObject allPkgFragmentsCache, Map rootToResolvedEntries) {
40
		ProjectCache(IPackageFragmentRoot[] allPkgFragmentRootsCache, Map rootToResolvedEntries, Map pkgFragmentsCaches) {
41
			this.allPkgFragmentRootsCache = allPkgFragmentRootsCache;
41
			this.allPkgFragmentRootsCache = allPkgFragmentRootsCache;
42
			this.allPkgFragmentsCache = allPkgFragmentsCache;
43
			this.rootToResolvedEntries = rootToResolvedEntries;
42
			this.rootToResolvedEntries = rootToResolvedEntries;
43
			this.pkgFragmentsCaches = pkgFragmentsCaches;
44
		}
44
		}
45
		
45
		
46
		/*
46
		/*
Lines 50-58 Link Here
50
		
50
		
51
		/*
51
		/*
52
		 * A cache of all package fragments in this project.
52
		 * A cache of all package fragments in this project.
53
		 * (a map from String[] (the package name) to IPackageFragmentRoot[] (the package fragment roots that contain a package fragment with this name)
53
		 * (an array of a map from String[] (the package name) to IPackageFragmentRoot[] (the package fragment roots that contain a package fragment with this name))
54
		 */
54
		 */
55
		public HashtableOfArrayToObject allPkgFragmentsCache;
55
		public HashtableOfArrayToObject[] allPkgFragmentsCaches;
56
		
57
		/*
58
		 * A cache of package fragments for each package fragment root of this project
59
		 * (a map from IPackageFragmentRoot to
60
		 *  a map from String[] (the package name) to IPackageFragmentRoot[] (the package fragment roots that contain a package fragment with this name))
61
		 */
62
		public Map pkgFragmentsCaches;
56
		
63
		
57
		public Map rootToResolvedEntries;		
64
		public Map rootToResolvedEntries;		
58
	}
65
	}
Lines 202-248 Link Here
202
				reverseMap.clear();
209
				reverseMap.clear();
203
			}
210
			}
204
			
211
			
205
			HashMap otherRoots = JavaModelManager.getJavaModelManager().deltaState.otherRoots;
212
			HashMap rootInfos = JavaModelManager.getJavaModelManager().deltaState.roots;
206
			HashtableOfArrayToObject fragmentsCache = new HashtableOfArrayToObject();
213
			HashMap pkgFragmentsCaches = new HashMap();
207
			for (int i = 0, length = roots.length; i < length; i++) {
214
			int length = roots.length;
215
			for (int i = 0; i < length; i++) {
208
				IPackageFragmentRoot root = roots[i];
216
				IPackageFragmentRoot root = roots[i];
209
				IJavaElement[] frags = null;
217
				DeltaProcessor.RootInfo rootInfo = (DeltaProcessor.RootInfo) rootInfos.get(root.getPath());
210
				try {
218
				if (rootInfo == null || rootInfo.project.equals(project)) {
211
					if (root.isArchive() 
219
					// compute fragment cache
212
							&& !root.isOpen() 
220
					HashtableOfArrayToObject fragmentsCache = new HashtableOfArrayToObject();
213
							&& otherRoots.get(((JarPackageFragmentRoot) root).jarPath) == null/*only if jar belongs to 1 project (https://bugs.eclipse.org/bugs/show_bug.cgi?id=161175)*/) {
221
					initializePackageNames(root, fragmentsCache);
214
						JarPackageFragmentRootInfo info = new JarPackageFragmentRootInfo();
222
					pkgFragmentsCaches.put(root, fragmentsCache);
215
						((JarPackageFragmentRoot) root).computeChildren(info, new HashMap());
216
						frags = info.children;
217
					} else 
218
						frags = root.getChildren();
219
				} catch (JavaModelException e) {
220
					// root doesn't exist: ignore
221
					continue;
222
				}
223
				for (int j = 0, length2 = frags.length; j < length2; j++) {
224
					PackageFragment fragment= (PackageFragment) frags[j];
225
					String[] pkgName = fragment.names;
226
					Object existing = fragmentsCache.get(pkgName);
227
					if (existing == null || existing == NO_ROOTS) {
228
						fragmentsCache.put(pkgName, root);
229
						// ensure super packages (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=119161)
230
						// are also in the map
231
						addSuperPackageNames(pkgName, fragmentsCache);
232
					} else {
233
						if (existing instanceof PackageFragmentRoot) {
234
							fragmentsCache.put(pkgName, new IPackageFragmentRoot[] {(PackageFragmentRoot) existing, root});
235
						} else {
236
							IPackageFragmentRoot[] entry= (IPackageFragmentRoot[]) existing;
237
							IPackageFragmentRoot[] copy= new IPackageFragmentRoot[entry.length + 1];
238
							System.arraycopy(entry, 0, copy, 0, entry.length);
239
							copy[entry.length]= root;
240
							fragmentsCache.put(pkgName, copy);
241
						}
242
					}
243
				}
223
				}
244
			}
224
			}
245
			cache = new ProjectCache(roots, fragmentsCache, reverseMap);
225
			
226
			cache = new ProjectCache(roots, reverseMap, pkgFragmentsCaches);
246
			this.projectCache = cache;
227
			this.projectCache = cache;
247
		}
228
		}
248
		return cache;
229
		return cache;
Lines 258-263 Link Here
258
		}
239
		}
259
		return this.nonJavaResources;
240
		return this.nonJavaResources;
260
	}
241
	}
242
	
243
	private void initializePackageNames(IPackageFragmentRoot root, HashtableOfArrayToObject fragmentsCache) {
244
		IJavaElement[] frags = null;
245
		try {
246
			if (!root.isOpen()) {
247
				PackageFragmentRootInfo info = root.isArchive() ? new JarPackageFragmentRootInfo() : new PackageFragmentRootInfo();
248
				((PackageFragmentRoot) root).computeChildren(info, new HashMap());
249
				frags = info.children;
250
			} else 
251
				frags = root.getChildren();
252
		} catch (JavaModelException e) {
253
			// root doesn't exist: ignore
254
			return;
255
		}
256
		for (int j = 0, length2 = frags.length; j < length2; j++) {
257
			PackageFragment fragment= (PackageFragment) frags[j];
258
			String[] pkgName = fragment.names;
259
			Object existing = fragmentsCache.get(pkgName);
260
			if (existing == null || existing == NO_ROOTS) {
261
				fragmentsCache.put(pkgName, root);
262
				// ensure super packages (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=119161)
263
				// are also in the map
264
				addSuperPackageNames(pkgName, fragmentsCache);
265
			} else {
266
				if (existing instanceof PackageFragmentRoot) {
267
					fragmentsCache.put(pkgName, new IPackageFragmentRoot[] {(PackageFragmentRoot) existing, root});
268
				} else {
269
					IPackageFragmentRoot[] entry= (IPackageFragmentRoot[]) existing;
270
					IPackageFragmentRoot[] copy= new IPackageFragmentRoot[entry.length + 1];
271
					System.arraycopy(entry, 0, copy, 0, entry.length);
272
					copy[entry.length]= root;
273
					fragmentsCache.put(pkgName, copy);
274
				}
275
			}
276
		}
277
	}
261
278
262
	/*
279
	/*
263
	 * Returns whether the given path is a classpath entry or an output location.
280
	 * Returns whether the given path is a classpath entry or an output location.
Lines 284-290 Link Here
284
	 */
301
	 */
285
	NameLookup newNameLookup(JavaProject project, ICompilationUnit[] workingCopies) {
302
	NameLookup newNameLookup(JavaProject project, ICompilationUnit[] workingCopies) {
286
		ProjectCache cache = getProjectCache(project);
303
		ProjectCache cache = getProjectCache(project);
287
		return new NameLookup(cache.allPkgFragmentRootsCache, cache.allPkgFragmentsCache, workingCopies, cache.rootToResolvedEntries);
304
		HashtableOfArrayToObject[] allPkgFragmentsCaches = cache.allPkgFragmentsCaches;
305
		if (allPkgFragmentsCaches == null) {
306
			HashMap rootInfos = JavaModelManager.getJavaModelManager().deltaState.roots;
307
			IPackageFragmentRoot[] roots = cache.allPkgFragmentRootsCache;
308
			int length = roots.length;
309
			allPkgFragmentsCaches = new HashtableOfArrayToObject[length];
310
			for (int i = 0; i < length; i++) {
311
				IPackageFragmentRoot root = roots[i];
312
				DeltaProcessor.RootInfo rootInfo = (DeltaProcessor.RootInfo) rootInfos.get(root.getPath());
313
				JavaProject rootProject = rootInfo == null ? project : rootInfo.project;
314
				HashtableOfArrayToObject fragmentsCache;
315
				if (rootProject.equals(project)) {
316
					fragmentsCache = (HashtableOfArrayToObject) cache.pkgFragmentsCaches.get(root);
317
				} else {
318
					// retrieve fragment cache from root project
319
					ProjectCache rootProjectCache;
320
					try {
321
						rootProjectCache = rootProject.getProjectCache();
322
					} catch (JavaModelException e) {
323
						// project doesn't exit
324
						continue;
325
					}
326
					fragmentsCache = (HashtableOfArrayToObject) rootProjectCache.pkgFragmentsCaches.get(root);
327
				}
328
				allPkgFragmentsCaches[i] = fragmentsCache;
329
			}
330
			cache.allPkgFragmentsCaches = allPkgFragmentsCaches;
331
		}
332
		return new NameLookup(cache.allPkgFragmentRootsCache, cache.allPkgFragmentsCaches, workingCopies, cache.rootToResolvedEntries);
288
	}
333
	}
289
	
334
	
290
	/*
335
	/*
(-)model/org/eclipse/jdt/internal/core/NameLookup.java (-69 / +151 lines)
Lines 123-129 Link Here
123
	 * Note if the list is of size 1, then the IPackageFragmentRoot object
123
	 * Note if the list is of size 1, then the IPackageFragmentRoot object
124
	 * replaces the array.
124
	 * replaces the array.
125
	 */
125
	 */
126
	protected HashtableOfArrayToObject packageFragments;
126
	protected HashtableOfArrayToObject[] packageFragmentsCaches;
127
	
128
	protected HashtableOfArrayToObject workingCopyFragmentsCache;
127
	
129
	
128
	/**
130
	/**
129
	 * Reverse map from root path to corresponding resolved CP entry
131
	 * Reverse map from root path to corresponding resolved CP entry
Lines 142-170 Link Here
142
144
143
	public NameLookup(
145
	public NameLookup(
144
			IPackageFragmentRoot[] packageFragmentRoots, 
146
			IPackageFragmentRoot[] packageFragmentRoots, 
145
			HashtableOfArrayToObject packageFragments, 
147
			HashtableOfArrayToObject[] packageFragmentsCaches, 
146
			ICompilationUnit[] workingCopies, 
148
			ICompilationUnit[] workingCopies, 
147
			Map rootToResolvedEntries) {
149
			Map rootToResolvedEntries) {
148
		long start = -1;
150
		long start = -1;
149
		if (VERBOSE) {
151
		if (VERBOSE) {
150
			Util.verbose(" BUILDING NameLoopkup");  //$NON-NLS-1$
152
			Util.verbose(" BUILDING NameLoopkup");  //$NON-NLS-1$
151
			Util.verbose(" -> pkg roots size: " + (packageFragmentRoots == null ? 0 : packageFragmentRoots.length));  //$NON-NLS-1$
153
			Util.verbose(" -> pkg roots size: " + (packageFragmentRoots == null ? 0 : packageFragmentRoots.length));  //$NON-NLS-1$
152
			Util.verbose(" -> pkgs size: " + (packageFragments == null ? 0 : packageFragments.size()));  //$NON-NLS-1$
154
			//Util.verbose(" -> pkgs size: " + (packageFragments == null ? 0 : packageFragments.size()));  //$NON-NLS-1$
153
			Util.verbose(" -> working copy size: " + (workingCopies == null ? 0 : workingCopies.length));  //$NON-NLS-1$
155
			Util.verbose(" -> working copy size: " + (workingCopies == null ? 0 : workingCopies.length));  //$NON-NLS-1$
154
			start = System.currentTimeMillis();
156
			start = System.currentTimeMillis();
155
		}
157
		}
156
		this.packageFragmentRoots = packageFragmentRoots;
158
		this.packageFragmentRoots = packageFragmentRoots;
157
		if (workingCopies == null) {
159
		this.packageFragmentsCaches = packageFragmentsCaches;
158
			this.packageFragments = packageFragments;
160
		this.workingCopyFragmentsCache = new HashtableOfArrayToObject();
159
		} else {
161
		if (workingCopies != null) {
160
			// clone tables as we're adding packages from working copies
162
			// add packages from working copies first
161
			try {
162
				this.packageFragments = (HashtableOfArrayToObject) packageFragments.clone();
163
			} catch (CloneNotSupportedException e1) {
164
				// ignore (implementation of HashtableOfArrayToObject supports cloning)
165
			}
166
			this.typesInWorkingCopies = new HashMap();
163
			this.typesInWorkingCopies = new HashMap();
167
			for (int i = 0, length = workingCopies.length; i < length; i++) {
164
			for (int i = 0, length2 = workingCopies.length; i < length2; i++) {
168
				ICompilationUnit workingCopy = workingCopies[i];
165
				ICompilationUnit workingCopy = workingCopies[i];
169
				PackageFragment pkg = (PackageFragment) workingCopy.getParent();
166
				PackageFragment pkg = (PackageFragment) workingCopy.getParent();
170
				HashMap typeMap = (HashMap) this.typesInWorkingCopies.get(pkg);
167
				HashMap typeMap = (HashMap) this.typesInWorkingCopies.get(pkg);
Lines 203-218 Link Here
203
				// add root of package fragment to cache
200
				// add root of package fragment to cache
204
				IPackageFragmentRoot root = (IPackageFragmentRoot) pkg.getParent();
201
				IPackageFragmentRoot root = (IPackageFragmentRoot) pkg.getParent();
205
				String[] pkgName = pkg.names;
202
				String[] pkgName = pkg.names;
206
				Object existing = this.packageFragments.get(pkgName);
203
				Object existing = this.workingCopyFragmentsCache.get(pkgName);
207
				if (existing == null || existing == JavaProjectElementInfo.NO_ROOTS) {
204
				if (existing == null || existing == JavaProjectElementInfo.NO_ROOTS) {
208
					this.packageFragments.put(pkgName, root);
205
					workingCopyFragmentsCache.put(pkgName, root);
209
					// ensure super packages (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=119161)
206
					// ensure super packages (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=119161)
210
					// are also in the map
207
					// are also in the map
211
					JavaProjectElementInfo.addSuperPackageNames(pkgName, this.packageFragments);
208
					JavaProjectElementInfo.addSuperPackageNames(pkgName, this.workingCopyFragmentsCache);
212
				} else {
209
				} else {
213
					if (existing instanceof PackageFragmentRoot) {
210
					if (existing instanceof PackageFragmentRoot) {
214
						if (!existing.equals(root))
211
						if (!existing.equals(root))
215
							this.packageFragments.put(pkgName, new IPackageFragmentRoot[] {(PackageFragmentRoot) existing, root});
212
							this.workingCopyFragmentsCache.put(pkgName, new IPackageFragmentRoot[] {(PackageFragmentRoot) existing, root});
216
					} else {
213
					} else {
217
						IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) existing;
214
						IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) existing;
218
						int rootLength = roots.length;
215
						int rootLength = roots.length;
Lines 226-232 Link Here
226
						if (containsRoot) {
223
						if (containsRoot) {
227
							System.arraycopy(roots, 0, roots = new IPackageFragmentRoot[rootLength+1], 0, rootLength);
224
							System.arraycopy(roots, 0, roots = new IPackageFragmentRoot[rootLength+1], 0, rootLength);
228
							roots[rootLength] = root;
225
							roots[rootLength] = root;
229
							this.packageFragments.put(pkgName, roots);
226
							this.workingCopyFragmentsCache.put(pkgName, roots);
230
						}
227
						}
231
					}
228
					}
232
				}
229
				}
Lines 325-342 Link Here
325
		if (index != -1) {
322
		if (index != -1) {
326
			cuName= cuName.substring(0, index);
323
			cuName= cuName.substring(0, index);
327
		}
324
		}
328
		Object value = this.packageFragments.get(pkgName);
325
		// lookup working copies package fragments
329
		if (value != null) {
326
		Object value = this.workingCopyFragmentsCache.get(pkgName);
330
			if (value instanceof PackageFragmentRoot) {
327
		if (value == null)
331
				return findCompilationUnit(pkgName, cuName, (PackageFragmentRoot) value);
328
			return null;
332
			} else {
329
		if (value instanceof PackageFragmentRoot) {
333
				IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) value;
330
			return findCompilationUnit(pkgName, cuName, (PackageFragmentRoot) value);
334
				for (int i= 0; i < roots.length; i++) {
331
		} else {
335
					PackageFragmentRoot root= (PackageFragmentRoot) roots[i];
332
			IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) value;
336
					ICompilationUnit cu = findCompilationUnit(pkgName, cuName, root);
333
			for (int i = 0, length = roots.length; i < length; i++) {
337
					if (cu != null)
334
				ICompilationUnit cu = findCompilationUnit(pkgName, cuName, (PackageFragmentRoot) roots[i]);
338
						return cu;
335
				if (cu != null)
339
				}
336
					return cu;
337
			}
338
		}
339
		// lookup other package fragments
340
		for (int i = 0, length = this.packageFragmentsCaches.length; i < length; i++) {
341
			if (this.packageFragmentsCaches[i].containsKey(pkgName)) {
342
				ICompilationUnit cu = findCompilationUnit(pkgName, cuName, (PackageFragmentRoot) this.packageFragmentRoots[i]);
343
				if (cu != null)
344
					return cu;
340
			}
345
			}
341
		}
346
		}
342
		return null;
347
		return null;
Lines 421-441 Link Here
421
					try {
426
					try {
422
						IClasspathEntry entry = project.getClasspathEntryFor(path);
427
						IClasspathEntry entry = project.getClasspathEntryFor(path);
423
						if (entry != null) {
428
						if (entry != null) {
424
							IPackageFragmentRoot root =
429
							IPackageFragmentRoot root = project.getPackageFragmentRoot(project.getResource());
425
								project.getPackageFragmentRoot(project.getResource());
430
							for (int i = 0, length = this.packageFragmentRoots.length; i < length; i++) {
426
							Object defaultPkgRoot = this.packageFragments.get(CharOperation.NO_STRINGS);
431
								if (root.equals(this.packageFragmentRoots[i]))
427
							if (defaultPkgRoot == null) {
432
									return ((PackageFragmentRoot) root).getPackageFragment(CharOperation.NO_STRINGS);
428
								return null;
429
							}
430
							if (defaultPkgRoot instanceof PackageFragmentRoot && defaultPkgRoot.equals(root))
431
								return  ((PackageFragmentRoot) root).getPackageFragment(CharOperation.NO_STRINGS);
432
							else {
433
								IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) defaultPkgRoot;
434
								for (int i = 0; i < roots.length; i++) {
435
									if (roots[i].equals(root)) {
436
										return  ((PackageFragmentRoot) root).getPackageFragment(CharOperation.NO_STRINGS);
437
									}
438
								}
439
							}
433
							}
440
						}
434
						}
441
					} catch (JavaModelException e) {
435
					} catch (JavaModelException e) {
Lines 460-474 Link Here
460
	 *	only exact name matches qualify when <code>false</code>
454
	 *	only exact name matches qualify when <code>false</code>
461
	 */
455
	 */
462
	public IPackageFragment[] findPackageFragments(String name, boolean partialMatch) {
456
	public IPackageFragment[] findPackageFragments(String name, boolean partialMatch) {
457
		IPackageFragment[] oneFragment = null;
458
		ArrayList pkgs = null;
459
		HashSet knownPkgs = null;
463
		if (partialMatch) {
460
		if (partialMatch) {
464
			String[] splittedName = Util.splitOn('.', name, 0, name.length());
461
			String[] splittedName = Util.splitOn('.', name, 0, name.length());
465
			IPackageFragment[] oneFragment = null;
462
			// lookup working copies package fragments
466
			ArrayList pkgs = null;
463
			Object[][] keys = this.workingCopyFragmentsCache.keyTable;
467
			Object[][] keys = this.packageFragments.keyTable;
468
			for (int i = 0, length = keys.length; i < length; i++) {
464
			for (int i = 0, length = keys.length; i < length; i++) {
469
				String[] pkgName = (String[]) keys[i];
465
				String[] pkgName = (String[]) keys[i];
470
				if (pkgName != null && Util.startsWithIgnoreCase(pkgName, splittedName)) {
466
				if (pkgName != null && Util.startsWithIgnoreCase(pkgName, splittedName)) {
471
					Object value = this.packageFragments.valueTable[i];
467
					Object value = this.workingCopyFragmentsCache.valueTable[i];
472
					if (value instanceof PackageFragmentRoot) {
468
					if (value instanceof PackageFragmentRoot) {
473
						IPackageFragment pkg = ((PackageFragmentRoot) value).getPackageFragment(pkgName);
469
						IPackageFragment pkg = ((PackageFragmentRoot) value).getPackageFragment(pkgName);
474
						if (oneFragment == null) {
470
						if (oneFragment == null) {
Lines 477-484 Link Here
477
							if (pkgs == null) {
473
							if (pkgs == null) {
478
								pkgs = new ArrayList();
474
								pkgs = new ArrayList();
479
								pkgs.add(oneFragment[0]);
475
								pkgs.add(oneFragment[0]);
476
								knownPkgs = new HashSet();
477
								knownPkgs.add(oneFragment[0]);
480
							}
478
							}
481
							pkgs.add(pkg);
479
							if (!knownPkgs.contains(pkg))
480
								pkgs.add(pkg);
482
						}
481
						}
483
					} else {
482
					} else {
484
						IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) value;
483
						IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) value;
Lines 491-503 Link Here
491
								if (pkgs == null) {
490
								if (pkgs == null) {
492
									pkgs = new ArrayList();
491
									pkgs = new ArrayList();
493
									pkgs.add(oneFragment[0]);
492
									pkgs.add(oneFragment[0]);
493
									knownPkgs = new HashSet();
494
									knownPkgs.add(oneFragment[0]);
494
								}
495
								}
495
								pkgs.add(pkg);
496
								if (!knownPkgs.contains(pkg))
497
									pkgs.add(pkg);
496
							}
498
							}
497
						}
499
						}
498
					}
500
					}
499
				}
501
				}
500
			}
502
			}
503
			// lookup other package fragments
504
			for (int i = 0, length = this.packageFragmentsCaches.length; i < length; i++) {
505
				HashtableOfArrayToObject packageFragmentsCache = this.packageFragmentsCaches[i];
506
				PackageFragmentRoot root = (PackageFragmentRoot) this.packageFragmentRoots[i];
507
				keys = packageFragmentsCache.keyTable;
508
				for (int j = 0, length2 = keys.length; j < length2; j++) {
509
					String[] pkgName = (String[]) keys[j];
510
					if (pkgName != null && Util.startsWithIgnoreCase(pkgName, splittedName)) {
511
						IPackageFragment pkg = root.getPackageFragment(pkgName);
512
						if (oneFragment == null) {
513
							oneFragment = new IPackageFragment[] {pkg};
514
						} else {
515
							if (pkgs == null) {
516
								pkgs = new ArrayList();
517
								pkgs.add(oneFragment[0]);
518
								knownPkgs = new HashSet();
519
								knownPkgs.add(oneFragment[0]);
520
							}
521
							if (!knownPkgs.contains(pkg))
522
								pkgs.add(pkg);
523
						}
524
					}
525
				}
526
			}
501
			if (pkgs == null) return oneFragment;
527
			if (pkgs == null) return oneFragment;
502
			int resultLength = pkgs.size();
528
			int resultLength = pkgs.size();
503
			IPackageFragment[] result = new IPackageFragment[resultLength];
529
			IPackageFragment[] result = new IPackageFragment[resultLength];
Lines 505-523 Link Here
505
			return result;
531
			return result;
506
		} else {
532
		} else {
507
			String[] splittedName = Util.splitOn('.', name, 0, name.length());
533
			String[] splittedName = Util.splitOn('.', name, 0, name.length());
508
			Object value = this.packageFragments.get(splittedName);
534
			// lookup working copies package fragments
509
			if (value == null)
535
			Object workingCopyRoot = this.workingCopyFragmentsCache.get(splittedName);
510
				return null;
536
			if (workingCopyRoot != null) {
511
			if (value instanceof PackageFragmentRoot) {
537
				if (workingCopyRoot instanceof PackageFragmentRoot) {
512
				return new IPackageFragment[] {((PackageFragmentRoot) value).getPackageFragment(splittedName)};
538
					oneFragment = new IPackageFragment[] {((PackageFragmentRoot) workingCopyRoot).getPackageFragment(splittedName)};
513
			} else {
539
				} else {
514
				IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) value;
540
					pkgs = new ArrayList();
515
				IPackageFragment[] result = new IPackageFragment[roots.length];
541
					knownPkgs = new HashSet();
516
				for (int i= 0; i < roots.length; i++) {
542
					IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) workingCopyRoot;
517
					result[i] = ((PackageFragmentRoot) roots[i]).getPackageFragment(splittedName);
543
					for (int i= 0; i < roots.length; i++) {
544
						IPackageFragment pkg = ((PackageFragmentRoot) roots[i]).getPackageFragment(splittedName);
545
						pkgs.add(pkg);
546
						knownPkgs.add(pkg);
547
					}
548
				}
549
			}
550
			// lookup other package fragments
551
			for (int i = 0, length = this.packageFragmentsCaches.length; i < length; i++) {
552
				if (this.packageFragmentsCaches[i].containsKey(splittedName)) {
553
					IPackageFragment pkg = ((PackageFragmentRoot) this.packageFragmentRoots[i]).getPackageFragment(splittedName);
554
					if (oneFragment == null) {
555
						oneFragment = new IPackageFragment[] {pkg};
556
					} else {
557
						if (pkgs == null) {
558
							pkgs = new ArrayList();
559
							pkgs.add(oneFragment[0]);
560
							knownPkgs = new HashSet();
561
							knownPkgs.add(oneFragment[0]);
562
						}
563
						if (!knownPkgs.contains(pkg))
564
							pkgs.add(pkg);
565
					}
518
				}
566
				}
519
				return result;
520
			}
567
			}
568
			if (pkgs == null) return oneFragment;
569
			int resultLength = pkgs.size();
570
			IPackageFragment[] result = new IPackageFragment[resultLength];
571
			pkgs.toArray(result);
572
			return result;
521
		}
573
		}
522
	}
574
	}
523
575
Lines 769-775 Link Here
769
	}
821
	}
770
	
822
	
771
	public boolean isPackage(String[] pkgName) {
823
	public boolean isPackage(String[] pkgName) {
772
		return this.packageFragments.get(pkgName) != null;
824
		if (this.workingCopyFragmentsCache.containsKey(pkgName))
825
			return true;
826
		for (int i = 0, length = this.packageFragmentsCaches.length; i < length; i++) {
827
			if (this.packageFragmentsCaches[i].containsKey(pkgName))
828
				return true;
829
		}
830
		return false;
773
	}
831
	}
774
832
775
	/**
833
	/**
Lines 826-838 Link Here
826
		}
884
		}
827
*/		if (partialMatch) {
885
*/		if (partialMatch) {
828
			String[] splittedName = Util.splitOn('.', name, 0, name.length());
886
			String[] splittedName = Util.splitOn('.', name, 0, name.length());
829
			Object[][] keys = this.packageFragments.keyTable;
887
			// lookup working copies package fragments
888
			Object[][] keys = this.workingCopyFragmentsCache.keyTable;
830
			for (int i = 0, length = keys.length; i < length; i++) {
889
			for (int i = 0, length = keys.length; i < length; i++) {
831
				if (requestor.isCanceled())
890
				if (requestor.isCanceled())
832
					return;
891
					return;
833
				String[] pkgName = (String[]) keys[i];
892
				String[] pkgName = (String[]) keys[i];
834
				if (pkgName != null && Util.startsWithIgnoreCase(pkgName, splittedName)) {
893
				if (pkgName != null && Util.startsWithIgnoreCase(pkgName, splittedName)) {
835
					Object value = this.packageFragments.valueTable[i];
894
					Object value = this.workingCopyFragmentsCache.valueTable[i];
836
					if (value instanceof PackageFragmentRoot) {
895
					if (value instanceof PackageFragmentRoot) {
837
						PackageFragmentRoot root = (PackageFragmentRoot) value;
896
						PackageFragmentRoot root = (PackageFragmentRoot) value;
838
						requestor.acceptPackageFragment(root.getPackageFragment(pkgName));				
897
						requestor.acceptPackageFragment(root.getPackageFragment(pkgName));				
Lines 847-859 Link Here
847
					}
906
					}
848
				}
907
				}
849
			}
908
			}
909
			// lookup other package fragments
910
			for (int i = 0, length = this.packageFragmentsCaches.length; i < length; i++) {
911
				HashtableOfArrayToObject packageFragmentCache = this.packageFragmentsCaches[i];
912
				PackageFragmentRoot root = (PackageFragmentRoot) this.packageFragmentRoots[i];
913
				keys = packageFragmentCache.keyTable;
914
				for (int j = 0, length2 = keys.length; j < length2; j++) {
915
					if (requestor.isCanceled())
916
						return;
917
					String[] pkgName = (String[]) keys[j];
918
					if (pkgName != null && Util.startsWithIgnoreCase(pkgName, splittedName)) {
919
						requestor.acceptPackageFragment(root.getPackageFragment(pkgName));				
920
					}
921
				}
922
			}
850
		} else {
923
		} else {
851
			String[] splittedName = Util.splitOn('.', name, 0, name.length());
924
			String[] splittedName = Util.splitOn('.', name, 0, name.length());
852
			Object value = this.packageFragments.get(splittedName);
925
			// lookup working copies package fragments
853
			if (value instanceof PackageFragmentRoot) {
926
			Object workingCopyRoot = this.workingCopyFragmentsCache.get(splittedName);
854
				requestor.acceptPackageFragment(((PackageFragmentRoot) value).getPackageFragment(splittedName));
927
			if (workingCopyRoot instanceof PackageFragmentRoot) {
928
				requestor.acceptPackageFragment(((PackageFragmentRoot) workingCopyRoot).getPackageFragment(splittedName));
855
			} else {
929
			} else {
856
				IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) value;
930
				IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) workingCopyRoot;
857
				if (roots != null) {
931
				if (roots != null) {
858
					for (int i = 0, length = roots.length; i < length; i++) {
932
					for (int i = 0, length = roots.length; i < length; i++) {
859
						if (requestor.isCanceled())
933
						if (requestor.isCanceled())
Lines 862-867 Link Here
862
						requestor.acceptPackageFragment(root.getPackageFragment(splittedName));
936
						requestor.acceptPackageFragment(root.getPackageFragment(splittedName));
863
					}
937
					}
864
				}
938
				}
939
			}	
940
			// lookup other package fragments
941
			for (int i = 0, length = this.packageFragmentsCaches.length; i < length; i++) {
942
				if (requestor.isCanceled())
943
					return;
944
				if (this.packageFragmentsCaches[i].containsKey(splittedName)) {
945
					requestor.acceptPackageFragment(((PackageFragmentRoot) this.packageFragmentRoots[i]).getPackageFragment(splittedName));
946
				}
865
			}
947
			}
866
		}
948
		}
867
	}
949
	}

Return to bug 182930