1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 14:42:11 +02:00

A step towards unification of Organize Includes and Add Include header

substitution algorithms.
This commit is contained in:
Sergey Prigogin 2013-10-28 16:27:08 -07:00
parent cc3695ca21
commit 642d4c3975
3 changed files with 54 additions and 41 deletions

View file

@ -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();
}
}

View file

@ -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<IncludeCandidate> candidates = new ArrayList<IncludeCandidate>(candidatesMap.values());
@ -404,8 +407,8 @@ public class IncludeCreator {
* Adds an include candidate to the <code>candidates</code> map if the file containing
* the definition is suitable for inclusion.
*/
private void considerForInclusion(IIndexName definition, IIndexBinding binding,
IIndex index, Map<String, IncludeCandidate> candidates) throws CoreException {
private void considerForInclusion(IIndexName definition, IIndexBinding binding, IIndex index,
HeaderSubstitutor headerSubstitutor, Map<String, IncludeCandidate> 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<String> 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

View file

@ -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.