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:
parent
2b18829db8
commit
6d64bcb42a
7 changed files with 172 additions and 108 deletions
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
#include "a/b/I6.h"
|
|
@ -0,0 +1,2 @@
|
|||
#include "b/I6.h"
|
||||
#include "b/I7.h"
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue