1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-09 09:15:38 +02:00

Bug 317435: Change to file-encoding shall trigger index update.

This commit is contained in:
Markus Schorn 2010-06-24 13:01:39 +00:00
parent 5a013d6320
commit 1285350432
12 changed files with 144 additions and 39 deletions

View file

@ -2278,4 +2278,42 @@ public class IndexBugsTests extends BaseTestCase {
index.releaseReadLock();
}
}
public void testUpdateForContentTypeChange_283080() throws Exception {
IIndexBinding[] r;
final IProject prj = fCProject.getProject();
IFile file= TestSourceReader.createFile(prj, "a.cpp", "// \u0110 \n int a;");
file.setCharset("US-ASCII", new NullProgressMonitor());
waitForIndexer(fCProject);
final IIndex index= CCorePlugin.getIndexManager().getIndex(fCProject);
int offset1= 0;
index.acquireReadLock();
try {
r = index.findBindings("a".toCharArray(), IndexFilter.ALL_DECLARED, null);
assertEquals(1, r.length);
IIndexName[] defs = index.findDefinitions(r[0]);
assertEquals(1, defs.length);
offset1= defs[0].getNodeOffset();
} finally {
index.releaseReadLock();
}
file.setCharset("UTF-8", new NullProgressMonitor());
waitForIndexer(fCProject);
int offset2= 0;
index.acquireReadLock();
try {
r = index.findBindings("a".toCharArray(), IndexFilter.ALL_DECLARED, null);
assertEquals(1, r.length);
IIndexName[] defs = index.findDefinitions(r[0]);
assertEquals(1, defs.length);
offset1= defs[0].getNodeOffset();
} finally {
index.releaseReadLock();
}
assertTrue(offset1 != offset2);
}
}

View file

@ -76,6 +76,14 @@ public interface IIndexFile {
*/
int getScannerConfigurationHashcode() throws CoreException;
/**
* Returns the hash-code of the file encoding that was used to parse the file.
* <code>0</code> will be returned in case the hash-code is unknown.
* @return the hash-code of the file encoding or <code>0</code>.
* @since 5.3
*/
int getEncodingHashcode() throws CoreException;
/**
* Find all names within the given range.
*/

View file

@ -83,11 +83,16 @@ public abstract class FileContent {
return InternalParserUtil.createWorkspaceFileContent(file);
}
public static FileContent createForExternalFileLocation(String fileLocation) {
return createForExternalFileLocation(fileLocation, InternalParserUtil.SYSTEM_DEFAULT_ENCODING);
}
/**
* Creates a file content object for a file location that is not part of the workspace
* @since 5.3
*/
public static FileContent createForExternalFileLocation(String fileLocation) {
return InternalParserUtil.createExternalFileContent(fileLocation);
public static FileContent createForExternalFileLocation(String fileLocation, String encoding) {
return InternalParserUtil.createExternalFileContent(fileLocation, encoding);
}
/**

View file

@ -40,6 +40,12 @@ public interface IIndexFragmentFile extends IIndexFile {
*/
void setScannerConfigurationHashcode(int hashcode) throws CoreException;
/**
* Sets the hash-code of the file encoding.
* @param hashcode a hash-code or <code>0</code> if it is unknown.
*/
void setEncodingHashcode(int hashcode) throws CoreException;
/**
* Returns whether this file contains content in its
* associated fragment. Files without content are inserted to track includes.

View file

@ -17,10 +17,10 @@ import java.util.HashMap;
import org.eclipse.cdt.core.index.IIndexFileLocation;
import org.eclipse.cdt.core.model.AbstractLanguage;
import org.eclipse.cdt.core.model.ILanguage;
import org.eclipse.cdt.core.parser.CodeReader;
import org.eclipse.cdt.core.parser.FileContent;
import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.internal.core.index.IndexFileLocation;
import org.eclipse.cdt.internal.core.parser.InternalParserUtil;
import org.eclipse.cdt.internal.core.pdom.IndexerInputAdapter;
import org.eclipse.cdt.internal.core.pdom.indexer.FileExistsCache;
import org.eclipse.core.filesystem.URIUtil;
@ -51,6 +51,16 @@ public class StandaloneIndexerInputAdapter extends IndexerInputAdapter {
return new File(URIUtil.toPath(location.getURI()).toOSString()).lastModified();
}
@Override
public String getEncoding(IIndexFileLocation ifl) {
String encoding= getFileEncoding(getASTPath(ifl));
if (encoding == null)
return InternalParserUtil.SYSTEM_DEFAULT_ENCODING;
return encoding;
}
@Override
public boolean isSourceUnit(Object tu) {
return isValidSourceUnitName((String) tu);
@ -130,24 +140,23 @@ public class StandaloneIndexerInputAdapter extends IndexerInputAdapter {
@Override
public FileContent getCodeReader(Object tu) {
try {
String stu = (String) tu;
String fileEncoding = null;
// query file's encoding, if we find it and use it to create CodeReader
FileEncodingRegistry fileEncodingRegistry = fIndexer.getFileEncodingRegistry();
if(fileEncodingRegistry != null){
fileEncoding = fileEncodingRegistry.getFileEncoding(stu);
}
String stu = (String) tu;
String fileEncoding = getFileEncoding(stu);
if (fileEncoding != null) {
// TODO this is bad
return FileContent.adapt(new CodeReader(stu, fileEncoding));
} else {
return FileContent.createForExternalFileLocation((String) tu);
}
} catch (IOException e) {
return FileContent.createForExternalFileLocation(stu, fileEncoding);
}
public String getFileEncoding(String stu) {
String fileEncoding = null;
// query file's encoding, if we find it and use it to create CodeReader
FileEncodingRegistry fileEncodingRegistry = fIndexer.getFileEncodingRegistry();
if(fileEncodingRegistry != null){
fileEncoding = fileEncodingRegistry.getFileEncoding(stu);
}
return null;
if (fileEncoding == null)
return InternalParserUtil.SYSTEM_DEFAULT_ENCODING;
return fileEncoding;
}
@Override

View file

@ -36,7 +36,7 @@ import org.eclipse.core.runtime.Path;
* Utility for creating code readers
*/
public class InternalParserUtil extends ParserFactory {
private static final String SYSTEM_DEFAULT_ENCODING = System.getProperty("file.encoding"); //$NON-NLS-1$
public static final String SYSTEM_DEFAULT_ENCODING = System.getProperty("file.encoding"); //$NON-NLS-1$
/**
* Normalizes the path by using the location of the file, if possible.
@ -133,7 +133,7 @@ public class InternalParserUtil extends ParserFactory {
if (res instanceof IFile)
return createWorkspaceFileContent((IFile) res);
}
return createExternalFileContent(ifl.getURI().getPath());
return createExternalFileContent(ifl.getURI().getPath(), SYSTEM_DEFAULT_ENCODING);
}
public static InternalFileContent createWorkspaceFileContent(IFile file) {
@ -170,7 +170,7 @@ public class InternalParserUtil extends ParserFactory {
* Creates a code reader for an external location, normalizing path to
* canonical path.
*/
public static InternalFileContent createExternalFileContent(String externalLocation) {
public static InternalFileContent createExternalFileContent(String externalLocation, String encoding) {
File includeFile = new File(externalLocation);
if (includeFile.isFile()) {
// Use the canonical path so that in case of non-case-sensitive OSs
@ -185,7 +185,7 @@ public class InternalParserUtil extends ParserFactory {
return null;
}
try {
return createFileContent(path, SYSTEM_DEFAULT_ENCODING, in);
return createFileContent(path, encoding, in);
} finally {
try {
in.close();

View file

@ -445,13 +445,16 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
private boolean isModified(boolean checkTimestamps, boolean checkFileContentsHash, IIndexFileLocation ifl,
Object tu, IIndexFragmentFile file) throws CoreException {
boolean timestampDifferent = checkTimestamps && fResolver.getLastModified(ifl) != file.getTimestamp();
if (timestampDifferent) {
if (checkFileContentsHash && computeFileContentsHash(tu) == file.getContentsHash()) {
return false;
if (checkTimestamps) {
if (fResolver.getLastModified(ifl) != file.getTimestamp() ||
fResolver.getEncoding(ifl).hashCode() != file.getEncodingHashcode()) {
if (checkFileContentsHash && computeFileContentsHash(tu) == file.getContentsHash()) {
return false;
}
return true;
}
}
return timestampDifferent;
return false;
}
private void requestUpdate(int linkageID, IIndexFileLocation ifl, IIndexFragmentFile ifile) {

View file

@ -70,4 +70,8 @@ public abstract class IndexerInputAdapter extends ASTFilePathResolver {
*/
public abstract FileContent getCodeReader(Object tu);
/**
* Returns the encoding for the file.
*/
public abstract String getEncoding(IIndexFileLocation ifl);
}

View file

@ -193,11 +193,14 @@ public class PDOM extends PlatformObject implements IPDOM {
* 95.0 - parameter packs, bug 294730.
* 96.0 - storing pack expansions in the template parameter map, bug 294730.
* 97.0 - storing file contents hash in PDOMFile, bug 302083.
* 98.0 - strongly typed enums, bug 305975.
* #98.0# - strongly typed enums, bug 305975. <<CDT 7.0.0>>
*
* CDT 8.0 development (versions not supported on the 7.0.x branch)
* 110.0 - update index on encoding change, bug 317435.
*/
private static final int MIN_SUPPORTED_VERSION= version(98, 0);
private static final int MAX_SUPPORTED_VERSION= version(98, Short.MAX_VALUE);
private static final int DEFAULT_VERSION = version(98, 0);
private static final int MIN_SUPPORTED_VERSION= version(110, 0);
private static final int MAX_SUPPORTED_VERSION= version(110, Short.MAX_VALUE);
private static final int DEFAULT_VERSION = version(110, 0);
private static int version(int major, int minor) {
return (major << 16) + minor;

View file

@ -38,6 +38,7 @@ import org.eclipse.cdt.core.dom.ast.ICompositeType;
import org.eclipse.cdt.core.dom.ast.IEnumeration;
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
@ -45,7 +46,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceAlias;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.index.IIndexFileLocation;
import org.eclipse.cdt.core.index.IIndexInclude;
import org.eclipse.cdt.core.parser.IProblem;
@ -461,7 +461,6 @@ abstract public class PDOMWriter {
YieldableIndexLock lock) throws CoreException, InterruptedException {
Set<IIndexFileLocation> clearedContexts= Collections.emptySet();
IIndexFragmentFile file;
long timestamp = fResolver.getLastModified(location);
// We create a temporary PDOMFile with zero timestamp, add names to it, then replace contents
// of the old file from the temporary one, then delete the temporary file. The write lock on
// the index can be yielded between adding names to the temporary file, if another thread
@ -503,7 +502,8 @@ abstract public class PDOMWriter {
}
index.setFileContent(file, linkageID, includeInfos, macros, names, fResolver, lock);
}
file.setTimestamp(timestamp);
file.setTimestamp(fResolver.getLastModified(location));
file.setEncodingHashcode(fResolver.getEncoding(location).hashCode());
file.setContentsHash(fileContentsHash);
file = index.commitUncommittedFile();
} finally {

View file

@ -40,9 +40,9 @@ import org.eclipse.cdt.core.index.IIndexName;
import org.eclipse.cdt.internal.core.index.IIndexFragment;
import org.eclipse.cdt.internal.core.index.IIndexFragmentFile;
import org.eclipse.cdt.internal.core.index.IIndexFragmentName;
import org.eclipse.cdt.internal.core.index.IWritableIndex.IncludeInformation;
import org.eclipse.cdt.internal.core.index.IWritableIndexFragment;
import org.eclipse.cdt.internal.core.index.IndexFileLocation;
import org.eclipse.cdt.internal.core.index.IWritableIndex.IncludeInformation;
import org.eclipse.cdt.internal.core.pdom.PDOM;
import org.eclipse.cdt.internal.core.pdom.YieldableIndexLock;
import org.eclipse.cdt.internal.core.pdom.db.BTree;
@ -73,10 +73,11 @@ public class PDOMFile implements IIndexFragmentFile {
private static final int TIME_STAMP = 24;
private static final int CONTENT_HASH= 32;
private static final int SCANNER_CONFIG_HASH= 40;
private static final int LAST_USING_DIRECTIVE= 44;
private static final int FIRST_MACRO_REFERENCE= 48;
private static final int ENCODING_HASH= 44;
private static final int LAST_USING_DIRECTIVE= 48;
private static final int FIRST_MACRO_REFERENCE= 52;
private static final int RECORD_SIZE= 52;
private static final int RECORD_SIZE= 56;
public static class Comparator implements IBTreeComparator {
private Database db;
@ -224,6 +225,7 @@ public class PDOMFile implements IIndexFragmentFile {
}
setTimestamp(sourceFile.getTimestamp());
setEncodingHashcode(sourceFile.getEncodingHashcode());
setContentsHash(sourceFile.getContentsHash());
setScannerConfigurationHashcode(sourceFile.getScannerConfigurationHashcode());
@ -293,6 +295,16 @@ public class PDOMFile implements IIndexFragmentFile {
db.putInt(record + SCANNER_CONFIG_HASH, hashcode);
}
public int getEncodingHashcode() throws CoreException {
Database db = fLinkage.getDB();
return db.getInt(record + ENCODING_HASH);
}
public void setEncodingHashcode(int hashcode) throws CoreException {
Database db= fLinkage.getDB();
db.putInt(record + ENCODING_HASH, hashcode);
}
private PDOMName getFirstName() throws CoreException {
long namerec = fLinkage.getDB().getRecPtr(record + FIRST_NAME);
return namerec != 0 ? new PDOMName(fLinkage, namerec) : null;

View file

@ -28,8 +28,10 @@ import org.eclipse.cdt.core.model.LanguageManager;
import org.eclipse.cdt.core.parser.FileContent;
import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.core.parser.ScannerInfo;
import org.eclipse.cdt.internal.core.parser.InternalParserUtil;
import org.eclipse.cdt.internal.core.pdom.IndexerInputAdapter;
import org.eclipse.cdt.internal.core.resources.PathCanonicalizationStrategy;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
@ -172,6 +174,21 @@ public class ProjectIndexerInputAdapter extends IndexerInputAdapter {
return 0;
}
@Override
public String getEncoding(IIndexFileLocation ifl) {
String fullPath= ifl.getFullPath();
if (fullPath != null) {
IResource res= ResourcesPlugin.getWorkspace().getRoot().findMember(new Path(fullPath));
if (res instanceof IFile) {
try {
return ((IFile) res).getCharset();
} catch (CoreException e) {
}
}
}
return InternalParserUtil.SYSTEM_DEFAULT_ENCODING;
}
@Override
public AbstractLanguage[] getLanguages(Object tuo, boolean bothForHeaders) {
if (tuo instanceof PotentialTranslationUnit) {