1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-19 15:05:36 +02:00

Bug 131165 - BinaryContainer.getBinaries sometimes incorrectly returns an empty list

This commit is contained in:
Anton Leherbauer 2010-03-29 09:50:15 +00:00
parent 666817a093
commit b6852ffe40
7 changed files with 148 additions and 35 deletions

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2009 QNX Software Systems and others.
* Copyright (c) 2000, 2010 QNX 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
@ -46,6 +46,7 @@ public class AllCoreTests {
suite.addTest(CModelBuilderInactiveCodeTest.suite());
suite.addTest(FlagTests.suite());
suite.addTest(ArchiveTests.suite());
suite.addTest(BinaryTests.suite());
suite.addTest(TranslationUnitTests.suite());
suite.addTest(DeclaratorsTests.suite());
suite.addTest(MacroTests.suite());

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2007 QNX Software Systems and others.
* Copyright (c) 2000, 2010 QNX 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
@ -18,13 +18,14 @@ import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.ICDescriptor;
import org.eclipse.cdt.core.ICDescriptorOperation;
import org.eclipse.cdt.core.dom.IPDOMManager;
import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.IBinary;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICProject;
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.CTestPlugin;
import org.eclipse.cdt.core.testplugin.util.ExpectedStrings;
@ -33,7 +34,6 @@ import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
@ -73,6 +73,7 @@ public class BinaryTests extends TestCase {
* Example code test the packages in the project
* "com.qnx.tools.ide.cdt.core"
*/
@Override
protected void setUp() throws Exception {
/***
* The tests assume that they have a working workspace
@ -95,17 +96,14 @@ public class BinaryTests extends TestCase {
testProject=CProjectHelper.createCProject("filetest", "none", IPDOMManager.ID_NO_INDEXER);
// since our test require that we can read the debug info from the exe whne must set the GNU elf
// since our test require that we can read the debug info from the exe we must set the GNU elf
// binary parser since the default (generic elf binary parser) does not do this.
ICDescriptorOperation op = new ICDescriptorOperation() {
public void execute(ICDescriptor descriptor, IProgressMonitor monitor) throws CoreException {
descriptor.remove(CCorePlugin.BINARY_PARSER_UNIQ_ID);
descriptor.create(CCorePlugin.BINARY_PARSER_UNIQ_ID, "org.eclipse.cdt.core.GNU_ELF");
}
};
CCorePlugin.getDefault().getCDescriptorManager().runDescriptorOperation(testProject.getProject(), op, null);
ICProjectDescription projDesc = CoreModel.getDefault().getProjectDescription(testProject.getProject(), true);
ICConfigurationDescription defaultConfig = projDesc.getDefaultSettingConfiguration();
defaultConfig.remove(CCorePlugin.BINARY_PARSER_UNIQ_ID);
defaultConfig.create(CCorePlugin.BINARY_PARSER_UNIQ_ID, "org.eclipse.cdt.core.GNU_ELF");
CoreModel.getDefault().setProjectDescription(testProject.getProject(), projDesc);
if (testProject==null)
fail("Unable to create project");
@ -180,6 +178,7 @@ public class BinaryTests extends TestCase {
*
* Called after every test case method.
*/
@Override
protected void tearDown() throws CoreException, InterruptedException {
System.gc();
System.runFinalization();

View file

@ -11,6 +11,7 @@
package org.eclipse.cdt.core.model.tests;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Arrays;
@ -23,9 +24,13 @@ import org.eclipse.cdt.core.CCProjectNature;
import org.eclipse.cdt.core.CProjectNature;
import org.eclipse.cdt.core.dom.IPDOMManager;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ElementChangedEvent;
import org.eclipse.cdt.core.model.IBinaryContainer;
import org.eclipse.cdt.core.model.ICContainer;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICElementDelta;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.IElementChangedListener;
import org.eclipse.cdt.core.model.ISourceRoot;
import org.eclipse.cdt.core.settings.model.COutputEntry;
import org.eclipse.cdt.core.settings.model.CSourceEntry;
@ -43,9 +48,16 @@ import org.eclipse.core.resources.IWorkspaceDescription;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.ui.dialogs.IOverwriteQuery;
import org.eclipse.ui.wizards.datatransfer.FileSystemStructureProvider;
import org.eclipse.ui.wizards.datatransfer.ImportOperation;
import org.osgi.framework.Bundle;
/**
* This file contains a set of generic tests for the core C model. Nothing
@ -474,4 +486,89 @@ public class CModelTests extends TestCase {
}
catch (CoreException e) {}
}
// bug 131165
public void testPickUpBinariesInNewFolder_131165() throws Exception {
ICProject testProject;
testProject = CProjectHelper.createCProject("bug131165", "none", IPDOMManager.ID_NO_INDEXER);
if (testProject == null) {
fail("Unable to create project");
}
CProjectHelper.addDefaultBinaryParser(testProject.getProject());
final IBinaryContainer bin = testProject.getBinaryContainer();
assertEquals(0, bin.getBinaries().length);
final boolean binContainerChanged[] = { false };
IElementChangedListener elementChangedListener = new IElementChangedListener() {
public void elementChanged(ElementChangedEvent event) {
ICElementDelta delta = event.getDelta();
processDelta(delta);
}
private boolean processDelta(ICElementDelta delta) {
if (delta.getElement().equals(bin)) {
synchronized (binContainerChanged) {
binContainerChanged[0] = true;
binContainerChanged.notify();
}
return true;
}
ICElementDelta[] childDeltas = delta.getChangedChildren();
for (ICElementDelta childDelta : childDeltas) {
if (processDelta(childDelta)) {
return true;
}
}
return false;
}
};
CoreModel.getDefault().addElementChangedListener(elementChangedListener );
Thread waiter = new Thread() {
@Override
public void run() {
synchronized (binContainerChanged) {
try {
binContainerChanged.wait(1000);
} catch (InterruptedException exc) {
}
}
}
};
waiter.start();
Thread.sleep(50);
// import with folder structure
importSourcesFromPlugin(testProject, CTestPlugin.getDefault().getBundle(), "resources/exe/x86");
// wait for delta notification
waiter.join(1000);
assertTrue(binContainerChanged[0]);
assertEquals(2, bin.getBinaries().length);
try {
testProject.getProject().delete(true,true,monitor);
}
catch (CoreException e) {}
}
// same as CprojectHelper.importSourcesFromPlugin(), but preserving folder structure
private static void importSourcesFromPlugin(ICProject project, Bundle bundle, String sources) throws CoreException {
try {
String baseDir= FileLocator.toFileURL(FileLocator.find(bundle, new Path(sources), null)).getFile();
ImportOperation importOp = new ImportOperation(project.getProject().getFullPath(),
new File(baseDir), FileSystemStructureProvider.INSTANCE, new IOverwriteQuery() {
public String queryOverwrite(String file) {
return ALL;
}});
importOp.setCreateContainerStructure(true);
importOp.run(new NullProgressMonitor());
}
catch (Exception e) {
throw new CoreException(new Status(IStatus.ERROR, CTestPlugin.PLUGIN_ID, 0, "Import Interrupted", e));
}
}
}

View file

@ -24,7 +24,6 @@ import org.eclipse.cdt.core.internal.tests.ResourceLookupTests;
import org.eclipse.cdt.core.internal.tests.StringBuilderTest;
import org.eclipse.cdt.core.language.AllLanguageTests;
import org.eclipse.cdt.core.model.tests.AllCoreTests;
import org.eclipse.cdt.core.model.tests.BinaryTests;
import org.eclipse.cdt.core.model.tests.ElementDeltaTests;
import org.eclipse.cdt.core.model.tests.WorkingCopyTests;
import org.eclipse.cdt.core.parser.tests.ParserTestSuite;
@ -63,7 +62,6 @@ public class AutomatedIntegrationSuite extends TestSuite {
suite.addTest(ErrorParserTests.suite());
suite.addTest(ParserTestSuite.suite());
suite.addTest(AllCoreTests.suite());
suite.addTest(BinaryTests.suite());
suite.addTest(ElementDeltaTests.suite());
suite.addTest(WorkingCopyTests.suite());
suite.addTest(PositionTrackerTests.suite());

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2005, 2009 IBM Corporation and others.
* Copyright (c) 2005, 2010 IBM Corporation 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
@ -22,7 +22,6 @@ import junit.framework.Assert;
import org.eclipse.cdt.core.CCProjectNature;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.CProjectNature;
import org.eclipse.cdt.core.ICExtensionReference;
import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.IArchive;
@ -34,6 +33,7 @@ import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.ISourceRoot;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.settings.model.ICConfigExtensionReference;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
import org.eclipse.cdt.core.settings.model.ICProjectDescriptionManager;
@ -119,7 +119,7 @@ public class CProjectHelper {
* @throws CoreException
*/
public static boolean addDefaultBinaryParser(IProject project) throws CoreException {
ICExtensionReference[] binaryParsers= CCorePlugin.getDefault().getBinaryParserExtensions(project);
ICConfigExtensionReference[] binaryParsers= CCorePlugin.getDefault().getDefaultBinaryParserExtensions(project);
if (binaryParsers == null || binaryParsers.length == 0) {
ICProjectDescription desc= CCorePlugin.getDefault().getProjectDescription(project);
if (desc == null) {

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2006 QNX Software Systems and others.
* Copyright (c) 2000, 2010 QNX 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
@ -170,6 +170,7 @@ public class CElementDelta implements ICElementDelta {
// child was changed then changed -> it is changed
case CHANGED:
((CElementDelta) existingChild).fChangeFlags |= child.fChangeFlags;
ICElementDelta[] children = child.getAffectedChildren();
for (ICElementDelta element : children) {
CElementDelta childsChild = (CElementDelta) element;

View file

@ -34,8 +34,8 @@ import org.eclipse.core.runtime.IPath;
/**
* This class is used by <code>CModelManager</code> to convert
* <code>IResourceDelta</code>s into <code>ICElementDelta</code>s.
* It also does some processing on the <code>CElement</code>s involved
* (e.g. closing them or updating classpaths).
* It also does some processing on the <code>CElement</code>s involved.
* (e.g. closing them or updating binary containers).
*/
final class DeltaProcessor {
@ -46,7 +46,7 @@ final class DeltaProcessor {
static final ICElementDelta[] NO_DELTA = new ICElementDelta[0];
// Hold on the element bein renamed.
// Hold on the element being renamed.
private ICElement movedFromElement = null;
/**
@ -226,8 +226,8 @@ final class DeltaProcessor {
* Processing for an element that has been added:<ul>
* <li>If the element is a project, do nothing, and do not process
* children, as when a project is created it does not yet have any
* natures - specifically a java nature.
* <li>If the elemet is not a project, process it as added (see
* natures - specifically a C nature.
* <li>If the element is not a project, process it as added (see
* <code>basicElementAdded</code>.
* </ul>
*/
@ -256,8 +256,7 @@ final class DeltaProcessor {
* as a the element being closed (CHANGED + F_CLOSED).
* </ul>
* <p>In both cases, the children of the element are not processed. When
* a resource is closed, the platform reports all children as removed. This
* would effectively delete the classpath if we processed children.
* a resource is closed, the platform reports all children as removed.
*/
protected void elementClosed(ICElement element, IResourceDelta delta) throws CModelException {
@ -333,7 +332,7 @@ final class DeltaProcessor {
protected void elementChanged(ICElement element, IResourceDelta delta) {
// For Binary/Archive We can not call close() to do the work
// closing will remove the element from the {Binary,Archive}Container
// We nee to clear the cache explicitely
// We need to clear the cache explicitly
if (element instanceof IBinary || element instanceof IArchive) {
closeBinary(element);
} else if (element instanceof Openable) {
@ -407,7 +406,7 @@ final class DeltaProcessor {
/**
* Returns true if the given resource is contained in an open project
* with a java nature, otherwise false.
* with a C nature, otherwise false.
*/
protected boolean hasCNature(IResource resource) {
// ensure the project has a C nature (if open)
@ -448,8 +447,8 @@ final class DeltaProcessor {
/**
* Converts an <code>IResourceDelta</code> and its children into
* the corresponding <code>ICElementDelta</code>s.
* Return whether the delta corresponds to a resource on the classpath.
* If it is not a resource on the classpath, it will be added as a non-java
* Return whether the delta corresponds to a C element.
* If it is not a C element, it will be added as a non-C
* resource by the sender of this method.
*/
protected void traverseDelta(ICElement parent, IResourceDelta delta) {
@ -564,7 +563,7 @@ final class DeltaProcessor {
/*
* Update the current delta (ie. add/remove/change the given element) and update the
* correponding index.
* corresponding index.
* Returns whether the children of the given delta must be processed.
* @throws a CModelException if the delta doesn't correspond to a c element of the given type.
*/
@ -576,11 +575,29 @@ final class DeltaProcessor {
case IResourceDelta.ADDED :
if (element != null) {
elementAdded(element, delta);
// no need to traverse further
if (element instanceof ICContainer) {
return ((ICContainer) element).isOpen();
ICContainer container = (ICContainer) element;
ICProject cProject = container.getCProject();
if (cProject.isOnOutputEntry(resource)) {
// if new folder is on output entry there might be new binaries to add
IBinaryContainer bin = cProject.getBinaryContainer();
IArchiveContainer archive = cProject.getArchiveContainer();
// traverse further if a binary container is open
return bin.isOpen() || archive.isOpen();
}
return container.isOpen();
} else if (element instanceof ICProject) {
return ((ICProject) element).isOpen();
} else if (element instanceof IBinary) {
if (((IBinary) element).showInBinaryContainer()) {
ICProject cProject = element.getCProject();
IBinaryContainer bin = cProject.getBinaryContainer();
fCurrentDelta.changed(bin, ICElementDelta.F_CONTENT);
}
} else if (element instanceof IArchive) {
ICProject cProject = element.getCProject();
IArchiveContainer archive = cProject.getArchiveContainer();
fCurrentDelta.changed(archive, ICElementDelta.F_CONTENT);
}
}
return false;