From 0b1492b5c83d5faf8010bebb3ec2608bd0b1b6d2 Mon Sep 17 00:00:00 2001 From: Marc-Andre Laperle Date: Sun, 19 Jul 2020 18:40:33 -0400 Subject: [PATCH] Add leave method to ICElementVisitor to support leaving ICElements This can be used when walking the ICElement tree and wanting to act after visiting all children of an element and the element itself. For example, I use this to collect information about whether or not all files in a folder are excluded or not and when "leaving" the source container, I can then act on whether or not the source exclusions can be simplified by excluding the whole folder. Without the leave() method, one would have to do cumbersome and error-prone path checking when visiting each node to detect if we have left a parent node. Change-Id: Iad480fe18f28db1477d5d527ac51c320f6d280b7 Signed-off-by: Marc-Andre Laperle --- .../cdt/core/model/tests/CModelTests.java | 37 +++++++++++++++++++ .../cdt/core/model/ICElementVisitor.java | 6 +++ .../cdt/internal/core/model/CElement.java | 1 + 3 files changed, 44 insertions(+) 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 8cd92f7767f..43d48513a15 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 @@ -17,6 +17,7 @@ import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -29,6 +30,7 @@ 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.ICElementVisitor; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.IElementChangedListener; import org.eclipse.cdt.core.model.ISourceRoot; @@ -270,6 +272,41 @@ public class CModelTests extends TestCase { assertTrue("Valid C file", CoreModel.isValidTranslationUnitName(null, "areal.c")); } + public void testCElementVisitorLeave() throws Exception { + ICProject testProject; + String projectName = "bug257609"; + testProject = CProjectHelper.createCProject(projectName, "none", IPDOMManager.ID_NO_INDEXER); + + IFolder testFolder = testProject.getProject().getFolder("test"); + testFolder.create(true, true, monitor); + IFolder subFolder1 = testFolder.getFolder("1"); + subFolder1.create(true, true, monitor); + IFolder subFolder2 = testFolder.getFolder("2"); + subFolder2.create(true, true, monitor); + IFolder subFolder3 = subFolder2.getFolder("3"); + subFolder3.create(true, true, monitor); + IFile file0 = testFolder.getFile("test0.c"); + file0.create(new ByteArrayInputStream(new byte[0]), true, monitor); + + List expected = Arrays.asList("visit " + projectName, "visit " + projectName, "visit test", "visit 1", + "leave 1", "visit 2", "visit 3", "leave 3", "leave 2", "visit test0.c", "leave test0.c", "leave test", + "leave " + projectName, "leave " + projectName); + final List actual = new ArrayList<>(); + testProject.accept(new ICElementVisitor() { + @Override + public boolean visit(ICElement element) throws CoreException { + actual.add("visit " + element.getResource().getName()); + return true; + } + + @Override + public void leave(ICElement element) throws CoreException { + actual.add("leave " + element.getResource().getName()); + } + }); + assertEquals(expected, actual); + } + // bug 275609 public void testSourceExclusionFilters_275609() throws Exception { ICProject testProject; diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ICElementVisitor.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ICElementVisitor.java index c4632bc3a07..0542f575591 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ICElementVisitor.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ICElementVisitor.java @@ -26,4 +26,10 @@ public interface ICElementVisitor { */ public boolean visit(ICElement element) throws CoreException; + /** + * Called when leaving a member in the ICElement tree. + * @since 7.0 + */ + public default void leave(ICElement element) throws CoreException { + } } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CElement.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CElement.java index 16e4232e069..088ec6bf7a0 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CElement.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CElement.java @@ -527,6 +527,7 @@ public abstract class CElement extends PlatformObject implements ICElement { children[i].accept(visitor); } } + visitor.leave(this); } @Override