Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 24130 Details for
Bug 101777
[search] selecting class with a main type ignores the default package
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
[patch]
Improved JavaSearchScope
patch101777_org.eclipse.jdt.core.txt (text/plain), 17.81 KB, created by
Jerome Lanneluc
on 2005-06-29 10:11:42 EDT
(
hide
)
Description:
Improved JavaSearchScope
Filename:
MIME Type:
Creator:
Jerome Lanneluc
Created:
2005-06-29 10:11:42 EDT
Size:
17.81 KB
patch
obsolete
>Index: search/org/eclipse/jdt/internal/core/search/JavaSearchScope.java >=================================================================== >RCS file: /home/eclipse/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchScope.java,v >retrieving revision 1.44 >diff -u -r1.44 JavaSearchScope.java >--- search/org/eclipse/jdt/internal/core/search/JavaSearchScope.java 23 Jun 2005 16:15:24 -0000 1.44 >+++ search/org/eclipse/jdt/internal/core/search/JavaSearchScope.java 29 Jun 2005 14:03:33 -0000 >@@ -24,7 +24,6 @@ > import org.eclipse.jdt.core.IJavaModel; > import org.eclipse.jdt.core.IJavaProject; > import org.eclipse.jdt.core.IMember; >-import org.eclipse.jdt.core.IOpenable; > import org.eclipse.jdt.core.IPackageFragmentRoot; > import org.eclipse.jdt.core.JavaModelException; > import org.eclipse.jdt.internal.compiler.env.AccessRuleSet; >@@ -42,12 +41,12 @@ > private ArrayList elements; > > /* The paths of the resources in this search scope >- (or the classpath entries' paths >- if the resources are projects) */ >- private String[] paths; >- private boolean[] pathWithSubFolders; >+ (or the classpath entries' paths if the resources are projects) >+ */ >+ private String[] containerPaths; // path to the container (e.g. /P/src, /P/lib.jar, c:\temp\mylib.jar) >+ private String[] relativePaths; // path relative to the container (e.g. x/y/Z.class, x/y, (empty)) >+ private boolean[] isPkgPath; // in the case of packages, matches must be direct children of the folder > protected AccessRuleSet[] pathRestrictions; >- private String[] containerPaths; > private int pathsCount; > private int threshold; > >@@ -134,7 +133,7 @@ > IPath path = entry.getPath(); > if (pathToAdd == null || pathToAdd.equals(path)) { > String pathToString = path.getDevice() == null ? path.toString() : path.toOSString(); >- add("", pathToString, true, access); //$NON-NLS-1$ >+ add("", pathToString, false/*not a package*/, access); //$NON-NLS-1$ > addEnclosingProjectOrJar(path); > } > } >@@ -147,7 +146,7 @@ > IPath path = entry.getPath(); > if (pathToAdd == null || pathToAdd.equals(path)) { > String pathToString = path.getDevice() == null ? path.toString() : path.toOSString(); >- add("", pathToString, true, access); //$NON-NLS-1$ >+ add("", pathToString, false/*not a package*/, access); //$NON-NLS-1$ > addEnclosingProjectOrJar(path); > } > } >@@ -166,7 +165,7 @@ > if ((includeMask & SOURCES) != 0) { > IPath path = entry.getPath(); > if (pathToAdd == null || pathToAdd.equals(path)) { >- add(Util.relativePath(path,1/*remove project segment*/), projectPathString, true, access); >+ add(Util.relativePath(path,1/*remove project segment*/), projectPathString, false/*not a package*/, access); > } > } > break; >@@ -197,9 +196,9 @@ > IResource rootResource = root.getResource(); > if (rootResource != null && rootResource.isAccessible()) { > String relativePath = Util.relativePath(rootResource.getFullPath(), containerPath.segmentCount()); >- add(relativePath, containerPathToString, true, null); >+ add(relativePath, containerPathToString, false/*not a package*/, null); > } else { >- add("", containerPathToString, true, null); //$NON-NLS-1$ >+ add("", containerPathToString, false/*not a package*/, null); //$NON-NLS-1$ > } > break; > case IJavaElement.PACKAGE_FRAGMENT: >@@ -208,14 +207,14 @@ > String relativePath = Util.concatWith(((PackageFragment) element).names, '/'); > containerPath = root.getPath(); > containerPathToString = containerPath.getDevice() == null ? containerPath.toString() : containerPath.toOSString(); >- add(relativePath, containerPathToString, false, null); >+ add(relativePath, containerPathToString, true/*package*/, null); > } else { > IResource resource = element.getResource(); > if (resource != null && resource.isAccessible()) { > containerPath = root.getKind() == IPackageFragmentRoot.K_SOURCE ? root.getParent().getPath() : root.getPath(); > containerPathToString = containerPath.getDevice() == null ? containerPath.toString() : containerPath.toOSString(); > String relativePath = Util.relativePath(resource.getFullPath(), containerPath.segmentCount()); >- add(relativePath, containerPathToString, false, null); >+ add(relativePath, containerPathToString, true/*package*/, null); > } > } > break; >@@ -237,7 +236,7 @@ > relativePath = getPath(element, true/*relative path*/).toString(); > } > containerPathToString = containerPath.getDevice() == null ? containerPath.toString() : containerPath.toOSString(); >- add(relativePath, containerPathToString, true, null); >+ add(relativePath, containerPathToString, false/*not a package*/, null); > } > > if (containerPath != null) >@@ -248,95 +247,135 @@ > * Adds the given path to this search scope. Remember if subfolders need to be included > * and associated access restriction as well. > */ >-private void add(String relativePath, String containerPath, boolean withSubFolders, AccessRuleSet access) { >- int index = (containerPath.hashCode() & 0x7FFFFFFF) % this.paths.length; >- String currentPath, currentContainerPath; >- while ((currentPath = this.paths[index]) != null && (currentContainerPath = this.containerPaths[index]) != null) { >- if (currentPath.equals(relativePath) && currentContainerPath.equals(containerPath)) >+private void add(String relativePath, String containerPath, boolean isPackage, AccessRuleSet access) { >+ // normalize containerPath and relativePath >+ containerPath = normalize(containerPath); >+ relativePath = normalize(relativePath); >+ >+ int index = (containerPath.hashCode() & 0x7FFFFFFF) % this.containerPaths.length; >+ String currentRelativePath, currentContainerPath; >+ while ((currentRelativePath = this.relativePaths[index]) != null && (currentContainerPath = this.containerPaths[index]) != null) { >+ if (currentRelativePath.equals(relativePath) && currentContainerPath.equals(containerPath)) > return; >- index = (index + 1) % this.paths.length; >+ index = (index + 1) % this.relativePaths.length; > } >- this.paths[index] = relativePath; >+ this.relativePaths[index] = relativePath; > this.containerPaths[index] = containerPath; >- this.pathWithSubFolders[index] = withSubFolders; >+ this.isPkgPath[index] = isPackage; > if (this.pathRestrictions != null) > this.pathRestrictions[index] = access; > else if (access != null) { >- this.pathRestrictions = new AccessRuleSet[this.paths.length]; >+ this.pathRestrictions = new AccessRuleSet[this.relativePaths.length]; > this.pathRestrictions[index] = access; > } > > // assumes the threshold is never equal to the size of the table > if (++this.pathsCount > this.threshold) > rehash(); >- > } > >-/* (non-Javadoc) >+/* >+ * E.g. >+ * >+ * 1. /P/src/pkg/X.java >+ * 2. /P/src/pkg >+ * 3. /P/lib.jar|org/eclipse/jdt/core/IJavaElement.class >+ * 4. /home/mylib.jar|x/y/z/X.class >+ * 5. c:\temp\mylib.jar|x/y/Y.class >+ * > * @see IJavaSearchScope#encloses(String) > */ > public boolean encloses(String resourcePathString) { > int separatorIndex = resourcePathString.indexOf(JAR_FILE_ENTRY_SEPARATOR); > if (separatorIndex != -1) { >- return indexOf(resourcePathString.substring(separatorIndex+1), resourcePathString.substring(0, separatorIndex)) >= 0; >+ // internal or external jar (case 3, 4, or 5) >+ String jarPath = resourcePathString.substring(0, separatorIndex); >+ String relativePath = resourcePathString.substring(separatorIndex+1); >+ return indexOf(jarPath, relativePath) >= 0; > } >- return indexOf(resourcePathString, null) >= 0; >+ // resource in workspace (case 1 or 2) >+ return indexOf(resourcePathString) >= 0; > } > > /** > * Returns paths list index of given path or -1 if not found. >+ * NOTE: Use indexOf(String, String) for path inside jars >+ * >+ * @param fullPath the full path of the resource, e.g. >+ * 1. /P/src/pkg/X.java >+ * 2. /P/src/pkg > */ >-private int indexOf(String relativePath, String containerPath) { >- if (containerPath != null) { >- // if container path is known, use the hash to get faster comparison >- int index = (containerPath.hashCode()& 0x7FFFFFFF) % this.paths.length; >- String currentContainerPath; >- while ((currentContainerPath = this.containerPaths[index]) != null) { >- if (currentContainerPath.equals(containerPath)) { >- String scopePath = this.paths[index]; >- if (encloses(scopePath, relativePath, index)) >- return index; >- } >- index = (index + 1) % this.paths.length; >- } >- return -1; >- } >- >+private int indexOf(String fullPath) { >+ // cannot guess the index of the container path > // fallback to sequentially looking at all known paths >- for (int i = 0, length = this.paths.length; i < length; i++) { >- String scopePath = this.paths[i]; >- if (scopePath == null) continue; >- if (encloses(this.containerPaths[i] + '/' + scopePath, relativePath, i)) >+ for (int i = 0, length = this.relativePaths.length; i < length; i++) { >+ String currentRelativePath = this.relativePaths[i]; >+ if (currentRelativePath == null) continue; >+ String currentContainerPath = this.containerPaths[i]; >+ String currentFullPath = currentRelativePath.length() == 0 ? currentContainerPath : (currentContainerPath + '/' + currentRelativePath); >+ if (encloses(currentFullPath, fullPath, i)) > return i; > } > return -1; > } > >-private boolean encloses(String scopePath, String path, int index) { >- if (this.pathWithSubFolders[index]) { >- // TODO (frederic) apply similar change also if not looking at subfolders >- int pathLength = path.length(); >- int scopeLength = scopePath.length(); >- if (pathLength < scopeLength) { >- return false; >- } >- if (scopeLength == 0) { >- return true; >- } >- if (pathLength == scopeLength) { >- return path.equals(scopePath); >- } >- if (path.startsWith(scopePath)) { >- if (scopePath.charAt(scopeLength-1) == '/') scopeLength--; >- return path.charAt(scopeLength) == '/'; >+/** >+ * Returns paths list index of given path or -1 if not found. >+ * @param containerPath the path of the container, e.g. >+ * 1. /P/src >+ * 2. /P >+ * 3. /P/lib.jar >+ * 4. /home/mylib.jar >+ * 5. c:\temp\mylib.jar >+ * @param relativePath the forward slash path relatively to the container, e.g. >+ * 1. x/y/Z.class >+ * 2. x/y >+ * 3. X.java >+ * 4. (empty) >+ */ >+private int indexOf(String containerPath, String relativePath) { >+ // use the hash to get faster comparison >+ int index = (containerPath.hashCode()& 0x7FFFFFFF) % this.containerPaths.length; >+ String currentContainerPath; >+ while ((currentContainerPath = this.containerPaths[index]) != null) { >+ if (currentContainerPath.equals(containerPath)) { >+ String currentRelativePath = this.relativePaths[index]; >+ if (encloses(currentRelativePath, relativePath, index)) >+ return index; > } >+ index = (index + 1) % this.relativePaths.length; >+ } >+ return -1; >+} >+ >+/* >+ * Returns whether the enclosing path encloses the given path (or is equal to it) >+ */ >+private boolean encloses(String enclosingPath, String path, int index) { >+ // normalize given path as it can come from outside >+ path = normalize(path); >+ >+ int pathLength = path.length(); >+ int enclosingLength = enclosingPath.length(); >+ if (pathLength < enclosingLength) { >+ return false; >+ } >+ if (enclosingLength == 0) { >+ return true; >+ } >+ if (pathLength == enclosingLength) { >+ return path.equals(enclosingPath); >+ } >+ if (!this.isPkgPath[index]) { >+ return path.startsWith(enclosingPath) >+ && path.charAt(enclosingLength) == '/'; > } else { >- // if not looking at subfolders, this scope encloses the given path >- // if this path is a direct child of the scope's ressource >- // or if this path is the scope's resource (see bug 13919 Declaration for package not found if scope is not project) >- if (path.startsWith(scopePath) >- && ((scopePath.length() == path.lastIndexOf('/')) >- || (scopePath.length() == path.length()))) { >+ // if looking at a package, this scope encloses the given path >+ // if the given path is a direct child of the folder >+ // or if the given path path is the folder path (see bug 13919 Declaration for package not found if scope is not project) >+ if (path.startsWith(enclosingPath) >+ && ((enclosingPath.length() == path.lastIndexOf('/')) >+ || (enclosingPath.length() == path.length()))) { > return true; > } > } >@@ -361,12 +400,15 @@ > } > IPackageFragmentRoot root = (IPackageFragmentRoot) element.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT); > if (root != null && root.isArchive()) { >+ // external or internal jar > IPath rootPath = root.getPath(); > String rootPathToString = rootPath.getDevice() == null ? rootPath.toString() : rootPath.toOSString(); > IPath relativePath = getPath(element, true/*relative path*/); >- return indexOf(relativePath.toString(), rootPathToString) >= 0; >+ return indexOf(rootPathToString, relativePath.toString()) >= 0; > } >- return this.indexOf(getPath(element, false/*full path*/).toString(), null) >= 0; >+ // resource in workspace >+ String fullResourcePathString = getPath(element, false/*full path*/).toString(); >+ return indexOf(fullResourcePathString) >= 0; > } > > /* (non-Javadoc) >@@ -376,23 +418,24 @@ > return this.enclosingProjectsAndJars; > } > private IPath getPath(IJavaElement element, boolean relativeToRoot) { >- if (element instanceof IPackageFragmentRoot) { >- if (relativeToRoot) >+ switch (element.getElementType()) { >+ case IJavaElement.JAVA_MODEL: > return Path.EMPTY; >- return ((IPackageFragmentRoot)element).getPath(); >- } >- IJavaElement parent = element.getParent(); >- IPath parentPath = parent == null ? null : getPath(parent, relativeToRoot); >- IPath childPath; >- if (element instanceof PackageFragment) { >- String relativePath = Util.concatWith(((PackageFragment) element).names, '/'); >- childPath = new Path(relativePath); >- } else if (element instanceof IOpenable) { >- childPath = new Path(element.getElementName()); >- } else { >- return parentPath; >+ case IJavaElement.JAVA_PROJECT: >+ return element.getPath(); >+ case IJavaElement.PACKAGE_FRAGMENT_ROOT: >+ if (relativeToRoot) >+ return Path.EMPTY; >+ return element.getPath(); >+ case IJavaElement.PACKAGE_FRAGMENT: >+ String relativePath = Util.concatWith(((PackageFragment) element).names, '/'); >+ return getPath(element.getParent(), relativeToRoot).append(new Path(relativePath)); >+ case IJavaElement.COMPILATION_UNIT: >+ case IJavaElement.CLASS_FILE: >+ return getPath(element.getParent(), relativeToRoot).append(new Path(element.getElementName())); >+ default: >+ return getPath(element.getParent(), relativeToRoot); > } >- return parentPath == null ? childPath : parentPath.append(childPath); > } > > /** >@@ -402,7 +445,7 @@ > * Returns specific uninit access rule set when scope does not enclose the given path. > */ > public AccessRuleSet getAccessRuleSet(String relativePath, String containerPath) { >- int index = indexOf(relativePath, containerPath); >+ int index = indexOf(containerPath, relativePath); > if (index == -1) { > // this search scope does not enclose given path > return NOT_ENCLOSED; >@@ -418,13 +461,27 @@ > int extraRoom = (int) (size * 1.75f); > if (this.threshold == extraRoom) > extraRoom++; >- this.paths = new String[extraRoom]; >+ this.relativePaths = new String[extraRoom]; > this.containerPaths = new String[extraRoom]; >- this.pathWithSubFolders = new boolean[extraRoom]; >+ this.isPkgPath = new boolean[extraRoom]; > this.pathRestrictions = null; // null to optimize case where no access rules are used > > this.enclosingProjectsAndJars = new IPath[0]; > } >+ >+/* >+ * Removes trailing slashes from the given path >+ */ >+private String normalize(String path) { >+ int pathLength = path.length(); >+ int index = pathLength-1; >+ while (index >= 0 && path.charAt(index) == '/') >+ index--; >+ if (index != pathLength-1) >+ return path.substring(0, index + 1); >+ return path; >+} >+ > /* > * @see AbstractSearchScope#processDelta(IJavaElementDelta) > */ >@@ -453,13 +510,13 @@ > } > int toRemove = -1; > for (int i = 0; i < this.pathsCount; i++) { >- if (this.paths[i].equals(path)) { >+ if (this.relativePaths[i].equals(path)) { // TODO (jerome) this compares String and IPath ! > toRemove = i; > break; > } > } > if (toRemove != -1) { >- this.paths[toRemove] = null; >+ this.relativePaths[toRemove] = null; > rehash(); > } > } >@@ -471,13 +528,13 @@ > private void rehash() { > JavaSearchScope newScope = new JavaSearchScope(this.pathsCount * 2); // double the number of expected elements > String currentPath; >- for (int i = this.paths.length; --i >= 0;) >- if ((currentPath = this.paths[i]) != null) >- newScope.add(currentPath, this.containerPaths[i], this.pathWithSubFolders[i], this.pathRestrictions == null ? null : this.pathRestrictions[i]); >+ for (int i = this.relativePaths.length; --i >= 0;) >+ if ((currentPath = this.relativePaths[i]) != null) >+ newScope.add(currentPath, this.containerPaths[i], this.isPkgPath[i], this.pathRestrictions == null ? null : this.pathRestrictions[i]); > >- this.paths = newScope.paths; >+ this.relativePaths = newScope.relativePaths; > this.containerPaths = newScope.containerPaths; >- this.pathWithSubFolders = newScope.pathWithSubFolders; >+ this.isPkgPath = newScope.isPkgPath; > this.pathRestrictions = newScope.pathRestrictions; > this.threshold = newScope.threshold; > } >@@ -497,8 +554,8 @@ > result.append("[empty scope]"); //$NON-NLS-1$ > } else { > result.append("["); //$NON-NLS-1$ >- for (int i = 0; i < this.paths.length; i++) { >- String path = this.paths[i]; >+ for (int i = 0; i < this.relativePaths.length; i++) { >+ String path = this.relativePaths[i]; > if (path == null) continue; > result.append("\n\t"); //$NON-NLS-1$ > result.append(this.containerPaths[i]);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 101777
: 24130 |
24131