diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexIncludeTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexIncludeTest.java index 6e2aef606f8..32a33e813b2 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexIncludeTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexIncludeTest.java @@ -68,6 +68,7 @@ public class IndexIncludeTest extends IndexTestBase { } public void tearDown() throws Exception { + TestScannerProvider.sIncludes= null; super.tearDown(); } @@ -314,4 +315,271 @@ public class IndexIncludeTest extends IndexTestBase { } } + + // #include "resolved20070426.h" + public void testFixedContext() throws Exception { + waitForIndexer(); + TestScannerProvider.sIncludes= new String[]{fProject.getProject().getLocation().toOSString()}; + String source= getContentsForTest(1)[0].toString(); + IFile header= TestSourceReader.createFile(fProject.getProject(), "resolved20070426.h", ""); + IFile s1= TestSourceReader.createFile(fProject.getProject(), "s1.cpp", source); + IFile s2= TestSourceReader.createFile(fProject.getProject(), "s2.cpp", source); + TestSourceReader.waitUntilFileIsIndexed(fIndex, s2, INDEXER_WAIT_TIME); + + fIndex.acquireReadLock(); + try { + IIndexFile ifile= fIndex.getFile(IndexLocationFactory.getWorkspaceIFL(header)); + assertNotNull(ifile); + IIndexInclude[] includes= fIndex.findIncludedBy(ifile); + assertEquals(2, includes.length); + assertEquals(s2.getFullPath().toString(), includes[0].getIncludedByLocation().getFullPath()); + assertEquals(s1.getFullPath().toString(), includes[1].getIncludedByLocation().getFullPath()); + } + finally { + fIndex.releaseReadLock(); + } + + s1= TestSourceReader.createFile(fProject.getProject(), "s1.cpp", source + "\nint a20070426;"); + TestSourceReader.waitUntilFileIsIndexed(fIndex, s1, INDEXER_WAIT_TIME); + fIndex.acquireReadLock(); + try { + assertEquals(1, fIndex.findBindings("a20070426".toCharArray(), IndexFilter.ALL_DECLARED, NPM).length); + IIndexFile ifile= fIndex.getFile(IndexLocationFactory.getWorkspaceIFL(header)); + assertNotNull(ifile); + IIndexInclude[] includes= fIndex.findIncludedBy(ifile); + assertEquals(2, includes.length); + assertEquals(s2.getFullPath().toString(), includes[0].getIncludedByLocation().getFullPath()); + assertEquals(s1.getFullPath().toString(), includes[1].getIncludedByLocation().getFullPath()); + } + finally { + fIndex.releaseReadLock(); + } + + s2= TestSourceReader.createFile(fProject.getProject(), "s2.cpp", source + "\nint b20070426;"); + TestSourceReader.waitUntilFileIsIndexed(fIndex, s1, INDEXER_WAIT_TIME); + fIndex.acquireReadLock(); + try { + assertEquals(1, fIndex.findBindings("b20070426".toCharArray(), IndexFilter.ALL_DECLARED, NPM).length); + IIndexFile ifile= fIndex.getFile(IndexLocationFactory.getWorkspaceIFL(header)); + assertNotNull(ifile); + IIndexInclude[] includes= fIndex.findIncludedBy(ifile); + assertEquals(2, includes.length); + assertEquals(s2.getFullPath().toString(), includes[0].getIncludedByLocation().getFullPath()); + assertEquals(s1.getFullPath().toString(), includes[1].getIncludedByLocation().getFullPath()); + } + finally { + fIndex.releaseReadLock(); + } + } + + // #include "resolved20070427.h" + // #include "unesolved20070427.h" + // #if 0 + // #include "inactive20070427.h" + // #endif + + // #include + // #if 0 + // #include + // #endif + + // #include + // #if 0 + // #include + // #endif + + // #include "resolved20070427.h" + // #include "unesolved20070427.h" + public void testUpdateIncludes() throws Exception { + waitForIndexer(); + TestScannerProvider.sIncludes= new String[]{fProject.getProject().getLocation().toOSString()}; + StringBuffer[] source= getContentsForTest(4); + IFile header= TestSourceReader.createFile(fProject.getProject(), "resolved20070427.h", ""); + IFile s1= TestSourceReader.createFile(fProject.getProject(), "s20070427.cpp", + source[0].toString() + "\nint a20070427;"); + TestSourceReader.waitUntilFileIsIndexed(fIndex, s1, INDEXER_WAIT_TIME); + standardCheckUpdateIncludes(header, s1, "a20070427"); + + s1= TestSourceReader.createFile(fProject.getProject(), "s20070427.cpp", + source[0].toString() + "\nint b20070427;"); + TestSourceReader.waitUntilFileIsIndexed(fIndex, s1, INDEXER_WAIT_TIME); + standardCheckUpdateIncludes(header, s1, "b20070427"); + + s1= TestSourceReader.createFile(fProject.getProject(), "s20070427.cpp", + source[1].toString() + "\nint c20070427;"); + TestSourceReader.waitUntilFileIsIndexed(fIndex, s1, INDEXER_WAIT_TIME); + checkUpdateIncludes1(header, s1, "c20070427"); + + s1= TestSourceReader.createFile(fProject.getProject(), "s20070427.cpp", + source[0].toString() + "\nint d20070427;"); + TestSourceReader.waitUntilFileIsIndexed(fIndex, s1, INDEXER_WAIT_TIME); + standardCheckUpdateIncludes(header, s1, "d20070427"); + + s1= TestSourceReader.createFile(fProject.getProject(), "s20070427.cpp", + source[2].toString() + "\nint e20070427;"); + TestSourceReader.waitUntilFileIsIndexed(fIndex, s1, INDEXER_WAIT_TIME); + checkUpdateIncludes2(header, s1, "e20070427"); + + s1= TestSourceReader.createFile(fProject.getProject(), "s20070427.cpp", + source[0].toString() + "\nint f20070427;"); + TestSourceReader.waitUntilFileIsIndexed(fIndex, s1, INDEXER_WAIT_TIME); + standardCheckUpdateIncludes(header, s1, "f20070427"); + + s1= TestSourceReader.createFile(fProject.getProject(), "s20070427.cpp", + source[3].toString() + "\nint g20070427;"); + TestSourceReader.waitUntilFileIsIndexed(fIndex, s1, INDEXER_WAIT_TIME); + checkUpdateIncludes3(header, s1, "g20070427"); + + s1= TestSourceReader.createFile(fProject.getProject(), "s20070427.cpp", + source[0].toString() + "\nint h20070427;"); + TestSourceReader.waitUntilFileIsIndexed(fIndex, s1, INDEXER_WAIT_TIME); + standardCheckUpdateIncludes(header, s1, "h20070427"); + + } + + private void standardCheckUpdateIncludes(IFile header, IFile s1, String tag) throws Exception { + fIndex.acquireReadLock(); + try { + assertEquals(1, fIndex.findBindings(tag.toCharArray(), IndexFilter.ALL_DECLARED, NPM).length); + + IIndexFile ifile= fIndex.getFile(IndexLocationFactory.getWorkspaceIFL(header)); + IIndexFile sfile= fIndex.getFile(IndexLocationFactory.getWorkspaceIFL(s1)); + assertNotNull(ifile); + IIndexInclude[] includes= fIndex.findIncludedBy(ifile); + assertEquals(1, includes.length); + assertEquals(s1.getFullPath().toString(), includes[0].getIncludedByLocation().getFullPath()); + assertEquals(header.getFullPath().toString(), includes[0].getIncludesLocation().getFullPath()); + assertTrue(includes[0].isActive()); + assertTrue(includes[0].isResolved()); + assertFalse(includes[0].isSystemInclude()); + + assertNotNull(sfile); + includes= fIndex.findIncludes(sfile); + assertEquals(3, includes.length); + assertEquals(header.getFullPath().toString(), includes[0].getIncludesLocation().getFullPath()); + assertEquals(s1.getFullPath().toString(), includes[0].getIncludedByLocation().getFullPath()); + assertTrue(includes[0].isActive()); + assertTrue(includes[0].isResolved()); + assertFalse(includes[0].isSystemInclude()); + + assertNull(includes[1].getIncludesLocation()); + assertEquals(s1.getFullPath().toString(), includes[1].getIncludedByLocation().getFullPath()); + assertTrue(includes[1].isActive()); + assertFalse(includes[1].isResolved()); + assertFalse(includes[1].isSystemInclude()); + + assertNull(includes[2].getIncludesLocation()); + assertEquals(s1.getFullPath().toString(), includes[2].getIncludedByLocation().getFullPath()); + assertFalse(includes[2].isActive()); + assertFalse(includes[2].isResolved()); + assertFalse(includes[2].isSystemInclude()); + } + finally { + fIndex.releaseReadLock(); + } + } + + private void checkUpdateIncludes1(IFile header, IFile s1, String tag) throws Exception { + fIndex.acquireReadLock(); + try { + assertEquals(1, fIndex.findBindings(tag.toCharArray(), IndexFilter.ALL_DECLARED, NPM).length); + + IIndexFile ifile= fIndex.getFile(IndexLocationFactory.getWorkspaceIFL(header)); + IIndexFile sfile= fIndex.getFile(IndexLocationFactory.getWorkspaceIFL(s1)); + assertNotNull(ifile); + IIndexInclude[] includes= fIndex.findIncludedBy(ifile); + assertEquals(0, includes.length); + + assertNotNull(sfile); + includes= fIndex.findIncludes(sfile); + assertEquals(2, includes.length); + + assertNull(includes[0].getIncludesLocation()); + assertEquals(s1.getFullPath().toString(), includes[0].getIncludedByLocation().getFullPath()); + assertTrue(includes[0].isActive()); + assertFalse(includes[0].isResolved()); + assertTrue(includes[0].isSystemInclude()); + + assertNull(includes[1].getIncludesLocation()); + assertEquals(s1.getFullPath().toString(), includes[1].getIncludedByLocation().getFullPath()); + assertFalse(includes[1].isActive()); + assertFalse(includes[1].isResolved()); + assertTrue(includes[1].isSystemInclude()); + } + finally { + fIndex.releaseReadLock(); + } + } + + private void checkUpdateIncludes2(IFile header, IFile s1, String tag) throws Exception { + fIndex.acquireReadLock(); + try { + assertEquals(1, fIndex.findBindings(tag.toCharArray(), IndexFilter.ALL_DECLARED, NPM).length); + + IIndexFile ifile= fIndex.getFile(IndexLocationFactory.getWorkspaceIFL(header)); + IIndexFile sfile= fIndex.getFile(IndexLocationFactory.getWorkspaceIFL(s1)); + assertNotNull(ifile); + IIndexInclude[] includes= fIndex.findIncludedBy(ifile); + assertEquals(1, includes.length); + assertEquals(s1.getFullPath().toString(), includes[0].getIncludedByLocation().getFullPath()); + assertEquals(header.getFullPath().toString(), includes[0].getIncludesLocation().getFullPath()); + assertTrue(includes[0].isActive()); + assertTrue(includes[0].isResolved()); + assertTrue(includes[0].isSystemInclude()); + + assertNotNull(sfile); + includes= fIndex.findIncludes(sfile); + assertEquals(2, includes.length); + assertEquals(header.getFullPath().toString(), includes[0].getIncludesLocation().getFullPath()); + assertEquals(s1.getFullPath().toString(), includes[0].getIncludedByLocation().getFullPath()); + assertTrue(includes[0].isActive()); + assertTrue(includes[0].isResolved()); + assertTrue(includes[0].isSystemInclude()); + + assertNull(includes[1].getIncludesLocation()); + assertEquals(s1.getFullPath().toString(), includes[1].getIncludedByLocation().getFullPath()); + assertFalse(includes[1].isActive()); + assertFalse(includes[1].isResolved()); + assertTrue(includes[1].isSystemInclude()); + } + finally { + fIndex.releaseReadLock(); + } + } + + private void checkUpdateIncludes3(IFile header, IFile s1, String tag) throws Exception { + fIndex.acquireReadLock(); + try { + assertEquals(1, fIndex.findBindings(tag.toCharArray(), IndexFilter.ALL_DECLARED, NPM).length); + + IIndexFile ifile= fIndex.getFile(IndexLocationFactory.getWorkspaceIFL(header)); + IIndexFile sfile= fIndex.getFile(IndexLocationFactory.getWorkspaceIFL(s1)); + assertNotNull(ifile); + IIndexInclude[] includes= fIndex.findIncludedBy(ifile); + assertEquals(1, includes.length); + assertEquals(s1.getFullPath().toString(), includes[0].getIncludedByLocation().getFullPath()); + assertEquals(header.getFullPath().toString(), includes[0].getIncludesLocation().getFullPath()); + assertTrue(includes[0].isActive()); + assertTrue(includes[0].isResolved()); + assertFalse(includes[0].isSystemInclude()); + + assertNotNull(sfile); + includes= fIndex.findIncludes(sfile); + assertEquals(2, includes.length); + assertEquals(header.getFullPath().toString(), includes[0].getIncludesLocation().getFullPath()); + assertEquals(s1.getFullPath().toString(), includes[0].getIncludedByLocation().getFullPath()); + assertTrue(includes[0].isActive()); + assertTrue(includes[0].isResolved()); + assertFalse(includes[0].isSystemInclude()); + + assertNull(includes[1].getIncludesLocation()); + assertEquals(s1.getFullPath().toString(), includes[1].getIncludedByLocation().getFullPath()); + assertTrue(includes[1].isActive()); + assertFalse(includes[1].isResolved()); + assertFalse(includes[1].isSystemInclude()); + } + finally { + fIndex.releaseReadLock(); + } + } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexTestBase.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexTestBase.java index e2be3588268..c328f9b8896 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexTestBase.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexTestBase.java @@ -11,6 +11,8 @@ package org.eclipse.cdt.internal.index.tests; +import java.io.IOException; + import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.IPDOMManager; import org.eclipse.cdt.core.model.ICProject; @@ -26,7 +28,8 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor; public class IndexTestBase extends BaseTestCase { - + protected static int INDEXER_WAIT_TIME= 8000; + public IndexTestBase(String name) { super(name); } @@ -56,4 +59,9 @@ public class IndexTestBase extends BaseTestCase { protected String readTaggedComment(String tag) throws Exception { return TestSourceReader.readTaggedComment(CTestPlugin.getDefault().getBundle(), "parser", getClass(), tag); } + + protected StringBuffer[] getContentsForTest(int blocks) throws IOException { + return TestSourceReader.getContentsForTest( + CTestPlugin.getDefault().getBundle(), "parser", getClass(), getName(), blocks); + } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/TeamSharedIndexTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/TeamSharedIndexTest.java index 1d788dd65c5..3a7dec6d22e 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/TeamSharedIndexTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/TeamSharedIndexTest.java @@ -44,8 +44,6 @@ import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin; public class TeamSharedIndexTest extends IndexTestBase { - private static final int INDEXER_WAIT_TIME = 8000; - public static TestSuite suite() { return suite(TeamSharedIndexTest.class); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexFile.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexFile.java index a0419339fa4..fda4e18d853 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexFile.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexFile.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006 Wind River Systems, Inc. and others. + * Copyright (c) 2006, 2007 Wind River Systems, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -58,6 +58,14 @@ public interface IIndexFile { */ long getTimestamp() throws CoreException; + /** + * Returns the hashcode of the scanner configuration that was used to parse the file. + * 0 will be returned in case the hashcode is unknown. + * @return the hashcode of the scanner configuration or 0. + * @throws CoreException + */ + int getScannerConfigurationHashcode() throws CoreException; + /** * Find all names within the given range. */ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexManager.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexManager.java index f2bf78b4120..d3e76f59bad 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexManager.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexManager.java @@ -67,11 +67,17 @@ public interface IIndexManager extends IPDOMManager { public final static int UPDATE_ALL= 0x1; /** - * Constant for indicating to update translation units only if their timestamp + * Constant for indicating to update translation units if their timestamp * has changed. */ public final static int UPDATE_CHECK_TIMESTAMPS= 0x2; - + + /** + * Constant for indicating to update translation units if their configuration + * has changed. + */ + public final static int UPDATE_CHECK_CONFIGURATION= 0x4; + /** * Returns the index for the given project. * @param project the project to get the index for diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragmentFile.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragmentFile.java index af81c7fafa3..a6f4f575c1a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragmentFile.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragmentFile.java @@ -28,6 +28,13 @@ public interface IIndexFragmentFile extends IIndexFile { */ void setTimestamp(long timestamp) throws CoreException; + /** + * Sets the hashcode of the scanner configuration. + * @param hashcode a hashcode or 0 if it is unknown. + * @throws CoreException + */ + void setScannerConfigurationHashcode(int hashcode) throws CoreException; + /** * Returns whether any names are associated with this file object * in this fragment - i.e. whether this file contains content in its diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IWritableIndex.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IWritableIndex.java index 3ec9b74d083..1a914154b55 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IWritableIndex.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IWritableIndex.java @@ -35,8 +35,6 @@ public interface IWritableIndex extends IIndex { * Adds content to the given file. */ void setFileContent(IIndexFragmentFile sourceFile, - IASTPreprocessorIncludeStatement[] includes, - IIndexFileLocation[] includeLocations, IASTPreprocessorMacroDefinition[] macros, IASTName[][] names) throws CoreException; /** @@ -46,8 +44,10 @@ public interface IWritableIndex extends IIndex { /** * Clears the given file in the index. + * @param newIncludes + * @param newIncludeLocations */ - void clearFile(IIndexFragmentFile file) throws CoreException; + void clearFile(IIndexFragmentFile file, IASTPreprocessorIncludeStatement[] newIncludes, IIndexFileLocation[] newIncludeLocations) throws CoreException; /** * Acquires a write lock, while giving up a certain amount of read locks. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IWritableIndexFragment.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IWritableIndexFragment.java index 33cc5795a06..d27c96146c9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IWritableIndexFragment.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IWritableIndexFragment.java @@ -30,8 +30,10 @@ public interface IWritableIndexFragment extends IIndexFragment { /** * Clears the given file in the index. + * @param newIncludes list of includes to set + * @param destFiles list of file objects for the includes */ - void clearFile(IIndexFragmentFile file) throws CoreException; + void clearFile(IIndexFragmentFile file, IASTPreprocessorIncludeStatement[] newIncludes, IIndexFragmentFile[] destFiles) throws CoreException; /** * Creates a file object for the given location or returns an existing one. @@ -45,7 +47,6 @@ public interface IWritableIndexFragment extends IIndexFragment { * Adds an include to the given file. */ void addFileContent(IIndexFragmentFile sourceFile, - IASTPreprocessorIncludeStatement[] includes, IIndexFragmentFile[] destFiles, IASTPreprocessorMacroDefinition[] macros, IASTName[][] names) throws CoreException; /** diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexBasedCodeReaderFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexBasedCodeReaderFactory.java index ea96e27f142..ae0797c04bb 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexBasedCodeReaderFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexBasedCodeReaderFactory.java @@ -46,7 +46,21 @@ import org.eclipse.core.runtime.CoreException; * */ public class IndexBasedCodeReaderFactory implements ICodeReaderFactory { + public static interface CallbackHandler { + boolean needToUpdate(IndexFileInfo fileInfo) throws CoreException; + } + public static class IndexFileInfo { + public final static int NOT_REQUESTED= 0; + public final static int REQUESTED_IF_CONFIG_CHANGED= 1; + public final static int REQUESTED= 2; + + private IndexFileInfo() {} + private IMacro[] fMacros= null; + public IIndexFile fFile= null; + public int fRequested= 0; + } + private final static boolean CASE_SENSITIVE_FILES= !new File("a").equals(new File("A")); //$NON-NLS-1$//$NON-NLS-2$ private final IIndex index; private Map/**/ fileInfoCache; @@ -55,27 +69,13 @@ public class IndexBasedCodeReaderFactory implements ICodeReaderFactory { private Set/**/ fIncluded= new HashSet(); /** The fallback code reader factory used in case a header file is not indexed */ private ICodeReaderFactory fFallBackFactory; + private CallbackHandler fCallbackHandler; private static final char[] EMPTY_CHARS = new char[0]; private static class NeedToParseException extends Exception { private static final long serialVersionUID = 1L; } - public static class FileInfo { - private FileInfo() {} - public IIndexFile fFile= null; - public IMacro[] fMacros= null; -// public FileInfo[] fFileInfos= null; - private boolean fRequested= false; - - public boolean isRequested() { - return fRequested; - } - public void setRequested(boolean val) { - fRequested= val; - } - } - public IndexBasedCodeReaderFactory(IIndex index) { this(index, new HashMap/**/()); } @@ -120,7 +120,7 @@ public class IndexBasedCodeReaderFactory implements ICodeReaderFactory { } try { IIndexFileLocation incLocation = findLocation(canonicalPath); - FileInfo info= createInfo(incLocation, null); + IndexFileInfo info= createInfo(incLocation, null); if (isIncluded(info)) { return new CodeReader(canonicalPath, EMPTY_CHARS); @@ -132,7 +132,7 @@ public class IndexBasedCodeReaderFactory implements ICodeReaderFactory { LinkedHashSet infos= new LinkedHashSet(); getInfosForMacroDictionary(info, infos); for (Iterator iter = infos.iterator(); iter.hasNext();) { - FileInfo fi = (FileInfo) iter.next(); + IndexFileInfo fi = (IndexFileInfo) iter.next(); if (fi.fMacros == null) { assert fi.fFile != null; IIndexMacro[] macros= fi.fFile.getMacros(); @@ -170,7 +170,7 @@ public class IndexBasedCodeReaderFactory implements ICodeReaderFactory { * Mark the given inclusion as included. * @param info */ - private void setIncluded(FileInfo info) { + private void setIncluded(IndexFileInfo info) { fIncluded.add(info); } @@ -179,38 +179,39 @@ public class IndexBasedCodeReaderFactory implements ICodeReaderFactory { * @param info * @return true if the inclusion is already included. */ - private boolean isIncluded(FileInfo info) { + private boolean isIncluded(IndexFileInfo info) { return fIncluded.contains(info); } - private FileInfo createInfo(IIndexFileLocation location, IIndexFile file) throws CoreException { - FileInfo info= (FileInfo) fileInfoCache.get(location); + private IndexFileInfo createInfo(IIndexFileLocation location, IIndexFile file) throws CoreException { + IndexFileInfo info= (IndexFileInfo) fileInfoCache.get(location); if (info == null) { - info= new FileInfo(); + info= new IndexFileInfo(); info.fFile= file == null ? index.getFile(location) : file; fileInfoCache.put(location, info); } return info; } - private void getInfosForMacroDictionary(FileInfo fileInfo, LinkedHashSet/**/ target) throws CoreException, NeedToParseException { + private void getInfosForMacroDictionary(IndexFileInfo fileInfo, LinkedHashSet/**/ target) throws CoreException, NeedToParseException { if (!target.add(fileInfo)) { return; } if (isIncluded(fileInfo)) { return; } - if (fileInfo.fFile == null || fileInfo.isRequested()) { + final IIndexFile file= fileInfo.fFile; + if (file == null || + (fCallbackHandler != null && fCallbackHandler.needToUpdate(fileInfo))) { throw new NeedToParseException(); } // Follow the includes - IIndexFile file= fileInfo.fFile; IIndexInclude[] includeDirectives= file.getIncludes(); for (int i = 0; i < includeDirectives.length; i++) { IIndexFile includedFile= index.resolveInclude(includeDirectives[i]); if (includedFile != null) { - FileInfo nextInfo= createInfo(includedFile.getLocation(), includedFile); + IndexFileInfo nextInfo= createInfo(includedFile.getLocation(), includedFile); getInfosForMacroDictionary(nextInfo, target); } } @@ -236,7 +237,7 @@ public class IndexBasedCodeReaderFactory implements ICodeReaderFactory { return null; } - public FileInfo createFileInfo(IIndexFileLocation location) throws CoreException { + public IndexFileInfo createFileInfo(IIndexFileLocation location) throws CoreException { return createInfo(location, null); } @@ -246,4 +247,8 @@ public class IndexBasedCodeReaderFactory implements ICodeReaderFactory { } return (IIndexFileLocation) iflCache.get(absolutePath); } + + public void setCallbackHandler(CallbackHandler callbackHandler) { + fCallbackHandler= callbackHandler; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/WritableCIndex.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/WritableCIndex.java index 157d7c13db6..160745cb13f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/WritableCIndex.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/WritableCIndex.java @@ -56,21 +56,12 @@ public class WritableCIndex extends CIndex implements IWritableIndex { } public void setFileContent(IIndexFragmentFile file, - IASTPreprocessorIncludeStatement[] includes, - IIndexFileLocation[] includeLocations, IASTPreprocessorMacroDefinition[] macros, IASTName[][] names) throws CoreException { IIndexFragment indexFragment = file.getIndexFragment(); assert isWritableFragment(indexFragment); - IIndexFragmentFile[] destFiles= new IIndexFragmentFile[includes.length]; - for (int i = 0; i < includes.length; i++) { - if (includeLocations[i] != null) { - destFiles[i]= addFile(includeLocations[i]); - } - } - ((IWritableIndexFragment) indexFragment).addFileContent(file, - includes, destFiles, macros, names); + ((IWritableIndexFragment) indexFragment).addFileContent(file, macros, names); } public void clear() throws CoreException { @@ -80,11 +71,20 @@ public class WritableCIndex extends CIndex implements IWritableIndex { } } - public void clearFile(IIndexFragmentFile file) throws CoreException { + public void clearFile(IIndexFragmentFile file, + IASTPreprocessorIncludeStatement[] newIncludes, + IIndexFileLocation[] newIncludeLocations) throws CoreException { IIndexFragment indexFragment = file.getIndexFragment(); assert isWritableFragment(indexFragment); - ((IWritableIndexFragment) indexFragment).clearFile(file); + IIndexFragmentFile[] destFiles= new IIndexFragmentFile[newIncludes.length]; + for (int i = 0; i < newIncludes.length; i++) { + if (newIncludeLocations[i] != null) { + destFiles[i]= addFile(newIncludeLocations[i]); + } + } + + ((IWritableIndexFragment) indexFragment).clearFile(file, newIncludes, destFiles); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IndexUpdatePolicy.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IndexUpdatePolicy.java index b69a87f807c..08d9224d4d6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IndexUpdatePolicy.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IndexUpdatePolicy.java @@ -16,6 +16,7 @@ import java.util.HashSet; import org.eclipse.cdt.core.dom.IPDOMIndexer; import org.eclipse.cdt.core.dom.IPDOMIndexerTask; import org.eclipse.cdt.core.dom.IPDOMManager; +import org.eclipse.cdt.core.index.IIndexManager; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.internal.core.pdom.indexer.IndexerPreferences; @@ -146,7 +147,7 @@ public class IndexUpdatePolicy { } else if (fIndexer != null) { if (oldPolicy == MANUAL) { - task= new PDOMUpdateTask(fIndexer, true); + task= new PDOMUpdateTask(fIndexer, IIndexManager.UPDATE_CHECK_TIMESTAMPS); clearTUs(); } else if (fKind == POST_CHANGE) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java index 39d2b44b082..d8740588fb3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java @@ -111,6 +111,7 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM { // 32 - support standalone function types (181936) // 33 - templates: constructor instances // 34 - fix for base classes represented by qualified names (183843) + // 35 - add scanner configuration hashcode (62366) public static final int LINKAGES = Database.DATA_AREA; public static final int FILE_INDEX = Database.DATA_AREA + 4; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java index b8609e5a958..acf5f697f5b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java @@ -36,6 +36,7 @@ import org.eclipse.cdt.core.dom.IPDOMManager; import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndexChangeListener; import org.eclipse.cdt.core.index.IIndexLocationConverter; +import org.eclipse.cdt.core.index.IIndexManager; import org.eclipse.cdt.core.index.IIndexerStateListener; import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.CoreModel; @@ -474,7 +475,7 @@ public class PDOMManager implements IWritableIndexManager, IListener { IPDOMIndexerTask task= null; if (operation.wasSuccessful()) { - task= new PDOMUpdateTask(indexer, true); + task= new PDOMUpdateTask(indexer, IIndexManager.UPDATE_CHECK_TIMESTAMPS); } else { task= new PDOMRebuildTask(indexer); @@ -1186,30 +1187,13 @@ public class PDOMManager implements IWritableIndexManager, IListener { } private void update(ICProject project, List filesAndFolders, int options) throws CoreException { - boolean all= false; - boolean timestamps= false; - if ((options & UPDATE_ALL) != 0) { - all= true; - } - else if ((options & UPDATE_CHECK_TIMESTAMPS) != 0) { - timestamps= true; - } - else { - throw new IllegalArgumentException(); - } - - if (all && filesAndFolders.size() == 1 && project.equals(filesAndFolders.get(0))) { - reindex(project); - } - else { - assert !Thread.holdsLock(fProjectToPDOM); - synchronized (fUpdatePolicies) { - IPDOMIndexer indexer= getIndexer(project); - PDOMUpdateTask task= new PDOMUpdateTask(indexer, timestamps); - task.setTranslationUnitSelection(filesAndFolders); - if (indexer != null) { - enqueue(task); - } + assert !Thread.holdsLock(fProjectToPDOM); + synchronized (fUpdatePolicies) { + IPDOMIndexer indexer= getIndexer(project); + PDOMUpdateTask task= new PDOMUpdateTask(indexer, options); + task.setTranslationUnitSelection(filesAndFolders); + if (indexer != null) { + enqueue(task); } } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMWriter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMWriter.java index e513ed7da03..a3c68044314 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMWriter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMWriter.java @@ -49,6 +49,9 @@ import org.eclipse.core.runtime.IProgressMonitor; * @since 4.0 */ abstract public class PDOMWriter { + private static final IASTPreprocessorIncludeStatement[] NO_INCLUDES = {}; + private static final IIndexFileLocation[] NO_LOCATIONS = {}; + public static int SKIP_ALL_REFERENCES= -1; public static int SKIP_TYPE_REFERENCES= 1; public static int SKIP_NO_REFERENCES= 0; @@ -85,7 +88,7 @@ abstract public class PDOMWriter { * @see #addSymbols(IASTTranslationUnit, IWritableIndex, int, IProgressMonitor) * @since 4.0 */ - protected abstract boolean needToUpdate(IIndexFileLocation location) throws CoreException; + protected abstract boolean needToUpdate(IIndexFileLocation location, int confighash) throws CoreException; /** * Called after a file was added to the index. @@ -100,7 +103,7 @@ abstract public class PDOMWriter { * @since 4.0 */ protected abstract IIndexFileLocation findLocation(String absolutePath); - + /** * Extracts symbols from the given ast and adds them to the index. It will * make calls to @@ -110,10 +113,11 @@ abstract public class PDOMWriter { * {@link #findLocation(String)} to obtain further information. * @since 4.0 */ - public void addSymbols(IASTTranslationUnit ast, IWritableIndex index, int readlockCount, IProgressMonitor pm) throws InterruptedException, CoreException { + public void addSymbols(IASTTranslationUnit ast, IWritableIndex index, int readlockCount, int configHash, + IProgressMonitor pm) throws InterruptedException, CoreException { final Map symbolMap= new HashMap(); try { - IIndexFileLocation[] orderedPaths= extractSymbols(ast, symbolMap); + IIndexFileLocation[] orderedPaths= extractSymbols(ast, symbolMap, configHash); for (int i=0; i*/ orderedIFLs= new LinkedHashSet/**/(); ArrayList/**/ iflStack= new ArrayList/**/(); @@ -206,7 +210,7 @@ abstract public class PDOMWriter { final IIndexFileLocation nextIFL= tmpLoc != null ? findLocation(tmpLoc.getFileName()) : astLocation; // command-line includes while (!aboveStackIFL.equals(nextIFL)) { if (!iflStack.isEmpty()) { - if (needToUpdate(aboveStackIFL)) { + if (needToUpdate(aboveStackIFL, confighash)) { prepareInMap(symbolMap, aboveStackIFL); orderedIFLs.add(aboveStackIFL); } @@ -221,7 +225,7 @@ abstract public class PDOMWriter { } // save include in map - if (needToUpdate(nextIFL)) { + if (needToUpdate(nextIFL, confighash)) { prepareInMap(symbolMap, nextIFL); addToMap(symbolMap, 0, nextIFL, include); } @@ -238,7 +242,7 @@ abstract public class PDOMWriter { iflStack.add(aboveStackIFL); while (!iflStack.isEmpty()) { aboveStackIFL= (IIndexFileLocation) iflStack.remove(iflStack.size()-1); - if (needToUpdate(aboveStackIFL)) { + if (needToUpdate(aboveStackIFL, confighash)) { prepareInMap(symbolMap, aboveStackIFL); orderedIFLs.add(aboveStackIFL); } @@ -340,30 +344,36 @@ abstract public class PDOMWriter { return false; } - private IIndexFragmentFile addToIndex(IWritableIndex index, IIndexFileLocation location, Map symbolMap) throws CoreException { - IIndexFragmentFile file= (IIndexFragmentFile) index.getFile(location); - if (file != null) { - index.clearFile(file); - } else { - file= index.addFile(location); - } - file.setTimestamp(getLastModified(location)); + private IIndexFragmentFile addToIndex(IWritableIndex index, IIndexFileLocation location, Map symbolMap, int configHash) throws CoreException { ArrayList[] lists= (ArrayList[]) symbolMap.get(location); + IASTPreprocessorIncludeStatement[] includes= NO_INCLUDES; + IASTPreprocessorMacroDefinition[] macros= null; + IASTName[][] names= null; + IIndexFileLocation[] includeLocations= NO_LOCATIONS; if (lists != null) { ArrayList list= lists[0]; - IASTPreprocessorIncludeStatement[] includes= (IASTPreprocessorIncludeStatement[]) list.toArray(new IASTPreprocessorIncludeStatement[list.size()]); + includes= (IASTPreprocessorIncludeStatement[]) list.toArray(new IASTPreprocessorIncludeStatement[list.size()]); list= lists[1]; - IASTPreprocessorMacroDefinition[] macros= (IASTPreprocessorMacroDefinition[]) list.toArray(new IASTPreprocessorMacroDefinition[list.size()]); + macros= (IASTPreprocessorMacroDefinition[]) list.toArray(new IASTPreprocessorMacroDefinition[list.size()]); list= lists[2]; - IASTName[][] names= (IASTName[][]) list.toArray(new IASTName[list.size()][]); + names= (IASTName[][]) list.toArray(new IASTName[list.size()][]); - IIndexFileLocation[] includeLocations = new IIndexFileLocation[includes.length]; + includeLocations = new IIndexFileLocation[includes.length]; for(int i=0; i0, if unknown. + * @throws CoreException + * @since 4.0 + */ + protected int getScannerConfigurationHashcode(IIndexFileLocation location) throws CoreException { + return 0; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/TeamPDOMImportOperation.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/TeamPDOMImportOperation.java index 30c23587965..ba503c98230 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/TeamPDOMImportOperation.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/TeamPDOMImportOperation.java @@ -30,6 +30,7 @@ import java.util.zip.ZipFile; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.IPDOMIndexerTask; +import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement; import org.eclipse.cdt.core.index.IIndexFileLocation; import org.eclipse.cdt.core.index.IndexLocationFactory; import org.eclipse.cdt.core.model.CoreModel; @@ -60,11 +61,13 @@ import org.eclipse.osgi.util.NLS; public class TeamPDOMImportOperation implements IWorkspaceRunnable { static final String CHECKSUMS_NAME = "checksums.dat"; //$NON-NLS-1$ static final String INDEX_NAME = "cdt-index.pdom"; //$NON-NLS-1$ - private static Pattern PROJECT_VAR_PATTERN= Pattern.compile("\\$\\{(project_[a-zA-Z0-9]*)\\}"); //$NON-NLS-1$ + private static final Pattern PROJECT_VAR_PATTERN= Pattern.compile("\\$\\{(project_[a-zA-Z0-9]*)\\}"); //$NON-NLS-1$ private static final String PROJECT_VAR_REPLACEMENT_BEGIN = "\\${$1:"; //$NON-NLS-1$ private static final String PROJECT_VAR_REPLACEMENT_END = "}"; //$NON-NLS-1$ private static final String DOLLAR_OR_BACKSLASH_REPLACEMENT = "\\\\$0"; //$NON-NLS-1$ - private static Pattern DOLLAR_OR_BACKSLASH_PATTERN= Pattern.compile("[\\$\\\\]"); //$NON-NLS-1$ + private static final IASTPreprocessorIncludeStatement[] NO_INCLUDES = {}; + private static final Pattern DOLLAR_OR_BACKSLASH_PATTERN= Pattern.compile("[\\$\\\\]"); //$NON-NLS-1$ + private static final IIndexFragmentFile[] NO_IDS = {}; private static final class FileAndChecksum { public ITranslationUnit fFile; @@ -265,7 +268,7 @@ public class TeamPDOMImportOperation implements IWorkspaceRunnable { IndexFileLocation ifl = (IndexFileLocation) i.next(); IIndexFragmentFile file= pdom.getFile(ifl); - pdom.clearFile(file); + pdom.clearFile(file, NO_INCLUDES, NO_IDS); } for (Iterator i = updateTimestamps.iterator(); i.hasNext();) { checkMonitor(monitor); @@ -276,6 +279,7 @@ public class TeamPDOMImportOperation implements IWorkspaceRunnable { IResource r= fc.fFile.getResource(); if (r != null) { file.setTimestamp(r.getLocalTimeStamp()); + file.setScannerConfigurationHashcode(0); } } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/WritablePDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/WritablePDOM.java index ef43f4e99f6..f93c9a00e81 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/WritablePDOM.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/WritablePDOM.java @@ -52,20 +52,19 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment { } public void addFileContent(IIndexFragmentFile sourceFile, - IASTPreprocessorIncludeStatement[] includes, IIndexFragmentFile[] destFiles, IASTPreprocessorMacroDefinition[] macros, IASTName[][] names) throws CoreException { assert sourceFile.getIndexFragment() == this; - assert includes.length == destFiles.length; PDOMFile pdomFile = (PDOMFile) sourceFile; - pdomFile.addIncludesTo(destFiles, includes); pdomFile.addMacros(macros); pdomFile.addNames(names); } - public void clearFile(IIndexFragmentFile file) throws CoreException { + public void clearFile(IIndexFragmentFile file, + IASTPreprocessorIncludeStatement[] newIncludes, IIndexFragmentFile[] destFiles) throws CoreException { assert file.getIndexFragment() == this; - ((PDOMFile) file).clear(); + assert newIncludes.length == destFiles.length; + ((PDOMFile) file).clear(newIncludes, destFiles); } public void clear() throws CoreException { @@ -131,7 +130,7 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment { for(Iterator i = notConverted.iterator(); i.hasNext(); ) { PDOMFile file = (PDOMFile) i.next(); file.convertIncludersToUnresolved(); - file.clear(); + file.clear(null, null); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java index 2c052a8046b..cea582844f7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java @@ -12,7 +12,9 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.dom; +import java.lang.reflect.Array; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -55,8 +57,9 @@ public class PDOMFile implements IIndexFragmentFile { private static final int FIRST_MACRO = 12; private static final int LOCATION_REPRESENTATION = 16; private static final int TIME_STAMP = 20; + private static final int SCANNER_CONFIG_HASH= 28; - private static final int RECORD_SIZE = 28; + private static final int RECORD_SIZE = 32; public static class Comparator implements IBTreeComparator { private Database db; @@ -130,6 +133,16 @@ public class PDOMFile implements IIndexFragmentFile { db.putLong(record + TIME_STAMP, timestamp); } + public int getScannerConfigurationHashcode() throws CoreException { + Database db = pdom.getDB(); + return db.getInt(record + SCANNER_CONFIG_HASH); + } + + public void setScannerConfigurationHashcode(int hashcode) throws CoreException { + Database db= pdom.getDB(); + db.putInt(record + SCANNER_CONFIG_HASH, hashcode); + } + public PDOMName getFirstName() throws CoreException { int namerec = pdom.getDB().getInt(record + FIRST_NAME); return namerec != 0 ? new PDOMName(pdom, namerec) : null; @@ -224,15 +237,63 @@ public class PDOMFile implements IIndexFragmentFile { return result; } - public void clear() throws CoreException { - // Remove the includes + public void clear(IASTPreprocessorIncludeStatement[] newIncludes, IIndexFragmentFile[] destFiles) throws CoreException { + int[] records= new int[destFiles.length]; + PDOMInclude[] oldDirectives= new PDOMInclude[destFiles.length]; + for (int i = 0; i < records.length; i++) { + PDOMFile destFile= (PDOMFile) destFiles[i]; + if (destFile != null) { + records[i]= destFile.getRecord(); + } + } + + // Remove the includes preserving the unchanged PDOMInclude include = getFirstInclude(); while (include != null) { PDOMInclude nextInclude = include.getNextInIncludes(); - include.delete(); + final PDOMFile includes= (PDOMFile) include.getIncludes(); + if (includes != null) { + final int rec= includes.record; + int i; + for (i=0; i < records.length; i++) { + if (rec == records[i]) { + records[i]= 0; + oldDirectives[i]= include; + include.setNextInIncludes(null); + break; + } + } + if (i >= records.length) { + include.delete(); + } + } include = nextInclude; } - setFirstInclude(include); + setFirstInclude(null); + + PDOMInclude lastInclude= null; + for (int i = 0; i < newIncludes.length; i++) { + IASTPreprocessorIncludeStatement statement = newIncludes[i]; + PDOMFile targetFile= (PDOMFile) destFiles[i]; + PDOMInclude pdomInclude= oldDirectives[i]; + if (pdomInclude == null) { + pdomInclude= new PDOMInclude(pdom, statement, this, targetFile); + if (targetFile != null) { + assert targetFile.getIndexFragment() instanceof IWritableIndexFragment; + targetFile.addIncludedBy(pdomInclude); + } + } + else { + pdomInclude.update(statement); + } + if (lastInclude == null) { + setFirstInclude(pdomInclude); + } + else { + lastInclude.setNextInIncludes(pdomInclude); + } + lastInclude= pdomInclude; + } // Delete all the macros in this file PDOMMacro macro = getFirstMacro(); @@ -259,30 +320,6 @@ public class PDOMFile implements IIndexFragmentFile { setFirstName(null); } - public void addIncludesTo(IIndexFragmentFile[] files, IASTPreprocessorIncludeStatement[] includes) throws CoreException { - assert files.length == includes.length; - assert getFirstInclude() == null; - - PDOMInclude lastInclude= null; - for (int i = 0; i < includes.length; i++) { - IASTPreprocessorIncludeStatement statement = includes[i]; - PDOMFile targetFile= (PDOMFile) files[i]; - - PDOMInclude pdomInclude = new PDOMInclude(pdom, statement, this, targetFile); - if (targetFile != null) { - assert targetFile.getIndexFragment() instanceof IWritableIndexFragment; - targetFile.addIncludedBy(pdomInclude); - } - if (lastInclude == null) { - setFirstInclude(pdomInclude); - } - else { - lastInclude.setNextInIncludes(pdomInclude); - } - lastInclude= pdomInclude; - } - } - public void addIncludedBy(PDOMInclude include) throws CoreException { PDOMInclude firstIncludedBy = getFirstIncludedBy(); if (firstIncludedBy != null) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMInclude.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMInclude.java index d1afaf9b58a..6bf8e0fc7c9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMInclude.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMInclude.java @@ -72,6 +72,20 @@ public class PDOMInclude implements IIndexFragmentInclude { setIncludes(targetFile, name.toCharArray()); } + public void update(IASTPreprocessorIncludeStatement include) throws CoreException { + IASTName name= include.getName(); + IASTFileLocation loc= name.getFileLocation(); + // includes generated by -include or -macro don't have a location + if (loc != null) { + setNameOffsetAndLength(loc.getNodeOffset(), (short) loc.getNodeLength()); + } + else { + setNameOffsetAndLength(0, (short) 0); + } + + setFlag(encodeFlags(include, false)); + } + private byte encodeFlags(IASTPreprocessorIncludeStatement include, boolean unresolved) { byte flags= 0; if (include.isSystemInclude()) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMIndexerTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMIndexerTask.java index ddff3791b01..0fbf2387cc2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMIndexerTask.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMIndexerTask.java @@ -25,11 +25,13 @@ import java.util.Map; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.IPDOMIndexer; import org.eclipse.cdt.core.dom.IPDOMIndexerTask; +import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndexFile; import org.eclipse.cdt.core.index.IIndexFileLocation; import org.eclipse.cdt.core.index.IIndexInclude; +import org.eclipse.cdt.core.index.IIndexManager; import org.eclipse.cdt.core.index.IndexLocationFactory; import org.eclipse.cdt.core.model.AbstractLanguage; import org.eclipse.cdt.core.model.CoreModel; @@ -39,6 +41,7 @@ import org.eclipse.cdt.core.model.ILanguage; import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.LanguageManager; import org.eclipse.cdt.core.parser.CodeReader; +import org.eclipse.cdt.core.parser.IExtendedScannerInfo; import org.eclipse.cdt.core.parser.IScannerInfo; import org.eclipse.cdt.core.parser.IScannerInfoProvider; import org.eclipse.cdt.core.parser.ScannerInfo; @@ -50,6 +53,7 @@ import org.eclipse.cdt.internal.core.pdom.PDOMWriter; import org.eclipse.cdt.internal.core.pdom.db.ChunkCache; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; @@ -62,12 +66,15 @@ public abstract class PDOMIndexerTask extends PDOMWriter implements IPDOMIndexer private static final Object NO_CONTEXT = new Object(); private static final int MAX_ERRORS = 500; private static final String TRUE = "true"; //$NON-NLS-1$ + private static final IIndexFileLocation[] NO_LOCATIONS= {}; + private static final IASTPreprocessorIncludeStatement[] NO_INCLUDES= {}; private AbstractPDOMIndexer fIndexer; protected Map/**/ fContextMap = new HashMap/**/(); private List fFilesUpFront= new ArrayList(); private String fDummyFileName; private URI fDummyFileURI; + private int fUpdateFlags= IIndexManager.UPDATE_ALL; protected PDOMIndexerTask(AbstractPDOMIndexer indexer) { fIndexer= indexer; @@ -93,7 +100,21 @@ public abstract class PDOMIndexerTask extends PDOMWriter implements IPDOMIndexer return super.getProgressInformation(); } - abstract public void setCheckTimestamps(boolean val); + public void setUpateFlags(int flags) { + fUpdateFlags= flags; + } + + final public boolean updateAll() { + return (fUpdateFlags & IIndexManager.UPDATE_ALL) != 0; + } + + final public boolean updateChangedTimestamps() { + return (fUpdateFlags & IIndexManager.UPDATE_CHECK_TIMESTAMPS) != 0; + } + + final public boolean updateChangedConfiguration() { + return (fUpdateFlags & IIndexManager.UPDATE_CHECK_CONFIGURATION) != 0; + } final public void setParseUpFront() { fFilesUpFront.addAll(Arrays.asList(fIndexer.getFilesToParseUpFront())); @@ -123,7 +144,7 @@ public abstract class PDOMIndexerTask extends PDOMWriter implements IPDOMIndexer return TRUE.equals(getIndexer().getProperty(key)); } - private IASTTranslationUnit createAST(ITranslationUnit tu, int options, IProgressMonitor pm) throws CoreException { + private IASTTranslationUnit createAST(ITranslationUnit tu, IScannerInfo scannerInfo, int options, IProgressMonitor pm) throws CoreException { IPath path = tu.getLocation(); if (path == null) { return null; @@ -132,17 +153,12 @@ public abstract class PDOMIndexerTask extends PDOMWriter implements IPDOMIndexer if (! (language instanceof AbstractLanguage)) return null; - // skip if no scanner info - IScannerInfo scanner= tu.getScannerInfo(getIndexAllFiles()); - if (scanner == null) { - return null; - } CodeReader codeReader = tu.getCodeReader(); if (codeReader == null) { return null; } - return createAST((AbstractLanguage)language, codeReader, scanner, options, pm); + return createAST((AbstractLanguage)language, codeReader, scannerInfo, options, pm); } /** @@ -156,7 +172,7 @@ public abstract class PDOMIndexerTask extends PDOMWriter implements IPDOMIndexer /** * Convenience method for subclasses, parses the files calling out to the methods * {@link #createAST(AbstractLanguage, CodeReader, IScannerInfo, int, IProgressMonitor)}, - * {@link #needToUpdate(IIndexFileLocation)}, + * {@link #needToUpdate(IIndexFileLocation,int)}, * {@link #addSymbols(IASTTranslationUnit, IWritableIndex, int, IProgressMonitor)} * {@link #postAddToIndex(IIndexFileLocation, IIndexFile)}, * {@link #getLastModified(IIndexFileLocation)} and @@ -179,8 +195,8 @@ public abstract class PDOMIndexerTask extends PDOMWriter implements IPDOMIndexer return; ITranslationUnit tu = (ITranslationUnit) iter.next(); final IIndexFileLocation ifl = IndexLocationFactory.getIFL(tu); - if (needToUpdate(ifl)) { - parseTU(tu, options, index, readlockCount, monitor); + if (needToUpdate(ifl, 0)) { + parseTU(ifl, tu, options, index, readlockCount, monitor); } } @@ -189,14 +205,14 @@ public abstract class PDOMIndexerTask extends PDOMWriter implements IPDOMIndexer if (monitor.isCanceled()) return; ITranslationUnit tu = (ITranslationUnit) iter.next(); - IIndexFileLocation location = IndexLocationFactory.getIFL(tu); - if (!needToUpdate(location)) { + final IIndexFileLocation ifl = IndexLocationFactory.getIFL(tu); + if (!needToUpdate(ifl, 0)) { iter.remove(); } else { - ITranslationUnit context= findContext(index, location); + ITranslationUnit context= findContext(index, ifl); if (context != null) { - parseTU(context, options, index, readlockCount, monitor); + parseTU(ifl, context, options, index, readlockCount, monitor); } } } @@ -208,11 +224,11 @@ public abstract class PDOMIndexerTask extends PDOMWriter implements IPDOMIndexer return; ITranslationUnit tu = (ITranslationUnit) iter.next(); final IIndexFileLocation ifl = IndexLocationFactory.getIFL(tu); - if (!needToUpdate(ifl)) { + if (!needToUpdate(ifl, 0)) { iter.remove(); } else { - parseTU(tu, options, index, readlockCount, monitor); + parseTU(ifl, tu, options, index, readlockCount, monitor); } } } @@ -225,32 +241,45 @@ public abstract class PDOMIndexerTask extends PDOMWriter implements IPDOMIndexer * @since 4.0 */ final protected boolean isOutdated(ITranslationUnit tu, IIndexFile indexFile) throws CoreException { - boolean outofdate= true; + if (indexFile == null) { + return true; + } IResource res= tu.getResource(); if (res != null) { if (indexFile != null) { if (res.getLocalTimeStamp() == indexFile.getTimestamp()) { - outofdate= false; + return false; } } + return true; } - return outofdate; + return false; } - private void parseTU(ITranslationUnit tu, int options, IWritableIndex index, int readlockCount, IProgressMonitor pm) throws CoreException, InterruptedException { + private void parseTU(IIndexFileLocation originator, ITranslationUnit tu, int options, IWritableIndex index, int readlockCount, IProgressMonitor pm) throws CoreException, InterruptedException { IPath path= tu.getPath(); try { - if (fShowActivity) { - System.out.println("Indexer: parsing " + path.toOSString()); //$NON-NLS-1$ + // skip if no scanner info + IScannerInfo scanner= tu.getScannerInfo(getIndexAllFiles()); + if (scanner == null) { + updateInfo(0, 0, -1); } - pm.subTask(MessageFormat.format(Messages.PDOMIndexerTask_parsingFileTask, - new Object[]{path.lastSegment(), path.removeLastSegments(1).toString()})); - long start= System.currentTimeMillis(); - IASTTranslationUnit ast= createAST(tu, options, pm); - fStatistics.fParsingTime += System.currentTimeMillis()-start; - if (ast != null) { - addSymbols(ast, index, readlockCount, pm); + else { + final int configHash = computeHashCode(scanner); + if (needToUpdate(originator, configHash)) { + if (fShowActivity) { + System.out.println("Indexer: parsing " + path.toOSString()); //$NON-NLS-1$ + } + pm.subTask(MessageFormat.format(Messages.PDOMIndexerTask_parsingFileTask, + new Object[]{path.lastSegment(), path.removeLastSegments(1).toString()})); + long start= System.currentTimeMillis(); + IASTTranslationUnit ast= createAST(tu, scanner, options, pm); + fStatistics.fParsingTime += System.currentTimeMillis()-start; + if (ast != null) { + addSymbols(ast, index, readlockCount, configHash, pm); + } + } } } catch (CoreException e) { @@ -305,7 +334,7 @@ public abstract class PDOMIndexerTask extends PDOMWriter implements IPDOMIndexer fStatistics.fParsingTime += System.currentTimeMillis()-start; if (ast != null) { - addSymbols(ast, index, readlockCount, pm); + addSymbols(ast, index, readlockCount, 0, pm); updateInfo(-1, +1, 0); } } @@ -329,7 +358,7 @@ public abstract class PDOMIndexerTask extends PDOMWriter implements IPDOMIndexer * } * return false; */ - protected boolean needToUpdate(IIndexFileLocation fileLoc) throws CoreException { + protected boolean needToUpdate(IIndexFileLocation fileLoc, int configHash) throws CoreException { return fDummyFileURI==null || !fDummyFileURI.equals(fileLoc.getURI()); } @@ -356,22 +385,16 @@ public abstract class PDOMIndexerTask extends PDOMWriter implements IPDOMIndexer if (pdomFile != null) { ICProject project= getIndexer().getProject(); IIndexInclude[] includedBy = index.findIncludedBy(pdomFile, IIndex.DEPTH_ZERO); - ArrayList/**/ paths= new ArrayList/**/(includedBy.length); - for (int i = 0; i < includedBy.length; i++) { + for (int i = includedBy.length-1; i >=0; i--) { IIndexInclude include = includedBy[i]; IIndexFileLocation incLocation = include.getIncludedByLocation(); + ITranslationUnit context= null; if (CoreModel.isValidSourceUnitName(project.getProject(), incLocation.getURI().toString())) { // FIXME - is this ok? - ITranslationUnit context = CoreModelUtil.findTranslationUnitForLocation(IndexLocationFactory.getAbsolutePath(incLocation), project); - if (context != null) { - fContextMap.put(location, context); - return context; - } + context = CoreModelUtil.findTranslationUnitForLocation(IndexLocationFactory.getAbsolutePath(incLocation), project); + } + else { + context= findContext(index, incLocation); } - paths.add(incLocation); - } - for (Iterator/**/ iter = paths.iterator(); iter.hasNext();) { - IIndexFileLocation nextLevel = (IIndexFileLocation) iter.next(); - ITranslationUnit context = findContext(index, nextLevel); if (context != null) { fContextMap.put(location, context); return context; @@ -393,7 +416,7 @@ public abstract class PDOMIndexerTask extends PDOMWriter implements IPDOMIndexer try { IIndexFragmentFile file = (IIndexFragmentFile) index.getFile(IndexLocationFactory.getIFL(tu)); if (file != null) - index.clearFile(file); + index.clearFile(file, NO_INCLUDES, NO_LOCATIONS); } finally { index.releaseWriteLock(readlocks); } @@ -449,4 +472,67 @@ public abstract class PDOMIndexerTask extends PDOMWriter implements IPDOMIndexer } } } -} + + protected long getLastModified(IIndexFileLocation location) throws CoreException { + String fullPath= location.getFullPath(); + if (fullPath != null) { + IResource res= ResourcesPlugin.getWorkspace().getRoot().findMember(fullPath); + if (res != null) { + return res.getLocalTimeStamp(); + } + } + return super.getLastModified(location); + } + + protected static int computeHashCode(IScannerInfo scannerInfo) { + int result= 0; + Map macros= scannerInfo.getDefinedSymbols(); + if (macros != null) { + for (Iterator i = macros.entrySet().iterator(); i.hasNext();) { + Map.Entry entry = (Map.Entry) i.next(); + String key = (String) entry.getKey(); + String value = (String) entry.getValue(); + result= addToHashcode(result, key); + if (value != null && value.length() > 0) { + result= addToHashcode(result, value); + } + } + } + String[] a= scannerInfo.getIncludePaths(); + if (a != null) { + for (int i = 0; i < a.length; i++) { + result= addToHashcode(result, a[i]); + + } + } + if (scannerInfo instanceof IExtendedScannerInfo) { + IExtendedScannerInfo esi= (IExtendedScannerInfo) scannerInfo; + a= esi.getIncludeFiles(); + if (a != null) { + for (int i = 0; i < a.length; i++) { + result= addToHashcode(result, a[i]); + + } + } + a= esi.getLocalIncludePath(); + if (a != null) { + for (int i = 0; i < a.length; i++) { + result= addToHashcode(result, a[i]); + + } + } + a= esi.getMacroFiles(); + if (a != null) { + for (int i = 0; i < a.length; i++) { + result= addToHashcode(result, a[i]); + + } + } + } + return result; + } + + private static int addToHashcode(int result, String key) { + return result*31 + key.hashCode(); + } +} \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMRebuildTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMRebuildTask.java index 98fbea2375f..c0cbe77a43c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMRebuildTask.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMRebuildTask.java @@ -18,6 +18,7 @@ import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.IPDOMIndexer; import org.eclipse.cdt.core.dom.IPDOMIndexerTask; import org.eclipse.cdt.core.dom.IPDOMManager; +import org.eclipse.cdt.core.index.IIndexManager; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.internal.core.index.IWritableIndex; @@ -100,7 +101,7 @@ public class PDOMRebuildTask implements IPDOMIndexerTask { ITranslationUnit[] tus= (ITranslationUnit[]) sources.toArray(new ITranslationUnit[sources.size()]); fDelegate= fIndexer.createTask(tus, NO_TUS, NO_TUS); if (fDelegate instanceof PDOMIndexerTask) { - ((PDOMIndexerTask) fDelegate).setCheckTimestamps(true); + ((PDOMIndexerTask) fDelegate).setUpateFlags(IIndexManager.UPDATE_ALL); ((PDOMIndexerTask) fDelegate).setParseUpFront(); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMUpdateTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMUpdateTask.java index 3466e3fd9c8..bc63e88f7d7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMUpdateTask.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMUpdateTask.java @@ -34,14 +34,14 @@ public class PDOMUpdateTask implements IPDOMIndexerTask { private final IPDOMIndexer fIndexer; private final IndexerProgress fProgress; - private final boolean fCheckTimestamps; + private final int fUpdateOptions; private volatile IPDOMIndexerTask fDelegate; private ArrayList fFilesAndFolders= null; - public PDOMUpdateTask(IPDOMIndexer indexer, boolean checkTimestamps) { + public PDOMUpdateTask(IPDOMIndexer indexer, int updateOptions) { fIndexer= indexer; fProgress= createProgress(); - fCheckTimestamps= checkTimestamps; + fUpdateOptions= updateOptions; } private IndexerProgress createProgress() { @@ -90,7 +90,8 @@ public class PDOMUpdateTask implements IPDOMIndexerTask { ITranslationUnit[] tus= (ITranslationUnit[]) set.toArray(new ITranslationUnit[set.size()]); fDelegate= fIndexer.createTask(tus, NO_TUS, NO_TUS); if (fDelegate instanceof PDOMIndexerTask) { - ((PDOMIndexerTask) fDelegate).setCheckTimestamps(fCheckTimestamps); + final PDOMIndexerTask task = (PDOMIndexerTask) fDelegate; + task.setUpateFlags(fUpdateOptions); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/fast/PDOMFastIndexerTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/fast/PDOMFastIndexerTask.java index 5d6c0291f92..68b2e38fc12 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/fast/PDOMFastIndexerTask.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/fast/PDOMFastIndexerTask.java @@ -32,18 +32,19 @@ import org.eclipse.cdt.core.parser.ParserUtil; import org.eclipse.cdt.internal.core.index.IWritableIndex; import org.eclipse.cdt.internal.core.index.IWritableIndexManager; import org.eclipse.cdt.internal.core.index.IndexBasedCodeReaderFactory; -import org.eclipse.cdt.internal.core.index.IndexBasedCodeReaderFactory.FileInfo; +import org.eclipse.cdt.internal.core.index.IndexBasedCodeReaderFactory.CallbackHandler; +import org.eclipse.cdt.internal.core.index.IndexBasedCodeReaderFactory.IndexFileInfo; import org.eclipse.cdt.internal.core.pdom.indexer.PDOMIndexerTask; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; -class PDOMFastIndexerTask extends PDOMIndexerTask { +class PDOMFastIndexerTask extends PDOMIndexerTask implements CallbackHandler { private List fChanged = new ArrayList(); private List fRemoved = new ArrayList(); private IWritableIndex fIndex; private IndexBasedCodeReaderFactory fCodeReaderFactory; private Map fIflCache; - private boolean fCheckTimestamps= false; + private int fCurrentConfigHash= 0; public PDOMFastIndexerTask(PDOMFastIndexer indexer, ITranslationUnit[] added, ITranslationUnit[] changed, ITranslationUnit[] removed) { @@ -103,10 +104,11 @@ class PDOMFastIndexerTask extends PDOMIndexerTask { } private void setupIndexAndReaderFactory() throws CoreException { - this.fIndex= ((IWritableIndexManager) CCorePlugin.getIndexManager()).getWritableIndex(getProject()); - this.fIndex.resetCacheCounters(); - this.fIflCache = new HashMap/**/(); - this.fCodeReaderFactory = new IndexBasedCodeReaderFactory(fIndex, fIflCache); + fIndex= ((IWritableIndexManager) CCorePlugin.getIndexManager()).getWritableIndex(getProject()); + fIndex.resetCacheCounters(); + fIflCache = new HashMap/**/(); + fCodeReaderFactory = new IndexBasedCodeReaderFactory(fIndex, fIflCache); + fCodeReaderFactory.setCallbackHandler(this); } private void registerTUsInReaderFactory() throws CoreException { @@ -114,13 +116,19 @@ class PDOMFastIndexerTask extends PDOMIndexerTask { for (Iterator iter = fChanged.iterator(); iter.hasNext();) { ITranslationUnit tu = (ITranslationUnit) iter.next(); IIndexFileLocation ifl = IndexLocationFactory.getIFL(tu); - FileInfo info= fCodeReaderFactory.createFileInfo(ifl); - if (fCheckTimestamps && !isOutdated(tu, info.fFile)) { - iter.remove(); - removed++; + IndexFileInfo info= fCodeReaderFactory.createFileInfo(ifl); + if (updateAll()) { + info.fRequested= IndexFileInfo.REQUESTED; + } + else if (updateChangedTimestamps() && isOutdated(tu, info.fFile)) { + info.fRequested= IndexFileInfo.REQUESTED; + } + else if (updateChangedConfiguration()) { + info.fRequested= IndexFileInfo.REQUESTED_IF_CONFIG_CHANGED; } else { - info.setRequested(true); + iter.remove(); + removed++; } } updateInfo(0, 0, -removed); @@ -143,31 +151,47 @@ class PDOMFastIndexerTask extends PDOMIndexerTask { } // Clear the macros fCodeReaderFactory.clearMacroAttachements(); - return ast; } - protected boolean needToUpdate(IIndexFileLocation location) throws CoreException { - if (super.needToUpdate(location)) { + protected boolean needToUpdate(IIndexFileLocation location, int confighash) throws CoreException { + if (super.needToUpdate(location, confighash)) { // file is requested or is not yet indexed. - FileInfo info= fCodeReaderFactory.createFileInfo(location); - return info.isRequested() || info.fFile == null; + IndexFileInfo info= fCodeReaderFactory.createFileInfo(location); + return needToUpdate(info, confighash); } return false; } + + public boolean needToUpdate(IndexFileInfo info) throws CoreException { + return needToUpdate(info, fCurrentConfigHash); + } + + private boolean needToUpdate(IndexFileInfo info, int confighash) throws CoreException { + if (info.fFile == null) { + return true; + } + if (confighash != 0 && info.fRequested == IndexFileInfo.REQUESTED_IF_CONFIG_CHANGED) { + int oldhash= info.fFile.getScannerConfigurationHashcode(); + if (oldhash == 0 || oldhash==confighash) { + info.fRequested= IndexFileInfo.NOT_REQUESTED; + updateInfo(0, 0, -1); + } + else { + info.fRequested= IndexFileInfo.REQUESTED; + } + } + return info.fRequested != IndexFileInfo.NOT_REQUESTED; + } protected boolean postAddToIndex(IIndexFileLocation path, IIndexFile file) throws CoreException { - FileInfo info= fCodeReaderFactory.createFileInfo(path); + IndexFileInfo info= fCodeReaderFactory.createFileInfo(path); info.fFile= file; - if (info.isRequested()) { - info.setRequested(false); + if (info.fRequested != IndexFileInfo.NOT_REQUESTED) { + info.fRequested= IndexFileInfo.NOT_REQUESTED; return true; } return false; } - - public void setCheckTimestamps(boolean val) { - fCheckTimestamps= val; - } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullIndexerTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullIndexerTask.java index 83352083ae7..44332fcd02e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullIndexerTask.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullIndexerTask.java @@ -45,13 +45,13 @@ class PDOMFullIndexerTask extends PDOMIndexerTask { private final static Object REQUIRED= new Object(); private final static Object MISSING = new Object(); private final static Object SKIP= new Object(); + private final static Object REQUIRED_IF_CONFIG_CHANGED= new Object(); private List fChanged = new ArrayList(); private List fRemoved = new ArrayList(); private IWritableIndex fIndex = null; private Map filePathsToParse = new HashMap/**/(); private Map fIflCache = new HashMap/**/(); - private boolean fCheckTimestamps= false; public PDOMFullIndexerTask(PDOMFullIndexer indexer, ITranslationUnit[] added, ITranslationUnit[] changed, ITranslationUnit[] removed) { @@ -66,30 +66,18 @@ class PDOMFullIndexerTask extends PDOMIndexerTask { long start = System.currentTimeMillis(); try { setupIndex(); + registerTUsInReaderFactory(fChanged); // separate headers List headers= new ArrayList(); List sources= fChanged; - int removed= 0; for (Iterator iter = fChanged.iterator(); iter.hasNext();) { ITranslationUnit tu = (ITranslationUnit) iter.next(); - if (fCheckTimestamps) { - IIndexFileLocation ifl = IndexLocationFactory.getIFL(tu); - IIndexFile file= fIndex.getFile(ifl); - if (!isOutdated(tu, file)) { - iter.remove(); - removed++; - continue; - } - } if (!tu.isSourceUnit()) { headers.add(tu); iter.remove(); } } - updateInfo(0, 0, -removed); - registerTUsInReaderFactory(sources); - registerTUsInReaderFactory(headers); Iterator i= fRemoved.iterator(); while (i.hasNext()) { @@ -129,10 +117,26 @@ class PDOMFullIndexerTask extends PDOMIndexerTask { private void registerTUsInReaderFactory(Collection/**/ sources) throws CoreException { + int removed= 0; filePathsToParse= new HashMap/**/(); for (Iterator iter = sources.iterator(); iter.hasNext();) { ITranslationUnit tu = (ITranslationUnit) iter.next(); - filePathsToParse.put(IndexLocationFactory.getIFL(tu), REQUIRED); + IIndexFileLocation ifl= IndexLocationFactory.getIFL(tu); + if (updateAll()) { + filePathsToParse.put(ifl, REQUIRED); + } + else if (updateChangedTimestamps() && isOutdated(tu, fIndex.getFile(ifl))) { + filePathsToParse.put(ifl, REQUIRED); + } + else if (updateChangedConfiguration()) { + filePathsToParse.put(ifl, REQUIRED_IF_CONFIG_CHANGED); + } + else { + iter.remove(); + removed++; + continue; + } + updateInfo(0, 0, -removed); } } @@ -154,13 +158,27 @@ class PDOMFullIndexerTask extends PDOMIndexerTask { return ast; } - protected boolean needToUpdate(IIndexFileLocation location) throws CoreException { - if (super.needToUpdate(location)) { + public boolean needToUpdate(IIndexFileLocation location, int confighash) throws CoreException { + if (super.needToUpdate(location, confighash)) { Object required= filePathsToParse.get(location); if (required == null) { required= MISSING; filePathsToParse.put(location, required); } + else if (confighash != 0 && required == REQUIRED_IF_CONFIG_CHANGED) { + IIndexFile file= fIndex.getFile(location); + if (file != null) { + int oldConfig= file.getScannerConfigurationHashcode(); + if (oldConfig == 0 || oldConfig == confighash) { + required= SKIP; + updateInfo(0, 0, -1); + } + else { + required= REQUIRED; + } + filePathsToParse.put(location, required); + } + } return required != SKIP; } return false; @@ -172,8 +190,4 @@ class PDOMFullIndexerTask extends PDOMIndexerTask { filePathsToParse.put(location, SKIP); return required == REQUIRED; } - - public void setCheckTimestamps(boolean val) { - fCheckTimestamps= val; - } } diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/viewsupport/AsyncViewerTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/viewsupport/AsyncViewerTest.java index 0c89d747c22..0893fd26b0b 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/viewsupport/AsyncViewerTest.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/viewsupport/AsyncViewerTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006 Wind River Systems, Inc. and others. + * Copyright (c) 2006, 2007 Wind River Systems, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -114,17 +114,24 @@ public class AsyncViewerTest extends BaseUITestCase { return comp; } } + + private TestDialog fDialog; - public void testSyncPopulation() { - TestDialog dlg = createTestDialog(false); - doTestSyncPopulation(dlg); - dlg.close(); + protected void tearDown() throws Exception { + if (fDialog != null) { + fDialog.close(); + } + super.tearDown(); + } + + public void testSyncPopulation() { + createTestDialog(false); + doTestSyncPopulation(fDialog); } public void testSyncPopulationEx() { - TestDialog dlg = createTestDialog(true); - doTestSyncPopulation(dlg); - dlg.close(); + createTestDialog(true); + doTestSyncPopulation(fDialog); } private void doTestSyncPopulation(TestDialog dlg) { @@ -145,11 +152,10 @@ public class AsyncViewerTest extends BaseUITestCase { assertEquals(3, countVisibleItems(dlg.fViewer)); } - private TestDialog createTestDialog(boolean useExtendedViewer) { - TestDialog dlg= new TestDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), useExtendedViewer); - dlg.setBlockOnOpen(false); - dlg.open(); - return dlg; + private void createTestDialog(boolean useExtendedViewer) { + fDialog= new TestDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), useExtendedViewer); + fDialog.setBlockOnOpen(false); + fDialog.open(); } private int countVisibleItems(TreeViewer viewer) { @@ -168,15 +174,13 @@ public class AsyncViewerTest extends BaseUITestCase { } public void testAsyncPopulation() throws InterruptedException { - TestDialog dlg = createTestDialog(false); - doTestAsyncPopulation(dlg); - dlg.close(); + createTestDialog(false); + doTestAsyncPopulation(fDialog); } public void testAsyncPopulationEx() throws InterruptedException { - TestDialog dlg = createTestDialog(true); - doTestAsyncPopulation(dlg); - dlg.close(); + createTestDialog(true); + doTestAsyncPopulation(fDialog); } private void doTestAsyncPopulation(TestDialog dlg) throws InterruptedException { @@ -252,7 +256,7 @@ public class AsyncViewerTest extends BaseUITestCase { } public void testRecompute() throws InterruptedException { - TestDialog dlg = createTestDialog(true); + createTestDialog(true); Node a,b,c; Node root= new Node("", new Node[] { @@ -264,15 +268,15 @@ public class AsyncViewerTest extends BaseUITestCase { }, 150) }, 0); - dlg.fViewer.setInput(root); runEventQueue(50); - assertEquals(2, countVisibleItems(dlg.fViewer)); + fDialog.fViewer.setInput(root); runEventQueue(50); + assertEquals(2, countVisibleItems(fDialog.fViewer)); - dlg.fContentProvider.recompute(); - assertEquals(2, countVisibleItems(dlg.fViewer)); + fDialog.fContentProvider.recompute(); + assertEquals(2, countVisibleItems(fDialog.fViewer)); - dlg.fViewer.setExpandedState(b, true); + fDialog.fViewer.setExpandedState(b, true); runEventQueue(200); - assertEquals(4, countVisibleItems(dlg.fViewer)); + assertEquals(4, countVisibleItems(fDialog.fViewer)); runEventQueue(200); root.fChildren= new Node[] { @@ -283,24 +287,23 @@ public class AsyncViewerTest extends BaseUITestCase { new Node("d") }, 150) }; - dlg.fContentProvider.recompute(); - assertEquals(3, countVisibleItems(dlg.fViewer)); + fDialog.fContentProvider.recompute(); + assertEquals(3, countVisibleItems(fDialog.fViewer)); runEventQueue(200); - assertEquals(4, countVisibleItems(dlg.fViewer)); + assertEquals(4, countVisibleItems(fDialog.fViewer)); - dlg.fViewer.setExpandedState(c, true); - assertEquals(5, countVisibleItems(dlg.fViewer)); + fDialog.fViewer.setExpandedState(c, true); + assertEquals(5, countVisibleItems(fDialog.fViewer)); runEventQueue(200); - assertEquals(6, countVisibleItems(dlg.fViewer)); + assertEquals(6, countVisibleItems(fDialog.fViewer)); - dlg.fViewer.setSelection(new StructuredSelection(c)); - dlg.fContentProvider.recompute(); + fDialog.fViewer.setSelection(new StructuredSelection(c)); + fDialog.fContentProvider.recompute(); runEventQueue(200); - assertEquals(5, countVisibleItems(dlg.fViewer)); + assertEquals(5, countVisibleItems(fDialog.fViewer)); runEventQueue(200); - assertEquals(6, countVisibleItems(dlg.fViewer)); - assertEquals(1, dlg.fViewer.getTree().getSelectionCount()); - assertEquals("c", dlg.fViewer.getTree().getSelection()[0].getText()); - dlg.close(); + assertEquals(6, countVisibleItems(fDialog.fViewer)); + assertEquals(1, fDialog.fViewer.getTree().getSelectionCount()); + assertEquals("c", fDialog.fViewer.getTree().getSelection()[0].getText()); } } diff --git a/core/org.eclipse.cdt.ui/plugin.xml b/core/org.eclipse.cdt.ui/plugin.xml index e4e82bb1996..d146dddb69a 100644 --- a/core/org.eclipse.cdt.ui/plugin.xml +++ b/core/org.eclipse.cdt.ui/plugin.xml @@ -696,44 +696,71 @@ - + + id="org.eclipse.cdt.ui.cresources.contrib" + objectClass="org.eclipse.cdt.core.model.ICElement"> + + + + + + + + + + + - + menubarPath="org.eclipse.cdt.ui.indexmenu/update"/> - - + + + + + + + + + + + + + + + + + + - - - - -