1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-02 05:45:58 +02:00

Added IIndexInclude.getFullName method. Bug 272815.

This commit is contained in:
Sergey Prigogin 2009-04-23 05:47:34 +00:00
parent 2b18829db8
commit 6d64bcb42a
7 changed files with 172 additions and 108 deletions

View file

@ -6,7 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* QNX - Initial API and implementation * QNX - Initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.pdom.tests; package org.eclipse.cdt.internal.pdom.tests;
@ -21,13 +22,12 @@ import org.eclipse.cdt.core.index.IndexLocationFactory;
import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.Path;
/** /**
* @author Doug Schaefer * @author Doug Schaefer
*
*/ */
public class IncludesTests extends PDOMTestBase { public class IncludesTests extends PDOMTestBase {
protected ICProject project; protected ICProject project;
protected IIndex index; protected IIndex index;
@ -49,7 +49,7 @@ public class IncludesTests extends PDOMTestBase {
public void testIncludedBy() throws Exception { public void testIncludedBy() throws Exception {
IResource loc = project.getProject().findMember("I2.h"); IResource loc = project.getProject().findMember("I2.h");
IIndexFile file = index.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL((IFile)loc)); IIndexFile file = index.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL((IFile) loc));
assertNotNull(file); assertNotNull(file);
IIndexInclude[] allIncludedBy = index.findIncludedBy(file, -1); IIndexInclude[] allIncludedBy = index.findIncludedBy(file, -1);
assertEquals(9, allIncludedBy.length); // i.e. all of them assertEquals(9, allIncludedBy.length); // i.e. all of them
@ -57,9 +57,41 @@ public class IncludesTests extends PDOMTestBase {
public void testIncludes() throws Exception { public void testIncludes() throws Exception {
IResource loc = project.getProject().findMember("I1.cpp"); IResource loc = project.getProject().findMember("I1.cpp");
IIndexFile file = index.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL((IFile)loc)); IIndexFile file = index.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL((IFile) loc));
assertNotNull(file); assertNotNull(file);
IIndexInclude[] allIncludesTo= index.findIncludes(file, -1); IIndexInclude[] allIncludesTo= index.findIncludes(file, -1);
assertEquals(2, allIncludesTo.length); // i.e. I1.h, I2.h assertEquals(2, allIncludesTo.length); // i.e. I1.h, I2.h
} }
public void testIncludeName() throws Exception {
IResource loc = project.getProject().findMember("a/b/I6.h");
IIndexFile file = index.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL((IFile) loc));
assertNotNull(file);
IIndexInclude[] allIncludedBy = index.findIncludedBy(file, -1);
assertEquals(2, allIncludedBy.length);
for (IIndexInclude include : allIncludedBy) {
assertTrue(include.isResolved());
assertFalse(include.isSystemInclude());
IIndexFile includer = include.getIncludedBy();
String includerName = new Path(includer.getLocation().getFullPath()).lastSegment();
if ("I6.cpp".equals(includerName)) {
assertEquals("I6.h", include.getName());
assertEquals("a/b/I6.h", include.getFullName());
} else {
assertEquals("I7.cpp", includerName);
assertEquals("I6.h", include.getName());
assertEquals("b/I6.h", include.getFullName());
IIndexInclude[] includes = includer.getIncludes();
for (IIndexInclude include2 : includes) {
if ("I7.h".equals(include2.getName())) {
assertFalse(include2.isResolved());
assertFalse(include2.isSystemInclude());
assertEquals("b/I7.h", include2.getFullName());
} else {
assertEquals("I6.h", include2.getName());
}
}
}
}
}
} }

View file

@ -0,0 +1 @@
#include "a/b/I6.h"

View file

@ -0,0 +1,2 @@
#include "b/I6.h"
#include "b/I7.h"

View file

@ -8,6 +8,7 @@
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
* Andrew Ferguson (Symbian) * Andrew Ferguson (Symbian)
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.core.index; package org.eclipse.cdt.core.index;
@ -57,8 +58,16 @@ public interface IIndexInclude {
String getName() throws CoreException; String getName() throws CoreException;
/** /**
* Returns the character offset of the name of the include in its source file. The name does * Returns the name of the include. The name does not include the enclosing quotes
* not include the enclosing quotes or angle brackets. * or angle brackets. E.g.: for '<sys/types.h>' 'sys/types.h' will be returned.
* @throws CoreException
* @since 5.1
*/
String getFullName() throws CoreException;
/**
* Returns the character offset of the name of the include in its source file.
* The name does not include the enclosing quotes or angle brackets.
* @throws CoreException * @throws CoreException
*/ */
int getNameOffset() throws CoreException; int getNameOffset() throws CoreException;

View file

@ -173,11 +173,12 @@ public class PDOM extends PlatformObject implements IPDOM {
* 80.0 - support for specializations of partial specializations, bug 259872 * 80.0 - support for specializations of partial specializations, bug 259872
* 81.0 - change to c++ function types, bug 264479 * 81.0 - change to c++ function types, bug 264479
* 82.0 - offsets for using directives, bug 270806 * 82.0 - offsets for using directives, bug 270806
* 83.0 - unconditionally store name in PROMInclude, bug 272815
*/ */
private static int version(int major, int minor) { private static int version(int major, int minor) {
return major << 16 + minor; return major << 16 + minor;
} }
public static final int MAJOR_VERSION = 82; public static final int MAJOR_VERSION = 83;
public static final int MINOR_VERSION = 0; // minor versions must be compatible public static final int MINOR_VERSION = 0; // minor versions must be compatible
public static final int CURRENT_VERSION= version(MAJOR_VERSION, MINOR_VERSION); public static final int CURRENT_VERSION= version(MAJOR_VERSION, MINOR_VERSION);

View file

@ -6,8 +6,9 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* QNX - Initial API and implementation * QNX - Initial API and implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom; package org.eclipse.cdt.internal.core.pdom.dom;
@ -21,69 +22,83 @@ import org.eclipse.cdt.internal.core.index.IIndexFragment;
import org.eclipse.cdt.internal.core.index.IIndexFragmentFile; import org.eclipse.cdt.internal.core.index.IIndexFragmentFile;
import org.eclipse.cdt.internal.core.index.IIndexFragmentInclude; import org.eclipse.cdt.internal.core.index.IIndexFragmentInclude;
import org.eclipse.cdt.internal.core.pdom.db.Database; import org.eclipse.cdt.internal.core.pdom.db.Database;
import org.eclipse.cdt.internal.core.pdom.db.IString;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
/** /**
* @author Doug Schaefer * @author Doug Schaefer
*
*/ */
public class PDOMInclude implements IIndexFragmentInclude { public class PDOMInclude implements IIndexFragmentInclude {
private static final int INCLUDES_FILE_OR_NAME = 0; private static final int INCLUDED_FILE = 0;
private static final int INCLUDED_BY = 4; private static final int INCLUDED_BY = 4;
private static final int INCLUDES_NEXT = 8; private static final int INCLUDES_NEXT = 8;
private static final int INCLUDED_BY_NEXT = 12; private static final int INCLUDED_BY_NEXT = 12;
private static final int INCLUDED_BY_PREV = 16; private static final int INCLUDED_BY_PREV = 16;
private static final int NODE_OFFSET_OFFSET = 20; // If the include name is the same as the end part of the path of the included file,
private static final int NODE_LENGTH_OFFSET = 24; // we store the length of the name instead of the name itself, and indicate that
private static final int FLAG_OFFSET = 26; // by turning on FLAG_DEDUCIBLE_NAME flag. Notice that the length of include name
private static final int RECORD_SIZE = 27; // can be different from the node length, if the name is defined by a macro.
private static final int INCLUDE_NAME_OR_LENGTH = 20;
private static final int NODE_OFFSET = 24; // 3-byte unsigned int (sufficient for files <= 16mb)
private static final int NODE_LENGTH = 27; // short (sufficient for names <= 32k)
private static final int FLAGS = 29;
private static final int RECORD_SIZE = 30;
private static final int FLAG_SYSTEM_INCLUDE = 1; private static final int FLAG_SYSTEM_INCLUDE = 0x01;
private static final int FLAG_INACTIVE_INCLUDE = 2; private static final int FLAG_INACTIVE_INCLUDE = 0x02;
private static final int FLAG_UNRESOLVED_INCLUDE = 4; private static final int FLAG_RESOLVED_BY_HEURISTICS= 0x04;
private static final int FLAG_RESOLVED_BY_HEURISTICS= 8; private static final int FLAG_DEDUCIBLE_NAME = 0x08;
private final PDOMLinkage linkage; private final PDOMLinkage linkage;
private final int record; private final int record;
// cached fields // Cached fields
private String fName= null; private String fName;
public PDOMInclude(PDOMLinkage pdom, int record) { public PDOMInclude(PDOMLinkage pdom, int record) {
this.linkage = pdom; this.linkage = pdom;
this.record = record; this.record = record;
} }
public PDOMInclude(PDOMLinkage linkage, IASTPreprocessorIncludeStatement include, PDOMFile containerFile, PDOMFile targetFile) throws CoreException { public PDOMInclude(PDOMLinkage linkage, IASTPreprocessorIncludeStatement include, PDOMFile containerFile,
PDOMFile targetFile) throws CoreException {
this.linkage = linkage; this.linkage = linkage;
this.record = linkage.getDB().malloc(RECORD_SIZE); this.record = linkage.getDB().malloc(RECORD_SIZE);
IASTName name= include.getName(); IASTName name = include.getName();
IASTFileLocation loc= name.getFileLocation(); char[] nameChars = name.getSimpleID();
// includes generated by -include or -macro don't have a location IASTFileLocation loc = name.getFileLocation();
// Includes generated by -include or -macro don't have a location
if (loc != null) { if (loc != null) {
setNameOffsetAndLength(loc.getNodeOffset(), (short) loc.getNodeLength()); linkage.getDB().put3ByteUnsignedInt(record + NODE_OFFSET, loc.getNodeOffset());
linkage.getDB().putShort(record + NODE_LENGTH, (short) loc.getNodeLength());
} }
setFlag(encodeFlags(include, targetFile == null)); final Database db = linkage.getDB();
if (targetFile != null) {
db.putInt(record + INCLUDED_FILE, targetFile.getRecord());
}
boolean deducible_name = isDeducibleName(targetFile, nameChars);
// If the name is the same as an end part of the path of the included file,
// store the length of the name instead of the name itself.
int rec= deducible_name ? nameChars.length : db.newString(nameChars).getRecord();
db.putInt(record + INCLUDE_NAME_OR_LENGTH, rec);
setFlag(encodeFlags(include, deducible_name));
setIncludedBy(containerFile); setIncludedBy(containerFile);
setIncludes(targetFile, name.getSimpleID());
} }
private byte encodeFlags(IASTPreprocessorIncludeStatement include, boolean unresolved) { private byte encodeFlags(IASTPreprocessorIncludeStatement include, boolean deducible_name) {
byte flags= 0; byte flags= 0;
if (include.isSystemInclude()) { if (include.isSystemInclude()) {
flags |= FLAG_SYSTEM_INCLUDE; flags |= FLAG_SYSTEM_INCLUDE;
} }
if (!include.isActive()) { if (!include.isActive()) {
flags |= FLAG_INACTIVE_INCLUDE; flags |= FLAG_INACTIVE_INCLUDE;
}
if (unresolved) {
flags |= FLAG_UNRESOLVED_INCLUDE;
} else if (include.isResolvedByHeuristics()) { } else if (include.isResolvedByHeuristics()) {
flags |= FLAG_RESOLVED_BY_HEURISTICS; flags |= FLAG_RESOLVED_BY_HEURISTICS;
} }
if (deducible_name) {
flags |= FLAG_DEDUCIBLE_NAME;
}
return flags; return flags;
} }
@ -96,51 +111,51 @@ public class PDOMInclude implements IIndexFragmentInclude {
// Remove us from the includedBy chain // Remove us from the includedBy chain
removeThisFromIncludedByChain(); removeThisFromIncludedByChain();
} }
else { final Database db = linkage.getDB();
getNameForUnresolved().delete(); if ((getFlag() & FLAG_DEDUCIBLE_NAME) == 0) {
int rec = db.getInt(record + INCLUDE_NAME_OR_LENGTH);
db.getString(rec).delete();
} }
// Delete our record // Delete our record
linkage.getDB().free(record); db.free(record);
} }
private void removeThisFromIncludedByChain() throws CoreException { private void removeThisFromIncludedByChain() throws CoreException {
PDOMInclude prevInclude = getPrevInIncludedBy(); PDOMInclude prevInclude = getPrevInIncludedBy();
PDOMInclude nextInclude = getNextInIncludedBy(); PDOMInclude nextInclude = getNextInIncludedBy();
if (prevInclude != null) if (prevInclude != null) {
prevInclude.setNextInIncludedBy(nextInclude); prevInclude.setNextInIncludedBy(nextInclude);
else } else {
((PDOMFile) getIncludes()).setFirstIncludedBy(nextInclude); ((PDOMFile) getIncludes()).setFirstIncludedBy(nextInclude);
}
if (nextInclude != null) if (nextInclude != null)
nextInclude.setPrevInIncludedBy(prevInclude); nextInclude.setPrevInIncludedBy(prevInclude);
} }
private IString getNameForUnresolved() throws CoreException {
if (isResolved()) {
return null;
}
final Database db = linkage.getDB();
return db.getString(db.getInt(record + INCLUDES_FILE_OR_NAME));
}
public IIndexFragmentFile getIncludes() throws CoreException { public IIndexFragmentFile getIncludes() throws CoreException {
if (!isResolved()) { int rec = linkage.getDB().getInt(record + INCLUDED_FILE);
return null;
}
int rec = linkage.getDB().getInt(record + INCLUDES_FILE_OR_NAME);
return rec != 0 ? new PDOMFile(linkage, rec) : null; return rec != 0 ? new PDOMFile(linkage, rec) : null;
} }
private void setIncludes(PDOMFile includes, char[] name) throws CoreException { /**
int rec= 0; * Checks if the name is the same as the end part of the path of the included file.
if (includes == null) { */
rec= linkage.getDB().newString(name).getRecord(); private static boolean isDeducibleName(PDOMFile includedFile, char[] name) throws CoreException {
if (includedFile == null) {
return false;
} }
else { String s = includedFile.getLocation().getURI().getPath();
rec= includes.getRecord(); int pos = s.length() - name.length;
if (pos < 0) {
return false;
} }
linkage.getDB().putInt(record + INCLUDES_FILE_OR_NAME, rec); for (int i = 0; i < name.length; i++, pos++) {
if (s.charAt(pos) != name[i]) {
return false;
}
}
return true;
} }
public IIndexFile getIncludedBy() throws CoreException { public IIndexFile getIncludedBy() throws CoreException {
@ -192,27 +207,20 @@ public class PDOMInclude implements IIndexFragmentInclude {
} }
public IIndexFileLocation getIncludesLocation() throws CoreException { public IIndexFileLocation getIncludesLocation() throws CoreException {
if (!isResolved()) { IIndexFragmentFile includes = getIncludes();
return null; return includes != null ? includes.getLocation() : null;
}
return getIncludes().getLocation();
} }
public IIndexFragment getFragment() { public IIndexFragment getFragment() {
return linkage.getPDOM(); return linkage.getPDOM();
} }
private void setNameOffsetAndLength(int offset, short length) throws CoreException {
linkage.getDB().putInt(record + NODE_OFFSET_OFFSET, offset);
linkage.getDB().putShort(record + NODE_LENGTH_OFFSET, length);
}
private void setFlag(byte flag) throws CoreException { private void setFlag(byte flag) throws CoreException {
linkage.getDB().putByte(record + FLAG_OFFSET, flag); linkage.getDB().putByte(record + FLAGS, flag);
} }
private int getFlag() throws CoreException { private int getFlag() throws CoreException {
return linkage.getDB().getByte(record + FLAG_OFFSET); return linkage.getDB().getByte(record + FLAGS);
} }
public boolean isSystemInclude() throws CoreException { public boolean isSystemInclude() throws CoreException {
@ -224,7 +232,7 @@ public class PDOMInclude implements IIndexFragmentInclude {
} }
public boolean isResolved() throws CoreException { public boolean isResolved() throws CoreException {
return (getFlag() & FLAG_UNRESOLVED_INCLUDE) == 0; return linkage.getDB().getInt(record + INCLUDED_FILE) != 0;
} }
public boolean isResolvedByHeuristics() throws CoreException { public boolean isResolvedByHeuristics() throws CoreException {
@ -232,34 +240,45 @@ public class PDOMInclude implements IIndexFragmentInclude {
} }
public int getNameOffset() throws CoreException { public int getNameOffset() throws CoreException {
return linkage.getDB().getInt(record + NODE_OFFSET_OFFSET); return linkage.getDB().get3ByteUnsignedInt(record + NODE_OFFSET);
} }
public int getNameLength() throws CoreException { public int getNameLength() throws CoreException {
return linkage.getDB().getShort(record + NODE_LENGTH_OFFSET) & 0xffff; return linkage.getDB().getShort(record + NODE_LENGTH) & 0xffff;
} }
public String getName() throws CoreException { public String getFullName() throws CoreException {
if (fName == null) { if (fName == null) {
computeName(); final Database db = linkage.getDB();
// The include name is either stored explicitly, or can be deduced from the path
// of the included file.
if ((getFlag() & FLAG_DEDUCIBLE_NAME) == 0) {
int rec = db.getInt(record + INCLUDE_NAME_OR_LENGTH);
fName = db.getString(rec).getString();
} else {
String path = getIncludes().getLocation().getURI().getPath();
int nameLength = db.getInt(record + INCLUDE_NAME_OR_LENGTH);
fName = path.substring(Math.max(path.length() - nameLength, 0));
}
} }
return fName; return fName;
} }
private void computeName() throws CoreException { public String getName() throws CoreException {
if (isResolved()) { return getFullName().substring(fName.lastIndexOf('/') + 1);
fName= getIncludes().getLocation().getURI().getPath();
}
else {
fName= getNameForUnresolved().getString();
}
fName= fName.substring(fName.lastIndexOf('/')+1);
} }
public void convertToUnresolved() throws CoreException { public void convertToUnresolved() throws CoreException {
if (isResolved()) { if (isResolved()) {
setIncludes(null, getName().toCharArray()); final Database db = linkage.getDB();
setFlag((byte) (getFlag() | FLAG_UNRESOLVED_INCLUDE)); int flag = getFlag();
// Since included file is going away, the name is no longer deducible.
if ((flag & FLAG_DEDUCIBLE_NAME) != 0) {
int rec= db.newString(getFullName()).getRecord();
db.putInt(record + INCLUDE_NAME_OR_LENGTH, rec);
setFlag((byte) (flag & ~FLAG_DEDUCIBLE_NAME));
}
db.putInt(record + INCLUDED_FILE, 0);
} }
} }
} }