Bug 113063 - "Add include" does not add includes correctly..
Summary: "Add include" does not add includes correctly..
Status: RESOLVED FIXED
Alias: None
Product: CDT
Classification: Tools
Component: cdt-core (show other bugs)
Version: 3.0   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 8.2.1   Edit
Assignee: Sergey Prigogin CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-10-19 07:49 EDT by Neeraj Bhope CLA
Modified: 2013-08-26 16:22 EDT (History)
8 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Neeraj Bhope CLA 2005-10-19 07:49:54 EDT
Steps to reproduce.
1) Create a C++ project and create two classes t1 and t2.
2) In t2.h, type in a new member "t1 aT1;"
3) Place cursor on t1 and click "Add include" in the context menu.
4) "using namespace dummy namespace;" is added at the top of the file instead of
the expected "#include "t1.h""

Preliminary finding:
In AddIncludeOnSelectionAction.extractIncludes() the following piece of code
puts a string "dummy namespace" in fUsings which results in bypassing the code
following it.
			// Try contribution from plugins.
			IFunctionSummary fs = findContribution(name);
			if (fs != null) {
				fRequiredIncludes = fs.getIncludes();
				String ns = fs.getNamespace();
				if (ns != null && ns.length() > 0) {
					fUsings = new String[] {fs.getNamespace()};
				}
			}

Why??
Comment 1 Janees Elamkulam CLA 2005-10-26 04:44:52 EDT
dummy name space is due to the plugin org.eclipse.cdt.ui.tests

but "Add Include" does not add the includes correctly see the mail below

From: cdt-dev-bounces@eclipse.org [mailto:cdt-dev-bounces@eclipse.org] On 
Behalf Of Janees Elamkulam
Sent: Monday, October 24, 2005 2:23 AM
To: CDT General developers list.
Subject: [cdt-dev] Add Include broken ? 
  

Hi, 

I have two classes say 'Class1' and 'Class2' in a Project. (TestProject),  now 
add a member variable 'var1' of type 'Class1'in Class2.  Now add header file 
for Class1 using context menu (Right Click on Class1 -> Add Include). the 
result is #include "/TestProject/Class1.h" 
Shouldn't it be  #include "Class1.h" or atleast  
#include "TestProject/Class1.h" ? 

A quick look on this, I found 
that  "AddIncludeOnSelectionAction::getRequiredInclude" 
and "PathUtil::makeRelativePathToProjectIncludes" expects path in full and not 
related to the project as root , returned 
by "AddIncludeOnSelectionAction::findTypeInfos". This relative path is making 
the following code snippet in AddIncludeOnSelectionAction::getRequiredInclude  
to fail 

          if (includePath != null && !projectLocation.isPrefixOf
(typeLocation)) { 
               isSystemIncludePath = true; 
           } else if (projectLocation.isPrefixOf(typeLocation) 
                   && projectLocation.isPrefixOf(headerLocation)) { 
               includePath = PathUtil.makeRelativePath(typeLocation, 
headerLocation.removeLastSegments(1)); 
           } 
          if (includePath == null) 
               includePath = typeLocation; 

Is this a defect ? or am i doing some thing wrong ? 


Thanks, 

- Janees 
Comment 2 Janees Elamkulam CLA 2005-10-26 04:50:02 EDT
A possible solution given below. The fix is 
in 'AddIncludeOnSelectionAction::getRequiredInclude' . The idea is to check 
for whether the device is null; for absolute path it  should not  be null. The 
changes are given below with ">" prefixed.. 

private IRequiredInclude getRequiredInclude(ITypeInfo curr, ITranslationUnit 
tu) { 
        ITypeReference ref = curr.getResolvedReference(); 
        if (ref != null) { 
            IPath typeLocation = ref.getLocation(); 
                    IProject project = tu.getCProject().getProject(); 
            IPath projectLocation = project.getLocation(); 
                IPath headerLocation = tu.getResource().getLocation(); 
            boolean isSystemIncludePath = false; 
            
>            if(typeLocation.getDevice() == null && 
>                    project.getName().equals(typeLocation.segment(0))){ 
>                    typeLocation = projectLocation.removeLastSegments
(1).append(typeLocation); 
>            } 

            IPath includePath = PathUtil.makeRelativePathToProjectIncludes
(typeLocation, project); 
            if (includePath != null && !projectLocation.isPrefixOf
(typeLocation)) { 
                isSystemIncludePath = true; 
            } else if (projectLocation.isPrefixOf(typeLocation) 

I have also noted following problem for adding include for methods and 
dependent project types (i.e found through 'findMatches'). The error is in 
AddIncludeOnSelectionAction::selectResult(IMatch[] results, String name, Shell 
shell), it create new include as shown bellow. 

fRequiredIncludes[0] = new RequiredIncludes(curr.getLocation().lastSegment()); 

 This will just add <filename.h> . does not process it like the 
result 'findTypeInfos'. Solution for this is to write a function 
getRequiredInclude for IMatch type similar to the getRequiredInclude for  
ITypeInfo. 

Regards, 

- Janees 
Comment 3 Chris Recoskie CLA 2006-07-13 11:10:19 EDT
We'll look at fixing this for 3.1.1
Comment 4 Chris Recoskie CLA 2006-08-31 08:51:53 EDT
I have committed a partial fix for this bug to HEAD and 3.1.1 (thanks Janees and Vivian).  This will add an include that can be mapped to any header that the index knows about.  Please try it out.

The bigger question is how we want to deal with headers that the index doesn't know about.  The main use case for this feature is that you use it to add an include that you've not used somewhere before.  We need to have a discussion as to how that would work.  Do we have an indexer workbench preference for system include path root (e.g. /usr/include) that the indexer automatically adds to the index?  How do we pre-determine what the default for that path should be?  Really I think for that type of feature to work properly we need to properly interface to Mikhail S's proposed CDT-wide toolchains from CDT 4.0.
Comment 5 Chris Recoskie CLA 2006-09-07 10:24:04 EDT
Deferring the rest of the work to CDT 4.0.  We should have a discussion at the Summit as to how we would like to see this work in terms of automatic discovery of system includes.
Comment 6 Ravi Sankar CLA 2007-05-29 01:11:50 EDT
This bug seems to be fixed in 4.0.

Ravi

Comment 7 Ravi Sankar CLA 2007-05-29 01:21:07 EDT
(In reply to comment #6)
> This bug seems to be fixed in 4.0.
> Ravi

Oops sorry, the bug is not fixed completely. The issue chris has reported is still open.

Ravi
Comment 8 Chris Recoskie CLA 2007-06-08 10:32:50 EDT
The pieces are there but no one has had time to hook them up yet.  The SDK index stuff should provide a means for us to have a pre-built index of the system includes (or to create one on first run of CDT).  I will look at this again post-4.0.
Comment 9 David Michael CLA 2008-01-22 19:37:34 EST
I'm currently working around the problem Chris mentioned by using the "Indexer/Index all files (files neither built nor included, also)" option.

I'm running in to a different issue though.  I work on a relatively large system (~1 million lines of code, ~150 shared libraries, etc).  I don't want our developers to have to have the entire system in their workspace (it would make for a CM nightmare), so I'm trying to figure out how to make a project with a subset of our code reference all or some of the other "subsystems" of code from our main build tree.  If I add these external code directories as include directories (C++ General/Paths and symbols/Includes/G++ Includes), the indexer works fine and does what we want.  But if I use "Add Include", it always treats the .h file as a system library, i.e. - '#include <file.h>', rather than '#include "file.h"'.  That technically works okay, but it's not the usual convention.  If I add the external subsystems as Eclipse linked directories, then add those as includes, I get the same effect.

So I'm asking - is there a way to get the Add Include feature to add includes for files in directories outside the workspace using double quotes instead of angle brackets?  I understand that angle brackets make sense for many/most cases where people include a file outside of their workspace, but it doesn't make sense for us.  I think there should be a way to specify for a given include diretory whether it is a system library or not.  That, or have Add Include be smart enough to know the difference itself.
Comment 10 Mike Kucera CLA 2008-01-23 10:15:26 EST
(In reply to comment #9)

> I'm running in to a different issue though.  I work on a relatively large
> system (~1 million lines of code, ~150 shared libraries, etc).  I don't want
> our developers to have to have the entire system in their workspace (it would
> make for a CM nightmare), so I'm trying to figure out how to make a project
> with a subset of our code reference all or some of the other "subsystems" of
> code from our main build tree.  

If you are just worried about clutter in your workspace you can use working sets to manage that.

Comment 11 David Michael CLA 2008-01-23 12:47:25 EST
(In reply to comment #10)
> If you are just worried about clutter in your workspace you can use working
> sets to manage that.

I emailed you a longer description of how we work.  The bottom line is, I'd rather not change our development paradigm to fit us in to Eclipse/CDT.  

And... after a little test, it looks like Add Include treats anything outside my _project_ as a system library.  So we'd basically have to have our whole system in 1 project to work around the <> includes, which is not really practical.  It would be acceptable to add a "Linked" folder to the external code to my project (instead of simply adding them as GNU C++ Include paths), but that has the same problem - a Linked Folder is treated as a system library (i.e., uses #include <...> instead of #include "...").

(By the way, I forgot to mention (or didn't notice) that the "Index all files" workaround I used for the problem Chris described only seems to help for source files that are in the project (either physically or via a linked folder). )
Comment 12 Chris Recoskie CLA 2008-01-23 13:25:31 EST
David,

One additional thing you can try is the "files to index up front" indexer setting.  This will let you add files that aren't in the project.  However, I suspect it will still try to include them via angle brackets (system includes) rather than quotes.
Comment 13 David Michael CLA 2008-01-23 14:47:23 EST
(In reply to comment #12)
> David,
> One additional thing you can try is the "files to index up front" indexer
> setting.  This will let you add files that aren't in the project.  However, I
> suspect it will still try to include them via angle brackets (system includes)
> rather than quotes.
Thanks for the suggestion.  Unfortunately, you're right - it still uses angle brackets.  This also probably wouldn't really be a practical solution for us, since we have a total of about 4000 classes to list :-)
Comment 14 Sergey Prigogin CLA 2013-08-26 16:22:19 EDT
(In reply to comment #13)
Fixed in cdt_8_2 and master. Please keep in mind that the fix depends on proper setting of system and non-system directories in the include path of the project.