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:
parent
5a013d6320
commit
1285350432
12 changed files with 144 additions and 39 deletions
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Add table
Reference in a new issue