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

Collapse All | Expand All

(-)search/org/eclipse/jdt/core/search/SearchEngine.java (-6 / +84 lines)
Lines 540-554 Link Here
540
540
541
	/**
541
	/**
542
	 * Searches for all top-level types and member types in the given scope.
542
	 * Searches for all top-level types and member types in the given scope.
543
	 * The search can be selecting specific types (given a package or a type name
543
	 * The search can be selecting specific types (given a package exact full name or
544
	 * prefix and match modes). 
544
	 * a type name with specific match mode). 
545
	 * 
546
	 * @param packageName the exact package full name of the searched types.<br>
547
	 * 					If you want to use a prefix or a wild-carded string for package, you need to use
548
	 * 					{@link #searchAllTypeNames(char[], int, char[], int, int, IJavaSearchScope, TypeNameRequestor, int, IProgressMonitor)} method  instead.
549
	 * @param typeName the dot-separated qualified name of the searched type (the qualification include
550
	 *					the enclosing types if the searched type is a member type), or a prefix
551
	 *					for this type, or a wild-carded string for this type.
552
	 * @param matchRule type name match rule one of
553
	 * <ul>
554
	 *		<li>{@link SearchPattern#R_EXACT_MATCH} if the package name and type name are the full names
555
	 *			of the searched types.</li>
556
	 *		<li>{@link SearchPattern#R_PREFIX_MATCH} if the package name and type name are prefixes of the names
557
	 *			of the searched types.</li>
558
	 *		<li>{@link SearchPattern#R_PATTERN_MATCH} if the package name and type name contain wild-cards.</li>
559
	 *		<li>{@link SearchPattern#R_CAMELCASE_MATCH} if type name are camel case of the names of the searched types.</li>
560
	 * </ul>
561
	 * combined with {@link SearchPattern#R_CASE_SENSITIVE},
562
	 *   e.g. {@link SearchPattern#R_EXACT_MATCH} | {@link SearchPattern#R_CASE_SENSITIVE} if an exact and case sensitive match is requested, 
563
	 *   or {@link SearchPattern#R_PREFIX_MATCH} if a prefix non case sensitive match is requested.
564
	 * @param searchFor determines the nature of the searched elements
565
	 *	<ul>
566
	 * 	<li>{@link IJavaSearchConstants#CLASS}: only look for classes</li>
567
	 *		<li>{@link IJavaSearchConstants#INTERFACE}: only look for interfaces</li>
568
	 * 	<li>{@link IJavaSearchConstants#ENUM}: only look for enumeration</li>
569
	 *		<li>{@link IJavaSearchConstants#ANNOTATION_TYPE}: only look for annotation type</li>
570
	 * 	<li>{@link IJavaSearchConstants#CLASS_AND_ENUM}: only look for classes and enumerations</li>
571
	 *		<li>{@link IJavaSearchConstants#CLASS_AND_INTERFACE}: only look for classes and interfaces</li>
572
	 * 	<li>{@link IJavaSearchConstants#TYPE}: look for all types (ie. classes, interfaces, enum and annotation types)</li>
573
	 *	</ul>
574
	 * @param scope the scope to search in
575
	 * @param nameRequestor the requestor that collects the results of the search
576
	 * @param waitingPolicy one of
577
	 * <ul>
578
	 *		<li>{@link IJavaSearchConstants#FORCE_IMMEDIATE_SEARCH} if the search should start immediately</li>
579
	 *		<li>{@link IJavaSearchConstants#CANCEL_IF_NOT_READY_TO_SEARCH} if the search should be cancelled if the
580
	 *			underlying indexer has not finished indexing the workspace</li>
581
	 *		<li>{@link IJavaSearchConstants#WAIT_UNTIL_READY_TO_SEARCH} if the search should wait for the
582
	 *			underlying indexer to finish indexing the workspace</li>
583
	 * </ul>
584
	 * @param progressMonitor the progress monitor to report progress to, or <code>null</code> if no progress
585
	 *							monitor is provided
586
	 * @exception JavaModelException if the search failed. Reasons include:
587
	 *	<ul>
588
	 *		<li>the classpath is incorrectly set</li>
589
	 *	</ul>
590
	 * @since 3.1
591
	 */
592
	public void searchAllTypeNames(
593
		final char[] packageName, 
594
		final char[] typeName,
595
		final int matchRule, 
596
		int searchFor, 
597
		IJavaSearchScope scope, 
598
		final TypeNameRequestor nameRequestor,
599
		int waitingPolicy,
600
		IProgressMonitor progressMonitor)  throws JavaModelException {
601
		
602
		TypeNameRequestorWrapper requestorWrapper = new TypeNameRequestorWrapper(nameRequestor);
603
		this.basicEngine.searchAllTypeNames(packageName, SearchPattern.R_EXACT_MATCH, typeName, matchRule, searchFor, scope, requestorWrapper, waitingPolicy, progressMonitor);
604
	}
605
606
	/**
607
	 * Searches for all top-level types and member types in the given scope.
608
	 * The search can be selecting specific types (given a package name using specific match mode
609
	 * and/or a type name using another specific match mode). 
545
	 * 
610
	 * 
546
	 * @param packageName the full name of the package of the searched types, or a prefix for this
611
	 * @param packageName the full name of the package of the searched types, or a prefix for this
547
	 *						package, or a wild-carded string for this package.
612
	 *						package, or a wild-carded string for this package.
548
	 * @param typeName the dot-separated qualified name of the searched type (the qualification include
613
	 * @param typeName the dot-separated qualified name of the searched type (the qualification include
549
	 *					the enclosing types if the searched type is a member type), or a prefix
614
	 *					the enclosing types if the searched type is a member type), or a prefix
550
	 *					for this type, or a wild-carded string for this type.
615
	 *					for this type, or a wild-carded string for this type.
551
	 * @param matchRule one of
616
	 * @param packageMatchRule one of
617
	 * <ul>
618
	 *		<li>{@link SearchPattern#R_EXACT_MATCH} if the package name and type name are the full names
619
	 *			of the searched types.</li>
620
	 *		<li>{@link SearchPattern#R_PREFIX_MATCH} if the package name and type name are prefixes of the names
621
	 *			of the searched types.</li>
622
	 *		<li>{@link SearchPattern#R_PATTERN_MATCH} if the package name and type name contain wild-cards.</li>
623
	 *		<li>{@link SearchPattern#R_CAMELCASE_MATCH} if type name are camel case of the names of the searched types.</li>
624
	 * </ul>
625
	 * combined with {@link SearchPattern#R_CASE_SENSITIVE},
626
	 *   e.g. {@link SearchPattern#R_EXACT_MATCH} | {@link SearchPattern#R_CASE_SENSITIVE} if an exact and case sensitive match is requested, 
627
	 *   or {@link SearchPattern#R_PREFIX_MATCH} if a prefix non case sensitive match is requested.
628
	 * @param typeMatchRule one of
552
	 * <ul>
629
	 * <ul>
553
	 *		<li>{@link SearchPattern#R_EXACT_MATCH} if the package name and type name are the full names
630
	 *		<li>{@link SearchPattern#R_EXACT_MATCH} if the package name and type name are the full names
554
	 *			of the searched types.</li>
631
	 *			of the searched types.</li>
Lines 590-597 Link Here
590
	 */
667
	 */
591
	public void searchAllTypeNames(
668
	public void searchAllTypeNames(
592
		final char[] packageName, 
669
		final char[] packageName, 
670
		final int packageMatchRule, 
593
		final char[] typeName,
671
		final char[] typeName,
594
		final int matchRule, 
672
		final int typeMatchRule, 
595
		int searchFor, 
673
		int searchFor, 
596
		IJavaSearchScope scope, 
674
		IJavaSearchScope scope, 
597
		final TypeNameRequestor nameRequestor,
675
		final TypeNameRequestor nameRequestor,
Lines 599-605 Link Here
599
		IProgressMonitor progressMonitor)  throws JavaModelException {
677
		IProgressMonitor progressMonitor)  throws JavaModelException {
600
		
678
		
601
		TypeNameRequestorWrapper requestorWrapper = new TypeNameRequestorWrapper(nameRequestor);
679
		TypeNameRequestorWrapper requestorWrapper = new TypeNameRequestorWrapper(nameRequestor);
602
		this.basicEngine.searchAllTypeNames(packageName, typeName, matchRule, searchFor, scope, requestorWrapper, waitingPolicy, progressMonitor);
680
		this.basicEngine.searchAllTypeNames(packageName, packageMatchRule, typeName, typeMatchRule, searchFor, scope, requestorWrapper, waitingPolicy, progressMonitor);
603
	}
681
	}
604
682
605
	/**
683
	/**
Lines 702-708 Link Here
702
		int waitingPolicy,
780
		int waitingPolicy,
703
		IProgressMonitor progressMonitor)  throws JavaModelException {
781
		IProgressMonitor progressMonitor)  throws JavaModelException {
704
		
782
		
705
		this.basicEngine.searchAllTypeNames(packageName, typeName, matchRule, searchFor, scope, new TypeNameRequestorAdapter(nameRequestor), waitingPolicy, progressMonitor);
783
		this.basicEngine.searchAllTypeNames(packageName, SearchPattern.R_EXACT_MATCH, typeName, matchRule, searchFor, scope, new TypeNameRequestorAdapter(nameRequestor), waitingPolicy, progressMonitor);
706
	}
784
	}
707
785
708
	/**
786
	/**
(-)search/org/eclipse/jdt/core/search/SearchPattern.java (-1 / +3 lines)
Lines 1777-1785 Link Here
1777
		boolean isCaseSensitive = (this.matchRule & R_CASE_SENSITIVE) != 0;
1777
		boolean isCaseSensitive = (this.matchRule & R_CASE_SENSITIVE) != 0;
1778
		boolean isCamelCase = (this.matchRule & R_CAMELCASE_MATCH) != 0;
1778
		boolean isCamelCase = (this.matchRule & R_CAMELCASE_MATCH) != 0;
1779
		int matchMode = this.matchRule & MODE_MASK;
1779
		int matchMode = this.matchRule & MODE_MASK;
1780
		boolean emptyPattern = pattern.length == 0;
1781
		if (matchMode == R_PREFIX_MATCH && emptyPattern) return true;
1780
		boolean sameLength = pattern.length == name.length;
1782
		boolean sameLength = pattern.length == name.length;
1781
		boolean canBePrefix = name.length >= pattern.length;
1783
		boolean canBePrefix = name.length >= pattern.length;
1782
		boolean matchFirstChar = !isCaseSensitive || pattern.length == 0 || (name.length > 0 &&  pattern[0] == name[0]);
1784
		boolean matchFirstChar = !isCaseSensitive || emptyPattern || (name.length > 0 &&  pattern[0] == name[0]);
1783
		if (isCamelCase && matchFirstChar && CharOperation.camelCaseMatch(pattern, name)) {
1785
		if (isCamelCase && matchFirstChar && CharOperation.camelCaseMatch(pattern, name)) {
1784
			return true;
1786
			return true;
1785
		}
1787
		}
(-)search/org/eclipse/jdt/internal/core/search/BasicSearchEngine.java (-136 / +146 lines)
Lines 504-509 Link Here
504
	}
504
	}
505
505
506
	/**
506
	/**
507
	 * Searches for all secondary types in the given scope.
508
	 * The search can be selecting specific types (given a package or a type name
509
	 * prefix and match modes). 
510
	 */
511
	public void searchAllSecondaryTypeNames(
512
			IPackageFragmentRoot[] sourceFolders,
513
			final IRestrictedAccessTypeRequestor nameRequestor,
514
			boolean waitForIndexes,
515
			IProgressMonitor progressMonitor)  throws JavaModelException {
516
517
		if (VERBOSE) {
518
			Util.verbose("BasicSearchEngine.searchAllSecondaryTypeNames(IPackageFragmentRoot[], IRestrictedAccessTypeRequestor, boolean, IProgressMonitor)"); //$NON-NLS-1$
519
			StringBuffer buffer = new StringBuffer("	- source folders: "); //$NON-NLS-1$
520
			int length = sourceFolders.length;
521
			for (int i=0; i<length; i++) {
522
				if (i==0) {
523
					buffer.append('[');
524
				} else {
525
					buffer.append(',');
526
				}
527
				buffer.append(sourceFolders[i].getElementName());
528
			}
529
			buffer.append("]\n	- waitForIndexes: "); //$NON-NLS-1$
530
			buffer.append(waitForIndexes);
531
			Util.verbose(buffer.toString());
532
		}
533
534
		IndexManager indexManager = JavaModelManager.getJavaModelManager().getIndexManager();
535
		final TypeDeclarationPattern pattern = new SecondaryTypeDeclarationPattern();
536
537
		// Get working copy path(s). Store in a single string in case of only one to optimize comparison in requestor
538
		final HashSet workingCopyPaths = new HashSet();
539
		String workingCopyPath = null;
540
		ICompilationUnit[] copies = getWorkingCopies();
541
		final int copiesLength = copies == null ? 0 : copies.length;
542
		if (copies != null) {
543
			if (copiesLength == 1) {
544
				workingCopyPath = copies[0].getPath().toString();
545
			} else {
546
				for (int i = 0; i < copiesLength; i++) {
547
					ICompilationUnit workingCopy = copies[i];
548
					workingCopyPaths.add(workingCopy.getPath().toString());
549
				}
550
			}
551
		}
552
		final String singleWkcpPath = workingCopyPath;
553
554
		// Index requestor
555
		IndexQueryRequestor searchRequestor = new IndexQueryRequestor(){
556
			public boolean acceptIndexMatch(String documentPath, SearchPattern indexRecord, SearchParticipant participant, AccessRuleSet access) {
557
				// Filter unexpected types
558
				TypeDeclarationPattern record = (TypeDeclarationPattern)indexRecord;
559
				if (!record.secondary) {
560
					return true; // filter maint types
561
				}
562
				if (record.enclosingTypeNames == IIndexConstants.ONE_ZERO_CHAR) {
563
					return true; // filter out local and anonymous classes
564
				}
565
				switch (copiesLength) {
566
					case 0:
567
						break;
568
					case 1:
569
						if (singleWkcpPath.equals(documentPath)) {
570
							return true; // fliter out *the* working copy
571
						}
572
						break;
573
					default:
574
						if (workingCopyPaths.contains(documentPath)) {
575
							return true; // filter out working copies
576
						}
577
						break;
578
				}
579
580
				// Accept document path
581
				AccessRestriction accessRestriction = null;
582
				if (access != null) {
583
					// Compute document relative path
584
					int pkgLength = (record.pkg==null || record.pkg.length==0) ? 0 : record.pkg.length+1;
585
					int nameLength = record.simpleName==null ? 0 : record.simpleName.length;
586
					char[] path = new char[pkgLength+nameLength];
587
					int pos = 0;
588
					if (pkgLength > 0) {
589
						System.arraycopy(record.pkg, 0, path, pos, pkgLength-1);
590
						CharOperation.replace(path, '.', '/');
591
						path[pkgLength-1] = '/';
592
						pos += pkgLength;
593
					}
594
					if (nameLength > 0) {
595
						System.arraycopy(record.simpleName, 0, path, pos, nameLength);
596
						pos += nameLength;
597
					}
598
					// Update access restriction if path is not empty
599
					if (pos > 0) {
600
						accessRestriction = access.getViolatedRestriction(path);
601
					}
602
				}
603
				nameRequestor.acceptType(record.modifiers, record.pkg, record.simpleName, record.enclosingTypeNames, documentPath, accessRestriction);
604
				return true;
605
			}
606
		};
607
608
		// add type names from indexes
609
		if (progressMonitor != null) {
610
			progressMonitor.beginTask(Messages.engine_searching, 100); 
611
		}
612
		try {
613
			indexManager.performConcurrentJob(
614
				new PatternSearchJob(
615
					pattern, 
616
					getDefaultSearchParticipant(), // Java search only
617
					createJavaSearchScope(sourceFolders), 
618
					searchRequestor),
619
				waitForIndexes
620
					? IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH
621
					: IJavaSearchConstants.FORCE_IMMEDIATE_SEARCH,
622
				progressMonitor == null ? null : new SubProgressMonitor(progressMonitor, 100));
623
		}
624
		catch (OperationCanceledException oce) {
625
			// do nothing
626
		}
627
	}
628
629
	/**
507
	 * Searches for all top-level types and member types in the given scope.
630
	 * Searches for all top-level types and member types in the given scope.
508
	 * The search can be selecting specific types (given a package or a type name
631
	 * The search can be selecting specific types (given a package or a type name
509
	 * prefix and match modes). 
632
	 * prefix and match modes). 
Lines 513-520 Link Here
513
	 */
636
	 */
514
	public void searchAllTypeNames(
637
	public void searchAllTypeNames(
515
		final char[] packageName, 
638
		final char[] packageName, 
639
		final int packageMatchRule, 
516
		final char[] typeName,
640
		final char[] typeName,
517
		final int matchRule, 
641
		final int typeMatchRule, 
518
		int searchFor, 
642
		int searchFor, 
519
		IJavaSearchScope scope, 
643
		IJavaSearchScope scope, 
520
		final IRestrictedAccessTypeRequestor nameRequestor,
644
		final IRestrictedAccessTypeRequestor nameRequestor,
Lines 524-531 Link Here
524
		if (VERBOSE) {
648
		if (VERBOSE) {
525
			Util.verbose("BasicSearchEngine.searchAllTypeNames(char[], char[], int, int, IJavaSearchScope, IRestrictedAccessTypeRequestor, int, IProgressMonitor)"); //$NON-NLS-1$
649
			Util.verbose("BasicSearchEngine.searchAllTypeNames(char[], char[], int, int, IJavaSearchScope, IRestrictedAccessTypeRequestor, int, IProgressMonitor)"); //$NON-NLS-1$
526
			Util.verbose("	- package name: "+(packageName==null?"null":new String(packageName))); //$NON-NLS-1$ //$NON-NLS-2$
650
			Util.verbose("	- package name: "+(packageName==null?"null":new String(packageName))); //$NON-NLS-1$ //$NON-NLS-2$
651
			Util.verbose("	- match rule: "+getMatchRuleString(packageMatchRule)); //$NON-NLS-1$
527
			Util.verbose("	- type name: "+(typeName==null?"null":new String(typeName))); //$NON-NLS-1$ //$NON-NLS-2$
652
			Util.verbose("	- type name: "+(typeName==null?"null":new String(typeName))); //$NON-NLS-1$ //$NON-NLS-2$
528
			Util.verbose("	- match rule: "+getMatchRuleString(matchRule)); //$NON-NLS-1$
653
			Util.verbose("	- match rule: "+getMatchRuleString(typeMatchRule)); //$NON-NLS-1$
529
			Util.verbose("	- search for: "+searchFor); //$NON-NLS-1$
654
			Util.verbose("	- search for: "+searchFor); //$NON-NLS-1$
530
			Util.verbose("	- scope: "+scope); //$NON-NLS-1$
655
			Util.verbose("	- scope: "+scope); //$NON-NLS-1$
531
		}
656
		}
Lines 533-538 Link Here
533
		// Return on invalid combination of package and type names
658
		// Return on invalid combination of package and type names
534
		if (packageName == null || packageName.length == 0) {
659
		if (packageName == null || packageName.length == 0) {
535
			if (typeName != null && typeName.length == 0) {
660
			if (typeName != null && typeName.length == 0) {
661
				// TODO (frederic) Throw a JME instead?
536
				if (VERBOSE) {
662
				if (VERBOSE) {
537
					Util.verbose("	=> return no result due to invalid empty values for package and type names!"); //$NON-NLS-1$
663
					Util.verbose("	=> return no result due to invalid empty values for package and type names!"); //$NON-NLS-1$
538
				}
664
				}
Lines 540-545 Link Here
540
			}
666
			}
541
		}
667
		}
542
668
669
		// Create pattern
543
		IndexManager indexManager = JavaModelManager.getJavaModelManager().getIndexManager();
670
		IndexManager indexManager = JavaModelManager.getJavaModelManager().getIndexManager();
544
		final char typeSuffix;
671
		final char typeSuffix;
545
		switch(searchFor){
672
		switch(searchFor){
Lines 565-576 Link Here
565
				typeSuffix = IIndexConstants.TYPE_SUFFIX;
692
				typeSuffix = IIndexConstants.TYPE_SUFFIX;
566
				break;
693
				break;
567
		}
694
		}
568
		final TypeDeclarationPattern pattern = new TypeDeclarationPattern(
695
		final TypeDeclarationPattern pattern = packageMatchRule == SearchPattern.R_EXACT_MATCH
569
			packageName,
696
			? new TypeDeclarationPattern(
570
			null, // do find member types
697
				packageName,
571
			typeName,
698
				null,
572
			typeSuffix,
699
				typeName,
573
			matchRule);
700
				typeSuffix,
701
				typeMatchRule)
702
			: new QualifiedTypeDeclarationPattern(
703
				packageName,
704
				packageMatchRule,
705
				typeName,
706
				typeSuffix,
707
				typeMatchRule);
574
708
575
		// Get working copy path(s). Store in a single string in case of only one to optimize comparison in requestor
709
		// Get working copy path(s). Store in a single string in case of only one to optimize comparison in requestor
576
		final HashSet workingCopyPaths = new HashSet();
710
		final HashSet workingCopyPaths = new HashSet();
Lines 687-693 Link Here
687
							} else /*if (type.isInterface())*/ {
821
							} else /*if (type.isInterface())*/ {
688
								kind = TypeDeclaration.INTERFACE_DECL;
822
								kind = TypeDeclaration.INTERFACE_DECL;
689
							}
823
							}
690
							if (match(typeSuffix, packageName, typeName, matchRule, kind, packageDeclaration, simpleName)) {
824
							if (match(typeSuffix, packageName, typeName, typeMatchRule, kind, packageDeclaration, simpleName)) {
691
								nameRequestor.acceptType(type.getFlags(), packageDeclaration, simpleName, enclosingTypeNames, path, null);
825
								nameRequestor.acceptType(type.getFlags(), packageDeclaration, simpleName, enclosingTypeNames, path, null);
692
							}
826
							}
693
						}
827
						}
Lines 703-715 Link Here
703
									return false; // no local/anonymous type
837
									return false; // no local/anonymous type
704
								}
838
								}
705
								public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope compilationUnitScope) {
839
								public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope compilationUnitScope) {
706
									if (match(typeSuffix, packageName, typeName, matchRule, TypeDeclaration.kind(typeDeclaration.modifiers), packageDeclaration, typeDeclaration.name)) {
840
									if (match(typeSuffix, packageName, typeName, typeMatchRule, TypeDeclaration.kind(typeDeclaration.modifiers), packageDeclaration, typeDeclaration.name)) {
707
										nameRequestor.acceptType(typeDeclaration.modifiers, packageDeclaration, typeDeclaration.name, CharOperation.NO_CHAR_CHAR, path, null);
841
										nameRequestor.acceptType(typeDeclaration.modifiers, packageDeclaration, typeDeclaration.name, CharOperation.NO_CHAR_CHAR, path, null);
708
									}
842
									}
709
									return true;
843
									return true;
710
								}
844
								}
711
								public boolean visit(TypeDeclaration memberTypeDeclaration, ClassScope classScope) {
845
								public boolean visit(TypeDeclaration memberTypeDeclaration, ClassScope classScope) {
712
									if (match(typeSuffix, packageName, typeName, matchRule, TypeDeclaration.kind(memberTypeDeclaration.modifiers), packageDeclaration, memberTypeDeclaration.name)) {
846
									if (match(typeSuffix, packageName, typeName, typeMatchRule, TypeDeclaration.kind(memberTypeDeclaration.modifiers), packageDeclaration, memberTypeDeclaration.name)) {
713
										// compute encloising type names
847
										// compute encloising type names
714
										TypeDeclaration enclosing = memberTypeDeclaration.enclosingType;
848
										TypeDeclaration enclosing = memberTypeDeclaration.enclosingType;
715
										char[][] enclosingTypeNames = CharOperation.NO_CHAR_CHAR;
849
										char[][] enclosingTypeNames = CharOperation.NO_CHAR_CHAR;
Lines 740-869 Link Here
740
	}
874
	}
741
875
742
	/**
876
	/**
743
	 * Searches for all top-level types and member types in the given scope.
744
	 * The search can be selecting specific types (given a package or a type name
745
	 * prefix and match modes). 
746
	 * 
747
	 */
748
	public void searchAllSecondaryTypeNames(
749
			IPackageFragmentRoot[] sourceFolders,
750
			final IRestrictedAccessTypeRequestor nameRequestor,
751
			boolean waitForIndexes,
752
			IProgressMonitor progressMonitor)  throws JavaModelException {
753
754
		if (VERBOSE) {
755
			Util.verbose("BasicSearchEngine.searchAllSecondaryTypeNames(IPackageFragmentRoot[], IRestrictedAccessTypeRequestor, boolean, IProgressMonitor)"); //$NON-NLS-1$
756
			StringBuffer buffer = new StringBuffer("	- source folders: "); //$NON-NLS-1$
757
			int length = sourceFolders.length;
758
			for (int i=0; i<length; i++) {
759
				if (i==0) {
760
					buffer.append('[');
761
				} else {
762
					buffer.append(',');
763
				}
764
				buffer.append(sourceFolders[i].getElementName());
765
			}
766
			buffer.append("]\n	- waitForIndexes: "); //$NON-NLS-1$
767
			buffer.append(waitForIndexes);
768
			Util.verbose(buffer.toString());
769
		}
770
771
		IndexManager indexManager = JavaModelManager.getJavaModelManager().getIndexManager();
772
		final TypeDeclarationPattern pattern = new SecondaryTypeDeclarationPattern();
773
774
		// Get working copy path(s). Store in a single string in case of only one to optimize comparison in requestor
775
		final HashSet workingCopyPaths = new HashSet();
776
		String workingCopyPath = null;
777
		ICompilationUnit[] copies = getWorkingCopies();
778
		final int copiesLength = copies == null ? 0 : copies.length;
779
		if (copies != null) {
780
			if (copiesLength == 1) {
781
				workingCopyPath = copies[0].getPath().toString();
782
			} else {
783
				for (int i = 0; i < copiesLength; i++) {
784
					ICompilationUnit workingCopy = copies[i];
785
					workingCopyPaths.add(workingCopy.getPath().toString());
786
				}
787
			}
788
		}
789
		final String singleWkcpPath = workingCopyPath;
790
791
		// Index requestor
792
		IndexQueryRequestor searchRequestor = new IndexQueryRequestor(){
793
			public boolean acceptIndexMatch(String documentPath, SearchPattern indexRecord, SearchParticipant participant, AccessRuleSet access) {
794
				// Filter unexpected types
795
				TypeDeclarationPattern record = (TypeDeclarationPattern)indexRecord;
796
				if (!record.secondary) {
797
					return true; // filter maint types
798
				}
799
				if (record.enclosingTypeNames == IIndexConstants.ONE_ZERO_CHAR) {
800
					return true; // filter out local and anonymous classes
801
				}
802
				switch (copiesLength) {
803
					case 0:
804
						break;
805
					case 1:
806
						if (singleWkcpPath.equals(documentPath)) {
807
							return true; // fliter out *the* working copy
808
						}
809
						break;
810
					default:
811
						if (workingCopyPaths.contains(documentPath)) {
812
							return true; // filter out working copies
813
						}
814
						break;
815
				}
816
817
				// Accept document path
818
				AccessRestriction accessRestriction = null;
819
				if (access != null) {
820
					// Compute document relative path
821
					int pkgLength = (record.pkg==null || record.pkg.length==0) ? 0 : record.pkg.length+1;
822
					int nameLength = record.simpleName==null ? 0 : record.simpleName.length;
823
					char[] path = new char[pkgLength+nameLength];
824
					int pos = 0;
825
					if (pkgLength > 0) {
826
						System.arraycopy(record.pkg, 0, path, pos, pkgLength-1);
827
						CharOperation.replace(path, '.', '/');
828
						path[pkgLength-1] = '/';
829
						pos += pkgLength;
830
					}
831
					if (nameLength > 0) {
832
						System.arraycopy(record.simpleName, 0, path, pos, nameLength);
833
						pos += nameLength;
834
					}
835
					// Update access restriction if path is not empty
836
					if (pos > 0) {
837
						accessRestriction = access.getViolatedRestriction(path);
838
					}
839
				}
840
				nameRequestor.acceptType(record.modifiers, record.pkg, record.simpleName, record.enclosingTypeNames, documentPath, accessRestriction);
841
				return true;
842
			}
843
		};
844
845
		// add type names from indexes
846
		if (progressMonitor != null) {
847
			progressMonitor.beginTask(Messages.engine_searching, 100); 
848
		}
849
		try {
850
			indexManager.performConcurrentJob(
851
				new PatternSearchJob(
852
					pattern, 
853
					getDefaultSearchParticipant(), // Java search only
854
					createJavaSearchScope(sourceFolders), 
855
					searchRequestor),
856
				waitForIndexes
857
					? IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH
858
					: IJavaSearchConstants.FORCE_IMMEDIATE_SEARCH,
859
				progressMonitor == null ? null : new SubProgressMonitor(progressMonitor, 100));
860
		}
861
		catch (OperationCanceledException oce) {
862
			// do nothing
863
		}
864
	}
865
866
	/**
867
	 * Searches for all top-level types and member types in the given scope using  a case sensitive exact match
877
	 * Searches for all top-level types and member types in the given scope using  a case sensitive exact match
868
	 * with the given qualified names and type names.
878
	 * with the given qualified names and type names.
869
	 * 
879
	 * 
Lines 976-982 Link Here
976
						accessRestriction = access.getViolatedRestriction(path);
986
						accessRestriction = access.getViolatedRestriction(path);
977
					}
987
					}
978
				}
988
				}
979
				nameRequestor.acceptType(record.modifiers, record.getPackageName(), record.simpleName, record.getEnclosingTypeNames(), documentPath, accessRestriction);
989
				nameRequestor.acceptType(record.modifiers, record.pkg, record.simpleName, record.enclosingTypeNames, documentPath, accessRestriction);
980
				return true;
990
				return true;
981
			}
991
			}
982
		};
992
		};
(-)search/org/eclipse/jdt/internal/core/search/TypeNameRequestorWrapper.java (-1 / +2 lines)
Lines 17-24 Link Here
17
 * Wrapper used to link {@link IRestrictedAccessTypeRequestor} with {@link TypeNameRequestor}.
17
 * Wrapper used to link {@link IRestrictedAccessTypeRequestor} with {@link TypeNameRequestor}.
18
 * This wrapper specifically allows usage of internal method {@link BasicSearchEngine#searchAllTypeNames(
18
 * This wrapper specifically allows usage of internal method {@link BasicSearchEngine#searchAllTypeNames(
19
 * 	char[] packageName, 
19
 * 	char[] packageName, 
20
 * 	int packageMatchRule, 
20
 * 	char[] typeName,
21
 * 	char[] typeName,
21
 * 	int matchRule, 
22
 * 	int typeMatchRule, 
22
 * 	int searchFor, 
23
 * 	int searchFor, 
23
 * 	org.eclipse.jdt.core.search.IJavaSearchScope scope, 
24
 * 	org.eclipse.jdt.core.search.IJavaSearchScope scope, 
24
 * 	IRestrictedAccessTypeRequestor nameRequestor,
25
 * 	IRestrictedAccessTypeRequestor nameRequestor,
(-)model/org/eclipse/jdt/internal/core/SearchableEnvironment.java (+1 lines)
Lines 264-269 Link Here
264
				if (camelCaseMatch) matchRule |= SearchPattern.R_CAMELCASE_MATCH;
264
				if (camelCaseMatch) matchRule |= SearchPattern.R_CAMELCASE_MATCH;
265
				new BasicSearchEngine(this.workingCopies).searchAllTypeNames(
265
				new BasicSearchEngine(this.workingCopies).searchAllTypeNames(
266
					qualification,
266
					qualification,
267
					SearchPattern.R_EXACT_MATCH,
267
					simpleName,
268
					simpleName,
268
					matchRule, // not case sensitive
269
					matchRule, // not case sensitive
269
					IJavaSearchConstants.TYPE,
270
					IJavaSearchConstants.TYPE,
(-)search/org/eclipse/jdt/internal/core/search/matching/QualifiedTypeDeclarationPattern.java (-30 / +33 lines)
Lines 17-23 Link Here
17
public class QualifiedTypeDeclarationPattern extends TypeDeclarationPattern implements IIndexConstants {
17
public class QualifiedTypeDeclarationPattern extends TypeDeclarationPattern implements IIndexConstants {
18
18
19
public char[] qualification;
19
public char[] qualification;
20
public int packageIndex;
20
PackageDeclarationPattern packagePattern;
21
public int packageIndex = -1;
21
22
22
public QualifiedTypeDeclarationPattern(char[] qualification, char[] simpleName, char typeSuffix, int matchRule) {
23
public QualifiedTypeDeclarationPattern(char[] qualification, char[] simpleName, char typeSuffix, int matchRule) {
23
	this(matchRule);
24
	this(matchRule);
Lines 28-33 Link Here
28
29
29
	((InternalSearchPattern)this).mustResolve = this.qualification != null || typeSuffix != TYPE_SUFFIX;
30
	((InternalSearchPattern)this).mustResolve = this.qualification != null || typeSuffix != TYPE_SUFFIX;
30
}
31
}
32
public QualifiedTypeDeclarationPattern(char[] qualification, int qualificationMatchRule, char[] simpleName, char typeSuffix, int matchRule) {
33
	this(qualification, simpleName, typeSuffix, matchRule);
34
	this.packagePattern = new PackageDeclarationPattern(qualification, qualificationMatchRule);
35
}
31
QualifiedTypeDeclarationPattern(int matchRule) {
36
QualifiedTypeDeclarationPattern(int matchRule) {
32
	super(matchRule);
37
	super(matchRule);
33
}
38
}
Lines 35-56 Link Here
35
	int slash = CharOperation.indexOf(SEPARATOR, key, 0);
40
	int slash = CharOperation.indexOf(SEPARATOR, key, 0);
36
	this.simpleName = CharOperation.subarray(key, 0, slash);
41
	this.simpleName = CharOperation.subarray(key, 0, slash);
37
42
38
	int start = slash + 1;
43
	int start = ++slash;
39
	slash = CharOperation.indexOf(SEPARATOR, key, start);
44
	if (key[start] == SEPARATOR) {
40
	int secondSlash = CharOperation.indexOf(SEPARATOR, key, slash + 1);
45
		this.pkg = CharOperation.NO_CHAR;
41
	this.packageIndex = -1; // used to compute package vs. enclosingTypeNames in MultiTypeDeclarationPattern
42
	if (start + 1 == secondSlash) {
43
		this.qualification = CharOperation.NO_CHAR; // no package name or enclosingTypeNames
44
	} else if (slash + 1 == secondSlash) {
45
		this.qualification = CharOperation.subarray(key, start, slash); // only a package name
46
	} else if (slash == start) {
47
		this.qualification = CharOperation.subarray(key, slash + 1, secondSlash); // no package name
48
		this.packageIndex = 0;
49
	} else {
46
	} else {
50
		this.qualification = CharOperation.subarray(key, start, secondSlash);
47
		slash = CharOperation.indexOf(SEPARATOR, key, start);
51
		this.packageIndex = slash - start;
48
		this.pkg = internedPackageNames.add(CharOperation.subarray(key, start, slash));
52
		this.qualification[this.packageIndex] = '.';
53
	}
49
	}
50
	this.qualification = this.pkg;
54
51
55
	// Continue key read by the end to decode modifiers
52
	// Continue key read by the end to decode modifiers
56
	int last = key.length-1;
53
	int last = key.length-1;
Lines 60-83 Link Here
60
	}
57
	}
61
	this.modifiers = key[last-1] + (key[last]<<16);
58
	this.modifiers = key[last-1] + (key[last]<<16);
62
	decodeModifiers();
59
	decodeModifiers();
60
61
	// Retrieve enclosing type names
62
	start = slash + 1;
63
	last -= 2; // position of ending slash
64
	if (start == last) {
65
		this.enclosingTypeNames = CharOperation.NO_CHAR_CHAR;
66
	} else {
67
		int length = this.qualification.length;
68
		int size = last - start;
69
		System.arraycopy(this.qualification, 0, this.qualification = new char[length+1+size], 0, length);
70
		this.qualification[length] = '.';
71
		if (last == (start+1) && key[start] == ZERO_CHAR) {
72
			this.enclosingTypeNames = ONE_ZERO_CHAR;
73
			this.qualification[length+1] = ZERO_CHAR;
74
		} else {
75
			this.enclosingTypeNames = CharOperation.splitOn('.', key, start, last);
76
			System.arraycopy(key, start, this.qualification, length+1, size);
77
		}
78
	}
63
}
79
}
64
public SearchPattern getBlankPattern() {
80
public SearchPattern getBlankPattern() {
65
	return new QualifiedTypeDeclarationPattern(R_EXACT_MATCH | R_CASE_SENSITIVE);
81
	return new QualifiedTypeDeclarationPattern(R_EXACT_MATCH | R_CASE_SENSITIVE);
66
}
82
}
67
public char[] getPackageName() {
68
	if (this.packageIndex == -1)
69
		return this.qualification;
70
	return internedPackageNames.add(CharOperation.subarray(this.qualification, 0, this.packageIndex));
71
}
72
public char[][] getEnclosingTypeNames() {
73
	if (this.packageIndex == -1)
74
		return CharOperation.NO_CHAR_CHAR;
75
	if (this.packageIndex == 0)
76
		return CharOperation.splitOn('.', this.qualification);
77
78
	char[] names = CharOperation.subarray(this.qualification, this.packageIndex + 1, this.qualification.length);
79
	return CharOperation.splitOn('.', names);
80
}
81
public boolean matchesDecodedKey(SearchPattern decodedPattern) {
83
public boolean matchesDecodedKey(SearchPattern decodedPattern) {
82
	QualifiedTypeDeclarationPattern pattern = (QualifiedTypeDeclarationPattern) decodedPattern;
84
	QualifiedTypeDeclarationPattern pattern = (QualifiedTypeDeclarationPattern) decodedPattern;
83
	switch(this.typeSuffix) {
85
	switch(this.typeSuffix) {
Lines 134-140 Link Here
134
			break;
136
			break;
135
	}
137
	}
136
138
137
	return matchesName(this.simpleName, pattern.simpleName) && matchesName(this.qualification, pattern.qualification);
139
	return matchesName(this.simpleName, pattern.simpleName) &&
140
		(this.qualification == null || this.packagePattern == null || this.packagePattern.matchesName(this.qualification, pattern.qualification));
138
}
141
}
139
protected StringBuffer print(StringBuffer output) {
142
protected StringBuffer print(StringBuffer output) {
140
	switch (this.typeSuffix){
143
	switch (this.typeSuffix){
(-)src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java (+100 lines)
Lines 2859-2864 Link Here
2859
}
2859
}
2860
2860
2861
/**
2861
/**
2862
 * Bug 92264: [search] all types names should support patterns for package/enclosing type name
2863
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=92264"
2864
 */
2865
public void testBug92264a() throws CoreException {
2866
	TypeNameRequestor requestor =  new SearchTests.SearchTypeNameRequestor();
2867
	new SearchEngine().searchAllTypeNames(
2868
		"*.lang".toCharArray(),
2869
		SearchPattern.R_PATTERN_MATCH, // case insensitive
2870
		IIndexConstants.ONE_STAR,
2871
		SearchPattern.R_PATTERN_MATCH, // case insensitive
2872
		TYPE,
2873
		getJavaSearchScopeBugs(),
2874
		requestor,
2875
		IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH,
2876
		null
2877
	);
2878
	assertSearchResults(
2879
		"Unexpected all type names",
2880
		"java.lang.CharSequence\n" + 
2881
		"java.lang.Class\n" + 
2882
		"java.lang.CloneNotSupportedException\n" + 
2883
		"java.lang.Comparable\n" + 
2884
		"java.lang.Enum\n" + 
2885
		"java.lang.Error\n" + 
2886
		"java.lang.Exception\n" + 
2887
		"java.lang.IllegalMonitorStateException\n" + 
2888
		"java.lang.InterruptedException\n" + 
2889
		"java.lang.Object\n" + 
2890
		"java.lang.RuntimeException\n" + 
2891
		"java.lang.String\n" + 
2892
		"java.lang.Throwable",
2893
		requestor);
2894
}
2895
public void testBug92264b() throws CoreException {
2896
	TypeNameRequestor requestor =  new SearchTests.SearchTypeNameRequestor();
2897
	new SearchEngine().searchAllTypeNames(
2898
		"*.lang*".toCharArray(),
2899
		SearchPattern.R_PATTERN_MATCH, // case insensitive
2900
		"*tion".toCharArray(),
2901
		SearchPattern.R_PATTERN_MATCH, // case insensitive
2902
		TYPE,
2903
		getJavaSearchScopeBugs(),
2904
		requestor,
2905
		IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH,
2906
		null
2907
	);
2908
	assertSearchResults(
2909
		"Unexpected all type names",
2910
		"java.lang.CloneNotSupportedException\n" + 
2911
		"java.lang.Exception\n" + 
2912
		"java.lang.IllegalMonitorStateException\n" + 
2913
		"java.lang.InterruptedException\n" + 
2914
		"java.lang.RuntimeException\n" + 
2915
		"java.lang.annotation.Annotation",
2916
		requestor);
2917
}
2918
public void testBug92264c() throws CoreException {
2919
	TypeNameRequestor requestor =  new SearchTests.SearchTypeNameRequestor();
2920
	new SearchEngine().searchAllTypeNames(
2921
		"*.test*".toCharArray(),
2922
		SearchPattern.R_PATTERN_MATCH, // case insensitive
2923
		IIndexConstants.ONE_STAR,
2924
		SearchPattern.R_PATTERN_MATCH, // case insensitive
2925
		TYPE,
2926
		getJavaSearchScopeBugs(),
2927
		requestor,
2928
		IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH,
2929
		null
2930
	);
2931
	assertSearchResults(
2932
		"Unexpected all type names",
2933
		"Test$Inner\n" + 
2934
		"b124645.test.A_124645\n" + 
2935
		"b124645.test.X_124645\n" + 
2936
		"b127628.Test127628$Member127628\n" + 
2937
		"b95794.Test$Color\n" + 
2938
		"pack.age.Test$Member",
2939
		requestor);
2940
}
2941
public void testBug92264d() throws CoreException {
2942
	TypeNameRequestor requestor =  new SearchTests.SearchTypeNameRequestor();
2943
	new SearchEngine().searchAllTypeNames(
2944
		"b12*".toCharArray(),
2945
		SearchPattern.R_PATTERN_MATCH, // case insensitive
2946
		new char[] { 'X' },
2947
		SearchPattern.R_PREFIX_MATCH, // case insensitive
2948
		TYPE,
2949
		getJavaSearchScopeBugs(),
2950
		requestor,
2951
		IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH,
2952
		null
2953
	);
2954
	assertSearchResults(
2955
		"Unexpected all type names",
2956
		"b124645.test.X_124645\n" + 
2957
		"b124645.xy.X_124645",
2958
		requestor);
2959
}
2960
2961
/**
2862
 * Bug 92944: [1.5][search] SearchEngine#searchAllTypeNames doesn't honor enum or annotation element kind
2962
 * Bug 92944: [1.5][search] SearchEngine#searchAllTypeNames doesn't honor enum or annotation element kind
2863
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=92944"
2963
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=92944"
2864
 */
2964
 */

Return to bug 92264