Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[cdt-patch] Outline Open Include patch

Folks,
  
  Here another CDT 1.2.x and CDT 2.0 patch corresponding to PR 51355.
This patch extends the search for an included file from the defined
include paths to the local project.  This is only done in the case
where searching the defined include paths provided no results.  This
allows a user to have both a properly configured environment (which
will return only the "valid" header files) and a mis-configured 
environment, favouring the properly configured environment.

  Additionally the local project search is improved to use a proxy
and then to match project entries only where they make sense.  For
example if you were looking for #include "a/b.h" and you had a 
path c/b.h then it would _not_ be reported since you explicitly
indicated the path.

For the ChangeLog:

- Extend the scope of the search for an include entry to the local
  project if no results are found in the defined paths.  
  Improve the performance by using an IResourceProxyVisitor

--- PATCH START ---
Index: src/org/eclipse/cdt/internal/ui/editor/OpenIncludeAction.java
===================================================================
RCS 
file: /home/tools/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/O
penIncludeAction.java,v
retrieving revision 1.7
diff -u -r1.7 OpenIncludeAction.java
--- src/org/eclipse/cdt/internal/ui/editor/OpenIncludeAction.java	28 
Aug 2003 19:47:01 -0000	1.7
+++ src/org/eclipse/cdt/internal/ui/editor/OpenIncludeAction.java	9 
Feb 2004 09:19:25 -0000
@@ -23,6 +23,8 @@
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceProxy;
+import org.eclipse.core.resources.IResourceProxyVisitor;
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IPath;
@@ -83,10 +85,15 @@
 					if (info != null) {
 						String[] includePaths = 
info.getIncludePaths();
 						findFile(includePaths, 
includeName, filesFound);
-					} else {
-						// Fall back and search the 
project
+					} 
+					
+					//If we didn't find anything, then 
the worst that we can do is to 
+					//search the local project.  Of 
course if we did find something in
+					//the include path, then we should 
stick to only showing that.					
+					if(filesFound.isEmpty()) {
 						findFile(proj, new Path
(includeName), filesFound);
 					}
+					
 				}
 			}
 			IPath fileToOpen;
@@ -125,17 +132,62 @@
 		}
 	}
 
-	private void findFile(IContainer parent, IPath name, ArrayList list) 
throws CoreException {
-		IResource found= parent.findMember(name);
-		if (found != null && found.getType() == IResource.FILE) {
-			list.add(found.getLocation());
+	private void findFile(IContainer parent, IPath name, final ArrayList 
list) throws CoreException {
+		final String lastSegment = name.lastSegment();
+		if(lastSegment == null) {
+			return;
 		}
-		IResource[] children= parent.members();
-		for (int i= 0; i < children.length; i++) {
-			if (children[i] instanceof IContainer) {
-				findFile((IContainer)children[i], name, 
list);
+
+		final IPath pathSegments = name.removeLastSegments(1);
+		
+		//We use the lastSegment as a fast key, but then make sure 
that we can match
+		//the rest of the segments (if they exist) so a path like:
+		//#include "subsystem/includefile.h" won't match 
with "a/b/c/includefile.h"
+		IResourceProxyVisitor visitor = new IResourceProxyVisitor() {
+			private boolean checkSegments(IPath sourceSegments, 
IPath targetSegments) {
+				if(sourceSegments == null) {
+					return true;
+				}
+				if(targetSegments == null) {
+					return false;
+				}
+				
+				int segmentCount = 
sourceSegments.segmentCount();
+				int targetCount = targetSegments.segmentCount
();
+				if(segmentCount > targetCount) {
+					return false;
+				}
+				
+				for(int i = segmentCount - 1; i >= 0; i--) {
+					if(!sourceSegments.segment(i).equals
(targetSegments.segment(--targetCount))) {
+						return false;
+					}	
+				}
+				
+				return true;
+			}
+			
+			public boolean visit(IResourceProxy proxy) throws 
CoreException {
+				String resourceName = proxy.getName();
+				if(resourceName.equals(lastSegment)) {
+					IResource res = proxy.requestResource
();
+					if(!res.exists()) {
+						return true;
+					}
+					
+					//Check segment match criteria to 
make sure we really match this entry
+					IPath location = res.getLocation();
+					if(checkSegments(pathSegments, 
location.removeLastSegments(1)) != true) {
+						return true;
+					} 
+					
+					list.add(location);
+				}
+				return true;
 			}
-		}		
+		};
+		
+		parent.accept(visitor, IResource.NONE);		
 	}

--- PATCH END ---
Index: src/org/eclipse/cdt/internal/ui/editor/OpenIncludeAction.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/OpenIncludeAction.java,v
retrieving revision 1.7
diff -u -r1.7 OpenIncludeAction.java
--- src/org/eclipse/cdt/internal/ui/editor/OpenIncludeAction.java	28 Aug 2003 19:47:01 -0000	1.7
+++ src/org/eclipse/cdt/internal/ui/editor/OpenIncludeAction.java	9 Feb 2004 09:19:25 -0000
@@ -23,6 +23,8 @@
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceProxy;
+import org.eclipse.core.resources.IResourceProxyVisitor;
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IPath;
@@ -83,10 +85,15 @@
 					if (info != null) {
 						String[] includePaths = info.getIncludePaths();
 						findFile(includePaths, includeName, filesFound);
-					} else {
-						// Fall back and search the project
+					} 
+					
+					//If we didn't find anything, then the worst that we can do is to 
+					//search the local project.  Of course if we did find something in
+					//the include path, then we should stick to only showing that.					
+					if(filesFound.isEmpty()) {
 						findFile(proj, new Path(includeName), filesFound);
 					}
+					
 				}
 			}
 			IPath fileToOpen;
@@ -125,17 +132,62 @@
 		}
 	}
 
-	private void findFile(IContainer parent, IPath name, ArrayList list) throws CoreException {
-		IResource found= parent.findMember(name);
-		if (found != null && found.getType() == IResource.FILE) {
-			list.add(found.getLocation());
+	private void findFile(IContainer parent, IPath name, final ArrayList list) throws CoreException {
+		final String lastSegment = name.lastSegment();
+		if(lastSegment == null) {
+			return;
 		}
-		IResource[] children= parent.members();
-		for (int i= 0; i < children.length; i++) {
-			if (children[i] instanceof IContainer) {
-				findFile((IContainer)children[i], name, list);
+
+		final IPath pathSegments = name.removeLastSegments(1);
+		
+		//We use the lastSegment as a fast key, but then make sure that we can match
+		//the rest of the segments (if they exist) so a path like:
+		//#include "subsystem/includefile.h" won't match with "a/b/c/includefile.h"
+		IResourceProxyVisitor visitor = new IResourceProxyVisitor() {
+			private boolean checkSegments(IPath sourceSegments, IPath targetSegments) {
+				if(sourceSegments == null) {
+					return true;
+				}
+				if(targetSegments == null) {
+					return false;
+				}
+				
+				int segmentCount = sourceSegments.segmentCount();
+				int targetCount = targetSegments.segmentCount();
+				if(segmentCount > targetCount) {
+					return false;
+				}
+				
+				for(int i = segmentCount - 1; i >= 0; i--) {
+					if(!sourceSegments.segment(i).equals(targetSegments.segment(--targetCount))) {
+						return false;
+					}	
+				}
+				
+				return true;
+			}
+			
+			public boolean visit(IResourceProxy proxy) throws CoreException {
+				String resourceName = proxy.getName();
+				if(resourceName.equals(lastSegment)) {
+					IResource res = proxy.requestResource();
+					if(!res.exists()) {
+						return true;
+					}
+					
+					//Check segment match criteria to make sure we really match this entry
+					IPath location = res.getLocation();
+					if(checkSegments(pathSegments, location.removeLastSegments(1)) != true) {
+						return true;
+					} 
+					
+					list.add(location);
+				}
+				return true;
 			}
-		}		
+		};
+		
+		parent.accept(visitor, IResource.NONE);		
 	}

Back to the top