From b6852ffe405c5eb4e3c30ccd1ba2f41070bba565 Mon Sep 17 00:00:00 2001 From: Anton Leherbauer Date: Mon, 29 Mar 2010 09:50:15 +0000 Subject: [PATCH] Bug 131165 - BinaryContainer.getBinaries sometimes incorrectly returns an empty list --- .../cdt/core/model/tests/AllCoreTests.java | 3 +- .../cdt/core/model/tests/BinaryTests.java | 27 +++--- .../cdt/core/model/tests/CModelTests.java | 97 +++++++++++++++++++ .../core/suite/AutomatedIntegrationSuite.java | 2 - .../cdt/core/testplugin/CProjectHelper.java | 6 +- .../internal/core/model/CElementDelta.java | 3 +- .../internal/core/model/DeltaProcessor.java | 45 ++++++--- 7 files changed, 148 insertions(+), 35 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/AllCoreTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/AllCoreTests.java index 256939bad12..ca9c6486a7a 100644 --- a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/AllCoreTests.java +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/AllCoreTests.java @@ -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()); diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/BinaryTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/BinaryTests.java index 737a3fdeac2..d79040b8915 100644 --- a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/BinaryTests.java +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/BinaryTests.java @@ -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(); diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/CModelTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/CModelTests.java index 517a0b3e6d8..9ce6e430ef4 100644 --- a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/CModelTests.java +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/CModelTests.java @@ -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)); + } + } + } diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/suite/AutomatedIntegrationSuite.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/suite/AutomatedIntegrationSuite.java index 43ce793edd0..230dd44980a 100644 --- a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/suite/AutomatedIntegrationSuite.java +++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/suite/AutomatedIntegrationSuite.java @@ -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()); diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/CProjectHelper.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/CProjectHelper.java index 7da40b06b07..080595c0044 100644 --- a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/CProjectHelper.java +++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/CProjectHelper.java @@ -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) { diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CElementDelta.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CElementDelta.java index 11e942b937b..abc9162b7f5 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CElementDelta.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CElementDelta.java @@ -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; diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/DeltaProcessor.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/DeltaProcessor.java index f341a9a5fa8..b91c40f18df 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/DeltaProcessor.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/DeltaProcessor.java @@ -34,8 +34,8 @@ import org.eclipse.core.runtime.IPath; /** * This class is used by CModelManager to convert * IResourceDeltas into ICElementDeltas. - * It also does some processing on the CElements involved - * (e.g. closing them or updating classpaths). + * It also does some processing on the CElements 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: */ @@ -256,8 +256,7 @@ final class DeltaProcessor { * as a the element being closed (CHANGED + F_CLOSED). * *

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 IResourceDelta and its children into * the corresponding ICElementDeltas. - * 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;