/*******************************************************************************
* Copyright (c) 2007, 2014 Symbian Software Systems 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Andrew Ferguson (Symbian) - Initial implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.pdom.tests;
import static org.eclipse.cdt.core.testplugin.CProjectHelper.createCCProject;
import java.io.File;
import java.net.URI;
import junit.framework.Test;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.IPDOMManager;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexLocationConverter;
import org.eclipse.cdt.core.index.IIndexManager;
import org.eclipse.cdt.core.index.IndexFilter;
import org.eclipse.cdt.core.index.ResourceContainerRelativeLocationConverter;
import org.eclipse.cdt.core.index.URIRelativeLocationConverter;
import org.eclipse.cdt.core.index.provider.IPDOMDescriptor;
import org.eclipse.cdt.core.index.provider.IReadOnlyPDOMProvider;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.LanguageManager;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
import org.eclipse.cdt.core.testplugin.CProjectHelper;
import org.eclipse.cdt.core.testplugin.util.TestSourceReader;
import org.eclipse.cdt.internal.core.CCoreInternals;
import org.eclipse.cdt.internal.core.index.provider.IndexProviderManager;
import org.eclipse.cdt.internal.core.index.provider.ReadOnlyPDOMProviderBridge;
import org.eclipse.cdt.internal.core.pdom.WritablePDOM;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
/**
* Tests addition of external pdom's into the logical index
*/
public class PDOMProviderTests extends PDOMTestBase {
private static final int A_FRAGMENT_OPTIONS = IIndexManager.ADD_EXTENSION_FRAGMENTS_ADD_IMPORT;
public static Test suite() {
return suite(PDOMProviderTests.class);
}
public void testLifeCycle() throws Exception {
final File tempPDOM= createTempFile("temp", ".pdom");
{
ICProject cproject= createCCProject("foo" + System.currentTimeMillis(), null, IPDOMManager.ID_FAST_INDEXER);
TestSourceReader.createFile(cproject.getProject(), new Path("/this.h"), "class A {};\n\n");
waitForIndexer(cproject);
IIndex index= CCorePlugin.getIndexManager().getIndex(cproject, A_FRAGMENT_OPTIONS);
index.acquireReadLock();
try {
IBinding[] bindings= index.findBindings("A".toCharArray(), IndexFilter.ALL, npm());
assertEquals(1, bindings.length);
} finally {
index.releaseReadLock();
}
ResourceContainerRelativeLocationConverter cvr= new ResourceContainerRelativeLocationConverter(cproject.getProject());
CCoreInternals.getPDOMManager().exportProjectPDOM(cproject, tempPDOM, cvr, null);
assertTrue(tempPDOM.exists());
CProjectHelper.delete(cproject);
}
final URI baseURI= new File("c:/ExternalSDK/").toURI();
final ICProject cproject2= createCCProject("bar" + System.currentTimeMillis(), null, IPDOMManager.ID_FAST_INDEXER);
TestSourceReader.createFile(cproject2.getProject(), new Path("/source.cpp"), "namespace X { class A {}; }\n\n");
waitForIndexer(cproject2);
IndexProviderManager ipm= CCoreInternals.getPDOMManager().getIndexProviderManager();
ipm.addIndexProvider(new ReadOnlyPDOMProviderBridge(
new IReadOnlyPDOMProvider() {
@Override
public IPDOMDescriptor[] getDescriptors(ICConfigurationDescription config) {
return new IPDOMDescriptor[] {
new IPDOMDescriptor() {
@Override
public IIndexLocationConverter getIndexLocationConverter() {
return new URIRelativeLocationConverter(baseURI);
}
@Override
public IPath getLocation() {
return new Path(tempPDOM.getAbsolutePath());
}
}
};
}
@Override
public boolean providesFor(ICProject project) throws CoreException {
return cproject2.equals(project);
}
}
));
IIndex index= CCorePlugin.getIndexManager().getIndex(cproject2, A_FRAGMENT_OPTIONS);
index.acquireReadLock();
try {
IBinding[] bindings= index.findBindings("A".toCharArray(), IndexFilter.ALL, npm());
assertEquals(1, bindings.length);
bindings= index.findBindingsForPrefix("A".toCharArray(), false, new IndexFilter() {
@Override
public boolean acceptBinding(IBinding binding) {
return binding instanceof ICPPClassType;
}
}, null);
assertEquals(2, bindings.length);
} finally {
index.releaseReadLock();
}
}
public void testCommonSDK() throws Exception {
final File tempPDOM= createTempFile("temp", ".pdom");
{
ICProject cproject= createCCProject("foo" + System.currentTimeMillis(), null, IPDOMManager.ID_FAST_INDEXER);
TestSourceReader.createFile(cproject.getProject(), new Path("/this.h"), "class A {};\n\n");
waitForIndexer(cproject);
IIndex index= CCorePlugin.getIndexManager().getIndex(cproject, A_FRAGMENT_OPTIONS);
index.acquireReadLock();
try {
IBinding[] bindings= index.findBindings("A".toCharArray(), IndexFilter.ALL, npm());
assertEquals(1, bindings.length);
} finally {
index.releaseReadLock();
}
ResourceContainerRelativeLocationConverter cvr= new ResourceContainerRelativeLocationConverter(cproject.getProject());
CCoreInternals.getPDOMManager().exportProjectPDOM(cproject, tempPDOM, cvr, null);
assertTrue(tempPDOM.exists());
CProjectHelper.delete(cproject);
}
final ICProject cproject3= createCCProject("bar" + System.currentTimeMillis(), null, IPDOMManager.ID_FAST_INDEXER);
TestSourceReader.createFile(cproject3.getProject(), new Path("/source.cpp"), "namespace Y { class A {}; }\n\n");
waitForIndexer(cproject3);
final URI baseURI= new File("c:/ExternalSDK/").toURI();
final ICProject cproject2= createCCProject("baz" + System.currentTimeMillis(), null, IPDOMManager.ID_FAST_INDEXER);
TestSourceReader.createFile(cproject2.getProject(), new Path("/source.cpp"), "namespace X { class A {}; }\n\n");
waitForIndexer(cproject2);
IndexProviderManager ipm= CCoreInternals.getPDOMManager().getIndexProviderManager();
ipm.addIndexProvider(new ReadOnlyPDOMProviderBridge(
new IReadOnlyPDOMProvider() {
@Override
public IPDOMDescriptor[] getDescriptors(ICConfigurationDescription config) {
return new IPDOMDescriptor[] {
new IPDOMDescriptor() {
@Override
public IIndexLocationConverter getIndexLocationConverter() {
return new URIRelativeLocationConverter(baseURI);
}
@Override
public IPath getLocation() {
return new Path(tempPDOM.getAbsolutePath());
}
}
};
}
@Override
public boolean providesFor(ICProject project) throws CoreException {
return cproject2.equals(project) || cproject3.equals(project);
}
}
));
{
IIndex index= CCorePlugin.getIndexManager().getIndex(cproject2, A_FRAGMENT_OPTIONS);
index.acquireReadLock();
try {
IBinding[] bindings= index.findBindings("A".toCharArray(), IndexFilter.ALL, npm());
assertEquals(1, bindings.length);
assertEquals(1, index.findDefinitions(bindings[0]).length);
bindings= index.findBindingsForPrefix("A".toCharArray(), false, new IndexFilter() {
@Override
public boolean acceptBinding(IBinding binding) {
return binding instanceof ICPPClassType;
}
}, null);
assertEquals(2, bindings.length);
} finally {
index.releaseReadLock();
}
}
{
IIndex index= CCorePlugin.getIndexManager().getIndex(cproject3, A_FRAGMENT_OPTIONS);
index.acquireReadLock();
try {
IBinding[] bindings= index.findBindings("A".toCharArray(), IndexFilter.ALL, npm());
assertEquals(1, bindings.length);
assertEquals(1, index.findDefinitions(bindings[0]).length);
bindings= index.findBindingsForPrefix("A".toCharArray(), false, new IndexFilter() {
@Override
public boolean acceptBinding(IBinding binding) {
return binding instanceof ICPPClassType;
}
}, null);
assertEquals(2, bindings.length);
} finally {
index.releaseReadLock();
}
}
{
IIndex index= CCorePlugin.getIndexManager().getIndex(new ICProject[]{cproject2, cproject3}, A_FRAGMENT_OPTIONS);
index.acquireReadLock();
try {
IBinding[] bindings= index.findBindings("A".toCharArray(), IndexFilter.ALL, npm());
assertEquals(1, bindings.length);
assertEquals(1, index.findDefinitions(bindings[0]).length);
bindings= index.findBindingsForPrefix("A".toCharArray(), false, new IndexFilter() {
@Override
public boolean acceptBinding(IBinding binding) {
return binding instanceof ICPPClassType;
}
}, null);
assertEquals(3, bindings.length);
} finally {
index.releaseReadLock();
}
}
}
public void testVersionMismatchOfExternalPDOM_178998() throws Exception {
final File tempPDOM= createTempFile("temp", ".pdom");
{
ICProject cproject= createCCProject("foo" + System.currentTimeMillis(), null, IPDOMManager.ID_FAST_INDEXER);
TestSourceReader.createFile(cproject.getProject(), new Path("/this.h"), "class A {};\n\n");
waitForIndexer(cproject);
ResourceContainerRelativeLocationConverter cvr= new ResourceContainerRelativeLocationConverter(cproject.getProject());
CCoreInternals.getPDOMManager().exportProjectPDOM(cproject, tempPDOM, cvr, null);
CProjectHelper.delete(cproject);
// Mimic a PDOM with superseded version.
WritablePDOM wpdom= new WritablePDOM(tempPDOM, cvr, LanguageManager.getInstance().getPDOMLinkageFactoryMappings());
wpdom.acquireWriteLock(null);
try {
wpdom.getDB().setVersion(1);
wpdom.close();
} finally {
wpdom.releaseWriteLock();
}
}
final URI baseURI= new File("c:/ExternalSDK/").toURI();
final ICProject cproject2=
createCCProject("baz" + System.currentTimeMillis(), null, IPDOMManager.ID_FAST_INDEXER);
TestSourceReader.createFile(cproject2.getProject(), new Path("/source.cpp"), "namespace X { class A {}; }\n\n");
waitForIndexer(cproject2);
IndexProviderManager ipm= CCoreInternals.getPDOMManager().getIndexProviderManager();
ipm.addIndexProvider(new ReadOnlyPDOMProviderBridge(
new IReadOnlyPDOMProvider() {
@Override
public IPDOMDescriptor[] getDescriptors(ICConfigurationDescription config) {
return new IPDOMDescriptor[] {
new IPDOMDescriptor() {
@Override
public IIndexLocationConverter getIndexLocationConverter() {
return new URIRelativeLocationConverter(baseURI);
}
@Override
public IPath getLocation() {
return new Path(tempPDOM.getAbsolutePath());
}
}
};
}
@Override
public boolean providesFor(ICProject project) throws CoreException {
return cproject2.equals(project);
}
}
));
setExpectedNumberOfLoggedNonOKStatusObjects(1); // (this applies to the entire test duration)
for (int i= 0; i < 3; i++) {
// Try several times in order to test the status is logged only once.
ICProjectDescription pd= CCorePlugin.getDefault().getProjectDescription(cproject2.getProject(), false);
assertEquals(0, ipm.getProvidedIndexFragments(pd.getActiveConfiguration(), -1).length);
}
}
}