diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/corext/codemanipulation/InclusionContext.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/corext/codemanipulation/InclusionContext.java index f121ad18061..600e794dea4 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/corext/codemanipulation/InclusionContext.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/corext/codemanipulation/InclusionContext.java @@ -22,6 +22,7 @@ import org.eclipse.core.runtime.Path; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.parser.IScannerInfo; +import org.eclipse.cdt.utils.PathUtil; import org.eclipse.cdt.internal.core.parser.scanner.CPreprocessor; import org.eclipse.cdt.internal.core.parser.scanner.IncludeSearchPath; @@ -225,4 +226,30 @@ public class InclusionContext { } return false; } + + public IncludeInfo createIncludeInfo(IPath header, IncludeGroupStyle style) { + String name = null; + if (style.isRelativePath()) { + name = getRelativePath(header); + } + if (name == null) { + IncludeInfo includeInfo = getIncludeForHeaderFile(header); + if (includeInfo != null) { + name = includeInfo.getName(); + } else { + name = getRelativePath(header); + } + if (name == null) { + name = header.toPortableString(); // Last resort. + } + } + return new IncludeInfo(name, style.isAngleBrackets()); + } + + private String getRelativePath(IPath header) { + IPath relativePath = PathUtil.makeRelativePath(header, getCurrentDirectory()); + if (relativePath == null) + return null; + return relativePath.toString(); + } } \ No newline at end of file diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/includes/IncludeCreator.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/includes/IncludeCreator.java index 28e5973e9f7..cbc54a86ba4 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/includes/IncludeCreator.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/includes/IncludeCreator.java @@ -155,6 +155,8 @@ public class IncludeCreator { } } + HeaderSubstitutor headerSubstitutor = new HeaderSubstitutor(fContext); + for (IIndexBinding indexBinding : bindings) { // Replace ctor with the class itself. if (indexBinding instanceof ICPPConstructor) { @@ -169,7 +171,8 @@ public class IncludeCreator { } if (definitions != null) { for (IIndexName definition : definitions) { - considerForInclusion(definition, indexBinding, index, candidatesMap); + considerForInclusion(definition, indexBinding, index, headerSubstitutor, + candidatesMap); } if (definitions.length > 0 && adaptedBinding != null) break; @@ -178,7 +181,7 @@ public class IncludeCreator { IIndexMacro[] macros = index.findMacros(nameChars, filter, new NullProgressMonitor()); for (IIndexMacro macro : macros) { IIndexName definition = macro.getDefinition(); - considerForInclusion(definition, macro, index, candidatesMap); + considerForInclusion(definition, macro, index, headerSubstitutor, candidatesMap); } final ArrayList candidates = new ArrayList(candidatesMap.values()); @@ -404,8 +407,8 @@ public class IncludeCreator { * Adds an include candidate to the candidates map if the file containing * the definition is suitable for inclusion. */ - private void considerForInclusion(IIndexName definition, IIndexBinding binding, - IIndex index, Map candidates) throws CoreException { + private void considerForInclusion(IIndexName definition, IIndexBinding binding, IIndex index, + HeaderSubstitutor headerSubstitutor, Map candidates) throws CoreException { if (definition == null) { return; } @@ -413,8 +416,16 @@ public class IncludeCreator { // Consider the file for inclusion only if it is not a source file, // or a source file that was already included by some other file. if (!isSource(getPath(file)) || index.findIncludedBy(file, 0).length > 0) { - IIndexFile representativeFile = getRepresentativeFile(file, index); - IncludeInfo include = getRequiredInclude(representativeFile, index); + IncludeInfo include; + if (fContext.getPreferences().heuristicHeaderSubstitution) { + include = getIncludeByHeuristic(file, index); + } else { + IPath header = getAbsolutePath(file.getLocation()); + header = headerSubstitutor.getPreferredRepresentativeHeader(header); + IncludeGroupStyle style = fContext.getIncludeStyle(header); + include = fContext.createIncludeInfo(header, style); + } + if (include != null) { IncludeCandidate candidate = new IncludeCandidate(binding, include); if (!candidates.containsKey(candidate.toString())) { @@ -431,11 +442,10 @@ public class IncludeCreator { } ArrayList targetChain = getUsingChain(target); if (targetChain.size() <= 1) { - return null; // Target is not in a namespace + return null; // Target is not in a namespace. } - // Check if any of the existing using declarations and directives matches - // the target. + // Check if any of the existing using declarations and directives matches the target. final IASTDeclaration[] declarations= ast.getDeclarations(false); for (IASTDeclaration declaration : declarations) { if (declaration.isPartOfTranslationUnitFile()) { @@ -530,7 +540,8 @@ public class IncludeCreator { processed.add(headerFile); while (!front.isEmpty()) { IIndexFile file = front.remove(); - // A header without an extension is a good candidate for inclusion into a C++ source file. + // A header without an extension is a good candidate for inclusion into a C++ source + // file. if (fContext.isCXXLanguage() && !hasExtension(getPath(file))) { return file; } @@ -604,12 +615,14 @@ public class IncludeCreator { } /** - * Returns the RequiredInclude object to be added to the include list + * Returns the {@link IncludeInfo} object to be added to the include list + * * @param path - the full path of the file to include - * @return the required include + * @return the {@link IncludeInfo} object * @throws CoreException */ - private IncludeInfo getRequiredInclude(IIndexFile file, IIndex index) throws CoreException { + private IncludeInfo getIncludeByHeuristic(IIndexFile file, IIndex index) throws CoreException { + file = getRepresentativeFile(file, index); IIndexInclude[] includes = index.findIncludedBy(file); if (includes.length > 0) { // Let the existing includes vote. To be eligible to vote, an include diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/includes/IncludeOrganizer.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/includes/IncludeOrganizer.java index 3d7bf8df919..f1993845380 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/includes/IncludeOrganizer.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/includes/IncludeOrganizer.java @@ -81,7 +81,6 @@ import org.eclipse.cdt.core.parser.util.CharArrayIntMap; import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.CodeGeneration; -import org.eclipse.cdt.utils.PathUtil; import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.ASTCommenter; import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap; @@ -219,7 +218,7 @@ public class IncludeOrganizer { // Put the new includes into includePrototypes. for (IPath header : fContext.getHeadersToInclude()) { IncludeGroupStyle style = fContext.getIncludeStyle(header); - IncludeInfo includeInfo = createIncludeInfo(header, style); + IncludeInfo includeInfo = fContext.createIncludeInfo(header, style); IncludePrototype prototype = new IncludePrototype(header, includeInfo, style); updateIncludePrototypes(includePrototypes, prototype); } @@ -1062,32 +1061,6 @@ public class IncludeOrganizer { return requests; } - private IncludeInfo createIncludeInfo(IPath header, IncludeGroupStyle style) { - String name = null; - if (style.isRelativePath()) { - name = getRelativePath(header); - } - if (name == null) { - IncludeInfo includeInfo = fContext.getIncludeForHeaderFile(header); - if (includeInfo != null) { - name = includeInfo.getName(); - } else { - name = getRelativePath(header); - } - if (name == null) { - name = header.toPortableString(); // Last resort. - } - } - return new IncludeInfo(name, style.isAngleBrackets()); - } - - private String getRelativePath(IPath header) { - IPath relativePath = PathUtil.makeRelativePath(header, fContext.getCurrentDirectory()); - if (relativePath == null) - return null; - return relativePath.toPortableString(); - } - private String createIncludeDirective(IncludePrototype include, String lineComment) { StringBuilder buf = new StringBuilder(); // Unresolved includes are preserved out of caution. Partner include is always preserved.