1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-25 01:45:33 +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
*
* Contributors:
* QNX - Initial API and implementation
* QNX - Initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
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.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.Path;
/**
* @author Doug Schaefer
*
*/
public class IncludesTests extends PDOMTestBase {
protected ICProject project;
protected IIndex index;
@ -49,7 +49,7 @@ public class IncludesTests extends PDOMTestBase {
public void testIncludedBy() throws Exception {
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);
IIndexInclude[] allIncludedBy = index.findIncludedBy(file, -1);
assertEquals(9, allIncludedBy.length); // i.e. all of them
@ -57,9 +57,41 @@ public class IncludesTests extends PDOMTestBase {
public void testIncludes() throws Exception {
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);
IIndexInclude[] allIncludesTo= index.findIncludes(file, -1);
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:
* Markus Schorn - initial API and implementation
* Andrew Ferguson (Symbian)
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.core.index;
@ -57,8 +58,16 @@ public interface IIndexInclude {
String getName() 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.
* Returns the name of the include. The name does not include the enclosing quotes
* 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
*/
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
* 81.0 - change to c++ function types, bug 264479
* 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) {
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 CURRENT_VERSION= version(MAJOR_VERSION, MINOR_VERSION);

View file

@ -6,8 +6,9 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* QNX - Initial API and implementation
* Markus Schorn (Wind River Systems)
* QNX - Initial API and implementation
* Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom;
@ -21,158 +22,172 @@ import org.eclipse.cdt.internal.core.index.IIndexFragment;
import org.eclipse.cdt.internal.core.index.IIndexFragmentFile;
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.IString;
import org.eclipse.core.runtime.CoreException;
/**
* @author Doug Schaefer
*
*/
public class PDOMInclude implements IIndexFragmentInclude {
private static final int INCLUDES_FILE_OR_NAME = 0;
private static final int INCLUDED_BY = 4;
private static final int INCLUDES_NEXT = 8;
private static final int INCLUDED_FILE = 0;
private static final int INCLUDED_BY = 4;
private static final int INCLUDES_NEXT = 8;
private static final int INCLUDED_BY_NEXT = 12;
private static final int INCLUDED_BY_PREV = 16;
private static final int NODE_OFFSET_OFFSET = 20;
private static final int NODE_LENGTH_OFFSET = 24;
private static final int FLAG_OFFSET = 26;
private static final int RECORD_SIZE = 27;
// If the include name is the same as the end part of the path of the included file,
// we store the length of the name instead of the name itself, and indicate that
// by turning on FLAG_DEDUCIBLE_NAME flag. Notice that the length of include name
// 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_INACTIVE_INCLUDE = 2;
private static final int FLAG_UNRESOLVED_INCLUDE = 4;
private static final int FLAG_RESOLVED_BY_HEURISTICS= 8;
private static final int FLAG_SYSTEM_INCLUDE = 0x01;
private static final int FLAG_INACTIVE_INCLUDE = 0x02;
private static final int FLAG_RESOLVED_BY_HEURISTICS= 0x04;
private static final int FLAG_DEDUCIBLE_NAME = 0x08;
private final PDOMLinkage linkage;
private final int record;
// cached fields
private String fName= null;
// Cached fields
private String fName;
public PDOMInclude(PDOMLinkage pdom, int record) {
this.linkage = pdom;
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.record = linkage.getDB().malloc(RECORD_SIZE);
IASTName name= include.getName();
IASTFileLocation loc= name.getFileLocation();
// includes generated by -include or -macro don't have a location
IASTName name = include.getName();
char[] nameChars = name.getSimpleID();
IASTFileLocation loc = name.getFileLocation();
// Includes generated by -include or -macro don't have a location
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);
setIncludes(targetFile, name.getSimpleID());
}
private byte encodeFlags(IASTPreprocessorIncludeStatement include, boolean unresolved) {
private byte encodeFlags(IASTPreprocessorIncludeStatement include, boolean deducible_name) {
byte flags= 0;
if (include.isSystemInclude()) {
flags |= FLAG_SYSTEM_INCLUDE;
}
if (!include.isActive()) {
flags |= FLAG_INACTIVE_INCLUDE;
}
if (unresolved) {
flags |= FLAG_UNRESOLVED_INCLUDE;
} else if (include.isResolvedByHeuristics()) {
flags |= FLAG_RESOLVED_BY_HEURISTICS;
}
if (deducible_name) {
flags |= FLAG_DEDUCIBLE_NAME;
}
return flags;
}
public int getRecord() {
return record;
}
public void delete() throws CoreException {
if (isResolved()) {
// Remove us from the includedBy chain
removeThisFromIncludedByChain();
}
else {
getNameForUnresolved().delete();
final Database db = linkage.getDB();
if ((getFlag() & FLAG_DEDUCIBLE_NAME) == 0) {
int rec = db.getInt(record + INCLUDE_NAME_OR_LENGTH);
db.getString(rec).delete();
}
// Delete our record
linkage.getDB().free(record);
db.free(record);
}
private void removeThisFromIncludedByChain() throws CoreException {
PDOMInclude prevInclude = getPrevInIncludedBy();
PDOMInclude nextInclude = getNextInIncludedBy();
if (prevInclude != null)
if (prevInclude != null) {
prevInclude.setNextInIncludedBy(nextInclude);
else
} else {
((PDOMFile) getIncludes()).setFirstIncludedBy(nextInclude);
}
if (nextInclude != null)
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 {
if (!isResolved()) {
return null;
}
int rec = linkage.getDB().getInt(record + INCLUDES_FILE_OR_NAME);
int rec = linkage.getDB().getInt(record + INCLUDED_FILE);
return rec != 0 ? new PDOMFile(linkage, rec) : null;
}
private void setIncludes(PDOMFile includes, char[] name) throws CoreException {
int rec= 0;
if (includes == null) {
rec= linkage.getDB().newString(name).getRecord();
/**
* Checks if the name is the same as the end part of the path of the included file.
*/
private static boolean isDeducibleName(PDOMFile includedFile, char[] name) throws CoreException {
if (includedFile == null) {
return false;
}
else {
rec= includes.getRecord();
String s = includedFile.getLocation().getURI().getPath();
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 {
int rec = linkage.getDB().getInt(record + INCLUDED_BY);
return rec != 0 ? new PDOMFile(linkage, rec) : null;
}
private void setIncludedBy(PDOMFile includedBy) throws CoreException {
int rec = includedBy != null ? includedBy.getRecord() : 0;
linkage.getDB().putInt(record + INCLUDED_BY, rec);
}
public PDOMInclude getNextInIncludes() throws CoreException {
int rec = linkage.getDB().getInt(record + INCLUDES_NEXT);
return rec != 0 ? new PDOMInclude(linkage, rec) : null;
}
public void setNextInIncludes(PDOMInclude include) throws CoreException {
int rec = include != null ? include.getRecord() : 0;
linkage.getDB().putInt(record + INCLUDES_NEXT, rec);
}
public PDOMInclude getNextInIncludedBy() throws CoreException {
int rec = linkage.getDB().getInt(record + INCLUDED_BY_NEXT);
return rec != 0 ? new PDOMInclude(linkage, rec) : null;
}
public void setNextInIncludedBy(PDOMInclude include) throws CoreException {
int rec = include != null ? include.getRecord() : 0;
linkage.getDB().putInt(record + INCLUDED_BY_NEXT, rec);
}
public PDOMInclude getPrevInIncludedBy() throws CoreException {
int rec = getPrevInIncludedByRecord();
return rec != 0 ? new PDOMInclude(linkage, rec) : null;
@ -181,7 +196,7 @@ public class PDOMInclude implements IIndexFragmentInclude {
int getPrevInIncludedByRecord() throws CoreException {
return linkage.getDB().getInt(record + INCLUDED_BY_PREV);
}
public void setPrevInIncludedBy(PDOMInclude include) throws CoreException {
int rec = include != null ? include.getRecord() : 0;
linkage.getDB().putInt(record + INCLUDED_BY_PREV, rec);
@ -192,39 +207,32 @@ public class PDOMInclude implements IIndexFragmentInclude {
}
public IIndexFileLocation getIncludesLocation() throws CoreException {
if (!isResolved()) {
return null;
}
return getIncludes().getLocation();
IIndexFragmentFile includes = getIncludes();
return includes != null ? includes.getLocation() : null;
}
public IIndexFragment getFragment() {
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 {
linkage.getDB().putByte(record + FLAG_OFFSET, flag);
linkage.getDB().putByte(record + FLAGS, flag);
}
private int getFlag() throws CoreException {
return linkage.getDB().getByte(record + FLAG_OFFSET);
return linkage.getDB().getByte(record + FLAGS);
}
public boolean isSystemInclude() throws CoreException {
return (getFlag() & FLAG_SYSTEM_INCLUDE) != 0;
}
public boolean isActive() throws CoreException {
return (getFlag() & FLAG_INACTIVE_INCLUDE) == 0;
}
public boolean isResolved() throws CoreException {
return (getFlag() & FLAG_UNRESOLVED_INCLUDE) == 0;
return linkage.getDB().getInt(record + INCLUDED_FILE) != 0;
}
public boolean isResolvedByHeuristics() throws CoreException {
@ -232,34 +240,45 @@ public class PDOMInclude implements IIndexFragmentInclude {
}
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 {
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) {
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;
}
private void computeName() throws CoreException {
if (isResolved()) {
fName= getIncludes().getLocation().getURI().getPath();
}
else {
fName= getNameForUnresolved().getString();
}
fName= fName.substring(fName.lastIndexOf('/')+1);
public String getName() throws CoreException {
return getFullName().substring(fName.lastIndexOf('/') + 1);
}
public void convertToUnresolved() throws CoreException {
if (isResolved()) {
setIncludes(null, getName().toCharArray());
setFlag((byte) (getFlag() | FLAG_UNRESOLVED_INCLUDE));
final Database db = linkage.getDB();
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);
}
}
}