Lines 172-179
Link Here
|
172 |
|
172 |
|
173 |
private static final String ENABLE_NEW_FORMATTER = JavaCore.PLUGIN_ID + "/formatter/enable_new" ; //$NON-NLS-1$ |
173 |
private static final String ENABLE_NEW_FORMATTER = JavaCore.PLUGIN_ID + "/formatter/enable_new" ; //$NON-NLS-1$ |
174 |
|
174 |
|
175 |
private final static String DIRTY_CACHE = "***dirty***"; //$NON-NLS-1$ |
175 |
private final static String INDEXED_SECONDARY_TYPES = "#@*_indexing secondary cache_*@#"; //$NON-NLS-1$ |
176 |
private final static HashMap NO_SECONDARY_TYPES = new HashMap(0); |
|
|
177 |
|
176 |
|
178 |
public static boolean PERF_VARIABLE_INITIALIZER = false; |
177 |
public static boolean PERF_VARIABLE_INITIALIZER = false; |
179 |
public static boolean PERF_CONTAINER_INITIALIZER = false; |
178 |
public static boolean PERF_CONTAINER_INITIALIZER = false; |
Lines 820-826
Link Here
|
820 |
|
819 |
|
821 |
public IEclipsePreferences preferences; |
820 |
public IEclipsePreferences preferences; |
822 |
public Hashtable options; |
821 |
public Hashtable options; |
823 |
public HashMap secondaryTypes; |
822 |
public Hashtable secondaryTypes; |
824 |
public LRUCache javadocCache; |
823 |
public LRUCache javadocCache; |
825 |
|
824 |
|
826 |
public PerProjectInfo(IProject project) { |
825 |
public PerProjectInfo(IProject project) { |
Lines 1435-1548
Link Here
|
1435 |
} |
1434 |
} |
1436 |
|
1435 |
|
1437 |
/** |
1436 |
/** |
1438 |
* Get all secondary types for a project and store result in per project info cache. |
|
|
1439 |
* |
1440 |
* @param project Project we want get secondary types from |
1441 |
* @return HashMap Table of secondary type names->path for given project |
1442 |
*/ |
1443 |
public HashMap getSecondaryTypes(IJavaProject project, boolean waitForIndexes, IProgressMonitor monitor) throws JavaModelException { |
1444 |
if (VERBOSE) { |
1445 |
StringBuffer buffer = new StringBuffer("JavaModelManager.getSecondaryTypesPaths("); //$NON-NLS-1$ |
1446 |
buffer.append(project.getElementName()); |
1447 |
buffer.append(')'); |
1448 |
Util.verbose(buffer.toString()); |
1449 |
} |
1450 |
|
1451 |
// Wait the end of indexing if requested |
1452 |
final PerProjectInfo projectInfo = getPerProjectInfoCheckExistence(project.getProject()); |
1453 |
IndexManager manager = getIndexManager(); |
1454 |
boolean indexing = manager.awaitingJobsCount() > 0; |
1455 |
if (indexing && waitForIndexes) { |
1456 |
while (manager.awaitingJobsCount() > 0) { |
1457 |
if (monitor != null && monitor.isCanceled()) { |
1458 |
if (projectInfo.secondaryTypes == null) return NO_SECONDARY_TYPES; |
1459 |
return projectInfo.secondaryTypes; |
1460 |
} |
1461 |
try { |
1462 |
Thread.sleep(10); |
1463 |
} catch (InterruptedException e) { |
1464 |
if (projectInfo.secondaryTypes == null) return NO_SECONDARY_TYPES; |
1465 |
return projectInfo.secondaryTypes; |
1466 |
} |
1467 |
} |
1468 |
} |
1469 |
|
1470 |
// Return cache if not empty and not dirty |
1471 |
if (projectInfo.secondaryTypes != null && projectInfo.secondaryTypes.get(DIRTY_CACHE) == null) { |
1472 |
return projectInfo.secondaryTypes; |
1473 |
} |
1474 |
|
1475 |
// Return cache if not waiting for indexing |
1476 |
if (indexing && !waitForIndexes) { |
1477 |
if (projectInfo.secondaryTypes == null) { |
1478 |
return NO_SECONDARY_TYPES; // cache is not initialized return empty one |
1479 |
} |
1480 |
return projectInfo.secondaryTypes; // cache is dirty => return current one... |
1481 |
} |
1482 |
|
1483 |
// Init variables for search |
1484 |
final HashMap secondaryTypes = new HashMap(3); |
1485 |
IRestrictedAccessTypeRequestor nameRequestor = new IRestrictedAccessTypeRequestor() { |
1486 |
public void acceptType(int modifiers, char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path, AccessRestriction access) { |
1487 |
String key = packageName==null ? "" : new String(packageName); //$NON-NLS-1$ |
1488 |
HashMap types = (HashMap) secondaryTypes.get(key); |
1489 |
if (types == null) types = new HashMap(3); |
1490 |
types.put(new String(simpleTypeName), path); |
1491 |
secondaryTypes.put(key, types); |
1492 |
} |
1493 |
}; |
1494 |
|
1495 |
// Build scope using prereq projects but only source folders |
1496 |
IPackageFragmentRoot[] allRoots = project.getAllPackageFragmentRoots(); |
1497 |
int length = allRoots.length, size = 0; |
1498 |
IPackageFragmentRoot[] allSourceFolders = new IPackageFragmentRoot[length]; |
1499 |
for (int i=0; i<length; i++) { |
1500 |
if (allRoots[i].getKind() == IPackageFragmentRoot.K_SOURCE) { |
1501 |
allSourceFolders[size++] = allRoots[i]; |
1502 |
} |
1503 |
} |
1504 |
if (size < length) { |
1505 |
System.arraycopy(allSourceFolders, 0, allSourceFolders = new IPackageFragmentRoot[size], 0, size); |
1506 |
} |
1507 |
|
1508 |
// Search all secondary types on scope |
1509 |
new BasicSearchEngine().searchAllSecondaryTypeNames(allSourceFolders, nameRequestor, monitor); |
1510 |
if (VERBOSE) { |
1511 |
System.out.print(Thread.currentThread() + " -> secondary paths: "); //$NON-NLS-1$ |
1512 |
System.out.println(); |
1513 |
Iterator keys = secondaryTypes.keySet().iterator(); |
1514 |
while (keys.hasNext()) { |
1515 |
String qualifiedName = (String) keys.next(); |
1516 |
Util.verbose(" - "+qualifiedName+'-'+secondaryTypes.get(qualifiedName) ); //$NON-NLS-1$ |
1517 |
} |
1518 |
} |
1519 |
|
1520 |
// Build types from paths |
1521 |
Iterator packages = secondaryTypes.keySet().iterator(); |
1522 |
while (packages.hasNext()) { |
1523 |
String packName = (String) packages.next(); |
1524 |
HashMap types = (HashMap) secondaryTypes.get(packName); |
1525 |
Iterator names = types.keySet().iterator(); |
1526 |
while (names.hasNext()) { |
1527 |
String typeName = (String) names.next(); |
1528 |
String path = (String) types.get(typeName); |
1529 |
if (org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(path)) { |
1530 |
IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(path)); |
1531 |
ICompilationUnit unit = JavaModelManager.createCompilationUnitFrom(file, null); |
1532 |
IType type = unit.getType(typeName); |
1533 |
types.put(typeName, type); // replace stored path with type itself |
1534 |
} |
1535 |
} |
1536 |
} |
1537 |
|
1538 |
// Store result in per project info cache if still null or dirty (may have been set by another thread...) |
1539 |
if (projectInfo.secondaryTypes == null || projectInfo.secondaryTypes.get(DIRTY_CACHE) != null) { |
1540 |
projectInfo.secondaryTypes = secondaryTypes; |
1541 |
} |
1542 |
return projectInfo.secondaryTypes; |
1543 |
} |
1544 |
|
1545 |
/** |
1546 |
* Returns the temporary cache for newly opened elements for the current thread. |
1437 |
* Returns the temporary cache for newly opened elements for the current thread. |
1547 |
* Creates it if not already created. |
1438 |
* Creates it if not already created. |
1548 |
*/ |
1439 |
*/ |
Lines 2400-2485
Link Here
|
2400 |
MANAGER = new JavaModelManager(); |
2291 |
MANAGER = new JavaModelManager(); |
2401 |
} |
2292 |
} |
2402 |
|
2293 |
|
2403 |
/** |
|
|
2404 |
* Remove a file from its project secondary types cache. |
2405 |
* |
2406 |
* @param file File to remove |
2407 |
*/ |
2408 |
public void removeFromSecondaryTypesCache(IFile file) { |
2409 |
if (VERBOSE) { |
2410 |
StringBuffer buffer = new StringBuffer("JavaModelManager.removeSecondaryTypePaths("); //$NON-NLS-1$ |
2411 |
buffer.append(file.getName()); |
2412 |
buffer.append(')'); |
2413 |
Util.verbose(buffer.toString()); |
2414 |
} |
2415 |
if (file != null) { |
2416 |
PerProjectInfo projectInfo = getPerProjectInfo(file.getProject(), false); |
2417 |
if (projectInfo != null && projectInfo.secondaryTypes != null) { |
2418 |
if (VERBOSE) { |
2419 |
Util.verbose("-> remove file from cache of project: "+file.getProject().getName()); //$NON-NLS-1$ |
2420 |
} |
2421 |
Iterator packages = projectInfo.secondaryTypes.keySet().iterator(); |
2422 |
while (packages.hasNext()) { |
2423 |
String packName = (String) packages.next(); |
2424 |
Object object = projectInfo.secondaryTypes.get(packName); |
2425 |
if (object instanceof HashMap) { |
2426 |
HashMap types = (HashMap) object; |
2427 |
Iterator names = types.keySet().iterator(); |
2428 |
while (names.hasNext()) { |
2429 |
String typeName = (String) names.next(); |
2430 |
IType type = (IType) types.get(typeName); |
2431 |
if (file.equals(type.getResource())) { |
2432 |
types.remove(typeName); |
2433 |
if (types.size() == 0) { |
2434 |
projectInfo.secondaryTypes.remove(packName); |
2435 |
} |
2436 |
return; |
2437 |
} |
2438 |
} |
2439 |
} |
2440 |
} |
2441 |
} |
2442 |
} |
2443 |
} |
2444 |
|
2445 |
/** |
2446 |
* Reset secondary types cache for a project got from given path. |
2447 |
* If secondary types cache already exist, do not reset it now to avoid |
2448 |
* cache desynchronization (this reset is done in indexing thread...). |
2449 |
* Instead flag the cache as dirty to store the fact that current cache |
2450 |
* should be recomputed when indexing will be ended. |
2451 |
* |
2452 |
* @param path Path of file containing a secondary type |
2453 |
*/ |
2454 |
public void resetSecondaryTypesCache(String path) { |
2455 |
if (VERBOSE) { |
2456 |
StringBuffer buffer = new StringBuffer("JavaModelManager.resetSecondaryTypePaths("); //$NON-NLS-1$ |
2457 |
buffer.append(path); |
2458 |
buffer.append(')'); |
2459 |
Util.verbose(buffer.toString()); |
2460 |
} |
2461 |
IWorkspaceRoot wRoot = ResourcesPlugin.getWorkspace().getRoot(); |
2462 |
IResource resource = wRoot.findMember(path); |
2463 |
if (resource != null) { |
2464 |
PerProjectInfo projectInfo = getPerProjectInfo(resource.getProject(), false); |
2465 |
if (projectInfo != null) { |
2466 |
if (VERBOSE) { |
2467 |
Util.verbose("-> reset cache for project: "+resource.getProject().getName()); //$NON-NLS-1$ |
2468 |
} |
2469 |
if (projectInfo.secondaryTypes != null) { |
2470 |
Object dirty = projectInfo.secondaryTypes.get(DIRTY_CACHE); |
2471 |
if (dirty == null) { |
2472 |
projectInfo.secondaryTypes.put(DIRTY_CACHE, resource); |
2473 |
} else { |
2474 |
HashSet resources = (dirty instanceof HashSet) ? (HashSet) dirty : new HashSet(3); |
2475 |
resources.add(resource); |
2476 |
projectInfo.secondaryTypes.put(DIRTY_CACHE, resource); |
2477 |
} |
2478 |
} |
2479 |
} |
2480 |
} |
2481 |
} |
2482 |
|
2483 |
/* |
2294 |
/* |
2484 |
* Resets the temporary cache for newly created elements to null. |
2295 |
* Resets the temporary cache for newly created elements to null. |
2485 |
*/ |
2296 |
*/ |
Lines 2694-2699
Link Here
|
2694 |
} |
2505 |
} |
2695 |
|
2506 |
|
2696 |
/** |
2507 |
/** |
|
|
2508 |
* Add a secondary type in temporary indexing cache for a project got from given path. |
2509 |
* |
2510 |
* Current secondary types cache is not modified as we want to wait that indexing |
2511 |
* was finished before taking new secondary types into account. |
2512 |
* |
2513 |
* Indexing cache is a specific entry in secondary types cache which key is |
2514 |
* {@link #INDEXED_SECONDARY_TYPES } and value a map with same structure than |
2515 |
* secondary types cache itself. |
2516 |
* |
2517 |
* @see #secondaryTypes(IJavaProject, boolean, IProgressMonitor) |
2518 |
*/ |
2519 |
public void secondaryTypeAdding(String path, char[] key) { |
2520 |
if (VERBOSE) { |
2521 |
StringBuffer buffer = new StringBuffer("JavaModelManager.addSecondaryType("); //$NON-NLS-1$ |
2522 |
buffer.append(path); |
2523 |
buffer.append(','); |
2524 |
buffer.append('['); |
2525 |
buffer.append(new String(key)); |
2526 |
buffer.append(']'); |
2527 |
buffer.append(')'); |
2528 |
Util.verbose(buffer.toString()); |
2529 |
} |
2530 |
IWorkspaceRoot wRoot = ResourcesPlugin.getWorkspace().getRoot(); |
2531 |
IResource resource = wRoot.findMember(path); |
2532 |
if (resource != null) { |
2533 |
if (org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(path) && resource.getType() == IResource.FILE) { |
2534 |
IProject project = resource.getProject(); |
2535 |
try { |
2536 |
PerProjectInfo projectInfo = getPerProjectInfoCheckExistence(project); |
2537 |
// Get or create map to cache secondary types while indexing (can be not synchronized as indexing insure a non-concurrent usage) |
2538 |
HashMap indexedSecondaryTypes = null; |
2539 |
if (projectInfo.secondaryTypes == null) { |
2540 |
projectInfo.secondaryTypes = new Hashtable(3); |
2541 |
indexedSecondaryTypes = new HashMap(3); |
2542 |
projectInfo.secondaryTypes.put(INDEXED_SECONDARY_TYPES, indexedSecondaryTypes); |
2543 |
} else { |
2544 |
indexedSecondaryTypes = (HashMap) projectInfo.secondaryTypes.get(INDEXED_SECONDARY_TYPES); |
2545 |
if (indexedSecondaryTypes == null) { |
2546 |
indexedSecondaryTypes = new HashMap(3); |
2547 |
projectInfo.secondaryTypes.put(INDEXED_SECONDARY_TYPES, indexedSecondaryTypes); |
2548 |
} |
2549 |
} |
2550 |
// Store the secondary type in temporary cache (these are just handles => no problem to create it now...) |
2551 |
HashMap allTypes = (HashMap) indexedSecondaryTypes.get(resource); |
2552 |
if (allTypes == null) { |
2553 |
allTypes = new HashMap(3); |
2554 |
indexedSecondaryTypes.put(resource, allTypes); |
2555 |
} |
2556 |
ICompilationUnit unit = JavaModelManager.createCompilationUnitFrom((IFile)resource, null); |
2557 |
if (unit != null) { |
2558 |
char[][] names = CharOperation.splitOn('/', key); |
2559 |
String typeName = new String(names[0]); |
2560 |
String packName = new String(names[1]); |
2561 |
HashMap packageTypes = (HashMap) allTypes.get(packName); |
2562 |
if (packageTypes == null) { |
2563 |
packageTypes = new HashMap(3); |
2564 |
allTypes.put(packName, packageTypes); |
2565 |
} |
2566 |
packageTypes.put(typeName, unit.getType(typeName)); |
2567 |
} |
2568 |
if (VERBOSE) { |
2569 |
Util.verbose(" - indexing cache:"); //$NON-NLS-1$ |
2570 |
Iterator keys = indexedSecondaryTypes.keySet().iterator(); |
2571 |
while (keys.hasNext()) { |
2572 |
IFile file = (IFile) keys.next(); |
2573 |
Util.verbose(" + "+file.getFullPath()+':'+indexedSecondaryTypes.get(file) ); //$NON-NLS-1$ |
2574 |
} |
2575 |
} |
2576 |
} |
2577 |
catch (JavaModelException jme) { |
2578 |
// do nothing |
2579 |
} |
2580 |
} |
2581 |
} |
2582 |
} |
2583 |
|
2584 |
/** |
2585 |
* Get all secondary types for a project and store result in per project info cache. |
2586 |
* |
2587 |
* This cache is an Hashtable<String, HashMap<String, IType>>: |
2588 |
* - key: package name |
2589 |
* - value: |
2590 |
* + key: type name |
2591 |
* + value: java model handle for the secondary type |
2592 |
* Hashtable was used to protect callers from possible concurrent access. |
2593 |
* |
2594 |
* Note that this map may have a specific entry which key is {@link #INDEXED_SECONDARY_TYPES } |
2595 |
* and value is a map containing all secondary types created during indexing. |
2596 |
* When this key is in cache and indexing is finished, returned map is merged |
2597 |
* with the value of this special key. If indexing is not finished and caller does |
2598 |
* not wait for the end of indexing, returned map is the current secondary |
2599 |
* types cache content which may be invalid... |
2600 |
* |
2601 |
* @param project Project we want get secondary types from |
2602 |
* @return HashMap Table of secondary type names->path for given project |
2603 |
*/ |
2604 |
public Map secondaryTypes(IJavaProject project, boolean waitForIndexes, IProgressMonitor monitor) throws JavaModelException { |
2605 |
if (VERBOSE) { |
2606 |
StringBuffer buffer = new StringBuffer("JavaModelManager.secondaryTypes("); //$NON-NLS-1$ |
2607 |
buffer.append(project.getElementName()); |
2608 |
buffer.append(','); |
2609 |
buffer.append(waitForIndexes); |
2610 |
buffer.append(')'); |
2611 |
Util.verbose(buffer.toString()); |
2612 |
} |
2613 |
|
2614 |
// Return cache if not empty and there's no new secondary types created during indexing |
2615 |
final PerProjectInfo projectInfo = getPerProjectInfoCheckExistence(project.getProject()); |
2616 |
Map indexingSecondaryCache = projectInfo.secondaryTypes == null ? null : (Map) projectInfo.secondaryTypes.get(INDEXED_SECONDARY_TYPES); |
2617 |
if (projectInfo.secondaryTypes != null && indexingSecondaryCache == null) { |
2618 |
return projectInfo.secondaryTypes; |
2619 |
} |
2620 |
|
2621 |
// Perform search request only if secondary types cache is not initialized yet (this will happen only once!) |
2622 |
if (projectInfo.secondaryTypes == null) { |
2623 |
return secondaryTypesSearching(project, waitForIndexes, monitor, projectInfo); |
2624 |
} |
2625 |
|
2626 |
// New secondary types have been created while indexing secondary types cache |
2627 |
// => need to know whether the indexing is finished or not |
2628 |
boolean indexing = this.indexManager.awaitingJobsCount() > 0; |
2629 |
if (indexing) { |
2630 |
if (!waitForIndexes) { |
2631 |
// Indexing is running but caller cannot wait => return current cache |
2632 |
return projectInfo.secondaryTypes; |
2633 |
} |
2634 |
|
2635 |
// Wait for the end of indexing or a cancel |
2636 |
while (this.indexManager.awaitingJobsCount() > 0) { |
2637 |
if (monitor != null && monitor.isCanceled()) { |
2638 |
return projectInfo.secondaryTypes; |
2639 |
} |
2640 |
try { |
2641 |
Thread.sleep(10); |
2642 |
} catch (InterruptedException e) { |
2643 |
return projectInfo.secondaryTypes; |
2644 |
} |
2645 |
} |
2646 |
} |
2647 |
|
2648 |
// Indexing is finished => merge caches and return result |
2649 |
return secondaryTypesMerging(projectInfo.secondaryTypes); |
2650 |
} |
2651 |
|
2652 |
/* |
2653 |
* Return secondary types cache merged with new secondary types created while indexing |
2654 |
* Note that merge result is directly stored in given parameter map. |
2655 |
*/ |
2656 |
private Hashtable secondaryTypesMerging(Hashtable secondaryTypes) { |
2657 |
if (VERBOSE) { |
2658 |
Util.verbose("JavaModelManager.getSecondaryTypesMerged()"); //$NON-NLS-1$ |
2659 |
Util.verbose(" - current cache to merge:"); //$NON-NLS-1$ |
2660 |
Iterator keys = secondaryTypes.keySet().iterator(); |
2661 |
while (keys.hasNext()) { |
2662 |
String packName = (String) keys.next(); |
2663 |
Util.verbose(" + "+packName+':'+secondaryTypes.get(packName) ); //$NON-NLS-1$ |
2664 |
} |
2665 |
} |
2666 |
|
2667 |
// Return current cache if there's no indexing cache (double check, this should not happen) |
2668 |
HashMap indexedSecondaryTypes = (HashMap) secondaryTypes.remove(INDEXED_SECONDARY_TYPES); |
2669 |
if (indexedSecondaryTypes == null) { |
2670 |
return secondaryTypes; |
2671 |
} |
2672 |
|
2673 |
// Merge indexing cache in secondary types one |
2674 |
Iterator files = indexedSecondaryTypes.keySet().iterator(); |
2675 |
while (files.hasNext()) { |
2676 |
IFile file = (IFile) files.next(); |
2677 |
|
2678 |
// Remove all secondary types of indexed file from cache |
2679 |
secondaryTypesRemoving(secondaryTypes, file); |
2680 |
|
2681 |
// Add all indexing file secondary types in given secondary types cache |
2682 |
HashMap fileSecondaryTypes = (HashMap) indexedSecondaryTypes.get(file); |
2683 |
Iterator packages = fileSecondaryTypes.keySet().iterator(); |
2684 |
while (packages.hasNext()) { |
2685 |
String packageName = (String) packages.next(); |
2686 |
HashMap cachedTypes = (HashMap) secondaryTypes.get(packageName); |
2687 |
if (cachedTypes == null) { |
2688 |
secondaryTypes.put(packageName, fileSecondaryTypes.get(packageName)); |
2689 |
} else { |
2690 |
HashMap types = (HashMap) fileSecondaryTypes.get(packageName); |
2691 |
Iterator typeNames = types.keySet().iterator(); |
2692 |
while (typeNames.hasNext()) { |
2693 |
String typeName = (String) typeNames.next(); |
2694 |
cachedTypes.put(typeName, types.get(typeName)); |
2695 |
} |
2696 |
} |
2697 |
} |
2698 |
} |
2699 |
if (VERBOSE) { |
2700 |
Util.verbose(" - secondary types cache merged:"); //$NON-NLS-1$ |
2701 |
Iterator keys = secondaryTypes.keySet().iterator(); |
2702 |
while (keys.hasNext()) { |
2703 |
String packName = (String) keys.next(); |
2704 |
Util.verbose(" + "+packName+':'+secondaryTypes.get(packName) ); //$NON-NLS-1$ |
2705 |
} |
2706 |
} |
2707 |
return secondaryTypes; |
2708 |
} |
2709 |
|
2710 |
/* |
2711 |
* Perform search request to get all secondary types of a given project. |
2712 |
* If not waiting for indexes and indexing is running, will return types found in current built indexes... |
2713 |
*/ |
2714 |
private Map secondaryTypesSearching(IJavaProject project, boolean waitForIndexes, IProgressMonitor monitor, final PerProjectInfo projectInfo) throws JavaModelException { |
2715 |
if (VERBOSE || BasicSearchEngine.VERBOSE) { |
2716 |
StringBuffer buffer = new StringBuffer("JavaModelManager.secondaryTypesSearch("); //$NON-NLS-1$ |
2717 |
buffer.append(project.getElementName()); |
2718 |
buffer.append(','); |
2719 |
buffer.append(waitForIndexes); |
2720 |
buffer.append(')'); |
2721 |
Util.verbose(buffer.toString()); |
2722 |
} |
2723 |
|
2724 |
final Hashtable secondaryTypes = new Hashtable(3); |
2725 |
IRestrictedAccessTypeRequestor nameRequestor = new IRestrictedAccessTypeRequestor() { |
2726 |
public void acceptType(int modifiers, char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path, AccessRestriction access) { |
2727 |
String key = packageName==null ? "" : new String(packageName); //$NON-NLS-1$ |
2728 |
HashMap types = (HashMap) secondaryTypes.get(key); |
2729 |
if (types == null) types = new HashMap(3); |
2730 |
types.put(new String(simpleTypeName), path); |
2731 |
secondaryTypes.put(key, types); |
2732 |
} |
2733 |
}; |
2734 |
|
2735 |
// Build scope using prereq projects but only source folders |
2736 |
IPackageFragmentRoot[] allRoots = project.getAllPackageFragmentRoots(); |
2737 |
int length = allRoots.length, size = 0; |
2738 |
IPackageFragmentRoot[] allSourceFolders = new IPackageFragmentRoot[length]; |
2739 |
for (int i=0; i<length; i++) { |
2740 |
if (allRoots[i].getKind() == IPackageFragmentRoot.K_SOURCE) { |
2741 |
allSourceFolders[size++] = allRoots[i]; |
2742 |
} |
2743 |
} |
2744 |
if (size < length) { |
2745 |
System.arraycopy(allSourceFolders, 0, allSourceFolders = new IPackageFragmentRoot[size], 0, size); |
2746 |
} |
2747 |
|
2748 |
// Search all secondary types on scope |
2749 |
new BasicSearchEngine().searchAllSecondaryTypeNames(allSourceFolders, nameRequestor, waitForIndexes, monitor); |
2750 |
|
2751 |
// Build types from paths |
2752 |
Iterator packages = secondaryTypes.keySet().iterator(); |
2753 |
while (packages.hasNext()) { |
2754 |
String packName = (String) packages.next(); |
2755 |
HashMap types = (HashMap) secondaryTypes.get(packName); |
2756 |
Iterator names = types.keySet().iterator(); |
2757 |
while (names.hasNext()) { |
2758 |
String typeName = (String) names.next(); |
2759 |
String path = (String) types.get(typeName); |
2760 |
if (org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(path)) { |
2761 |
IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(path)); |
2762 |
ICompilationUnit unit = JavaModelManager.createCompilationUnitFrom(file, null); |
2763 |
IType type = unit.getType(typeName); |
2764 |
types.put(typeName, type); // replace stored path with type itself |
2765 |
} |
2766 |
} |
2767 |
} |
2768 |
|
2769 |
// Store result in per project info cache if still null or there's still an indexing cache (may have been set by another thread...) |
2770 |
if (projectInfo.secondaryTypes == null || projectInfo.secondaryTypes.get(INDEXED_SECONDARY_TYPES) != null) { |
2771 |
projectInfo.secondaryTypes = secondaryTypes; |
2772 |
if (VERBOSE || BasicSearchEngine.VERBOSE) { |
2773 |
System.out.print(Thread.currentThread() + " -> secondary paths stored in cache: "); //$NON-NLS-1$ |
2774 |
System.out.println(); |
2775 |
Iterator keys = secondaryTypes.keySet().iterator(); |
2776 |
while (keys.hasNext()) { |
2777 |
String qualifiedName = (String) keys.next(); |
2778 |
Util.verbose(" - "+qualifiedName+'-'+secondaryTypes.get(qualifiedName) ); //$NON-NLS-1$ |
2779 |
} |
2780 |
} |
2781 |
} |
2782 |
return projectInfo.secondaryTypes; |
2783 |
} |
2784 |
|
2785 |
/** |
2786 |
* Remove from secondary types cache all types belonging to a given file. |
2787 |
* Clean secondary types cache built while indexing if requested. |
2788 |
* |
2789 |
* Project's secondary types cache is found using file location. |
2790 |
* |
2791 |
* @param file File to remove |
2792 |
*/ |
2793 |
public void secondaryTypesRemoving(IFile file, boolean cleanIndexCache) { |
2794 |
if (VERBOSE) { |
2795 |
StringBuffer buffer = new StringBuffer("JavaModelManager.removeFromSecondaryTypesCache("); //$NON-NLS-1$ |
2796 |
buffer.append(file.getName()); |
2797 |
buffer.append(')'); |
2798 |
Util.verbose(buffer.toString()); |
2799 |
} |
2800 |
if (file != null) { |
2801 |
PerProjectInfo projectInfo = getPerProjectInfo(file.getProject(), false); |
2802 |
if (projectInfo != null && projectInfo.secondaryTypes != null) { |
2803 |
if (VERBOSE) { |
2804 |
Util.verbose("-> remove file from cache of project: "+file.getProject().getName()); //$NON-NLS-1$ |
2805 |
} |
2806 |
|
2807 |
// Clean current cache |
2808 |
secondaryTypesRemoving(projectInfo.secondaryTypes, file); |
2809 |
|
2810 |
// Clean indexing cache if necessary |
2811 |
if (!cleanIndexCache) return; |
2812 |
HashMap indexingCache = (HashMap) projectInfo.secondaryTypes.get(INDEXED_SECONDARY_TYPES); |
2813 |
if (indexingCache != null) { |
2814 |
Set keys = indexingCache.keySet(); |
2815 |
int filesSize = keys.size(), filesCount = 0; |
2816 |
IFile[] removed = null; |
2817 |
Iterator cachedFiles = keys.iterator(); |
2818 |
while (cachedFiles.hasNext()) { |
2819 |
IFile cachedFile = (IFile) cachedFiles.next(); |
2820 |
if (file.equals(cachedFile)) { |
2821 |
if (removed == null) removed = new IFile[filesSize]; |
2822 |
filesSize--; |
2823 |
removed[filesCount++] = cachedFile; |
2824 |
} |
2825 |
} |
2826 |
for (int i=0; i<filesCount; i++) { |
2827 |
indexingCache.remove(removed[i]); |
2828 |
} |
2829 |
} |
2830 |
} |
2831 |
} |
2832 |
} |
2833 |
|
2834 |
/* |
2835 |
* Remove from a given cache map all secondary types belonging to a given file. |
2836 |
* Note that there can have several secondary types per file... |
2837 |
*/ |
2838 |
private void secondaryTypesRemoving(Hashtable secondaryTypesMap, IFile file) { |
2839 |
if (VERBOSE) { |
2840 |
StringBuffer buffer = new StringBuffer("JavaModelManager.removeSecondaryTypesFromMap("); //$NON-NLS-1$ |
2841 |
Iterator keys = secondaryTypesMap.keySet().iterator(); |
2842 |
while (keys.hasNext()) { |
2843 |
String qualifiedName = (String) keys.next(); |
2844 |
buffer.append(qualifiedName+':'+secondaryTypesMap.get(qualifiedName)); |
2845 |
} |
2846 |
buffer.append(','); |
2847 |
buffer.append(file.getFullPath()); |
2848 |
buffer.append(')'); |
2849 |
Util.verbose(buffer.toString()); |
2850 |
} |
2851 |
Set packageKeys = secondaryTypesMap.keySet(); |
2852 |
int packagesSize = packageKeys.size(), removedPackagesCount = 0; |
2853 |
String[] removedPackages = null; |
2854 |
Iterator packages = packageKeys.iterator(); |
2855 |
while (packages.hasNext()) { |
2856 |
String packName = (String) packages.next(); |
2857 |
if (packName != INDEXED_SECONDARY_TYPES) { // skip indexing cache entry if present (!= is intentional) |
2858 |
HashMap types = (HashMap) secondaryTypesMap.get(packName); |
2859 |
Set nameKeys = types.keySet(); |
2860 |
int namesSize = nameKeys.size(), removedNamesCount = 0; |
2861 |
String[] removedNames = null; |
2862 |
Iterator names = nameKeys.iterator(); |
2863 |
while (names.hasNext()) { |
2864 |
String typeName = (String) names.next(); |
2865 |
IType type = (IType) types.get(typeName); |
2866 |
if (file.equals(type.getResource())) { |
2867 |
if (removedNames == null) removedNames = new String[namesSize]; |
2868 |
namesSize--; |
2869 |
removedNames[removedNamesCount++] = typeName; |
2870 |
} |
2871 |
} |
2872 |
for (int i=0; i<removedNamesCount; i++) { |
2873 |
types.remove(removedNames[i]); |
2874 |
} |
2875 |
if (types.size() == 0) { |
2876 |
if (removedPackages == null) removedPackages = new String[packagesSize]; |
2877 |
packagesSize--; |
2878 |
removedPackages[removedPackagesCount++] = packName; |
2879 |
} |
2880 |
} |
2881 |
} |
2882 |
for (int i=0; i<removedPackagesCount; i++) { |
2883 |
secondaryTypesMap.remove(removedPackages[i]); |
2884 |
} |
2885 |
if (VERBOSE) { |
2886 |
Util.verbose(" - new secondary types map:"); //$NON-NLS-1$ |
2887 |
Iterator keys = secondaryTypesMap.keySet().iterator(); |
2888 |
while (keys.hasNext()) { |
2889 |
String qualifiedName = (String) keys.next(); |
2890 |
Util.verbose(" + "+qualifiedName+':'+secondaryTypesMap.get(qualifiedName) ); //$NON-NLS-1$ |
2891 |
} |
2892 |
} |
2893 |
} |
2894 |
|
2895 |
/** |
2697 |
* Record the order in which to build the java projects (batch build). This order is based |
2896 |
* Record the order in which to build the java projects (batch build). This order is based |
2698 |
* on the projects classpath settings. |
2897 |
* on the projects classpath settings. |
2699 |
*/ |
2898 |
*/ |