Bug 468048 - IEclipseContext#setParent only clears direct value computations Change-Id: Id731bf005a866341c758413e28300a6b5ae4c7c2
diff --git a/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/EclipseContext.java b/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/EclipseContext.java index b49debb..0cecde5 100644 --- a/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/EclipseContext.java +++ b/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/EclipseContext.java
@@ -497,12 +497,21 @@ invalidate(name, ContextChangeEvent.ADDED, oldValue, newValue, scheduled); } + invalidateLocalComputations(scheduled); + } + + protected void invalidateLocalComputations(Set<Scheduled> scheduled) { ContextChangeEvent event = new ContextChangeEvent(this, ContextChangeEvent.ADDED, null, null, null); for (Computation computation : localValueComputations.values()) { weakListeners.remove(computation); computation.handleInvalid(event, scheduled); } localValueComputations.clear(); + + // We need to cleanup computations recursively see bug 468048 + for (EclipseContext c : getChildren()) { + c.invalidateLocalComputations(scheduled); + } } private void collectDependentNames(Set<String> usedNames) {
diff --git a/tests/org.eclipse.e4.core.tests/src/org/eclipse/e4/core/internal/tests/contexts/ReparentingTest.java b/tests/org.eclipse.e4.core.tests/src/org/eclipse/e4/core/internal/tests/contexts/ReparentingTest.java index 3781bd3..14092c1 100644 --- a/tests/org.eclipse.e4.core.tests/src/org/eclipse/e4/core/internal/tests/contexts/ReparentingTest.java +++ b/tests/org.eclipse.e4.core.tests/src/org/eclipse/e4/core/internal/tests/contexts/ReparentingTest.java
@@ -11,9 +11,8 @@ package org.eclipse.e4.core.internal.tests.contexts; -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; +import javax.inject.Inject; +import javax.inject.Named; import org.eclipse.e4.core.contexts.ContextFunction; import org.eclipse.e4.core.contexts.ContextInjectionFactory; @@ -22,6 +21,10 @@ import org.eclipse.e4.core.contexts.RunAndTrack; import org.eclipse.e4.core.internal.tests.contexts.inject.ObjectSuperClass; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + /** * Test for changing a context's parent. */ @@ -278,4 +281,64 @@ childContext.setParent(childContext.getParent()); assertEquals(1, testServiceCount[0]); } + + public void testBug468048_contextFunction() { + IEclipseContext p1 = EclipseContextFactory.create("parent1"); + p1.set("sample", new ContextFunction() { + @Override + public Object compute(IEclipseContext context) { + return Integer.valueOf(1); + } + }); + + IEclipseContext p2 = EclipseContextFactory.create("parent2"); + p2.set("sample", new ContextFunction() { + @Override + public Object compute(IEclipseContext context) { + return Integer.valueOf(2); + } + }); + + final IEclipseContext intermed = p1.createChild("intermed"); + + final IEclipseContext leaf = intermed.createChild("leaf"); + assertEquals(Integer.valueOf(1), leaf.get("sample")); + intermed.setParent(p2); + assertEquals(Integer.valueOf(2), leaf.get("sample")); + } + + public void testBug468048_injection() { + IEclipseContext p1 = EclipseContextFactory.create("parent1"); + p1.set("sample", new ContextFunction() { + @Override + public Object compute(IEclipseContext context) { + return Integer.valueOf(1); + } + }); + + IEclipseContext p2 = EclipseContextFactory.create("parent2"); + p2.set("sample", new ContextFunction() { + @Override + public Object compute(IEclipseContext context) { + return Integer.valueOf(2); + } + }); + + final IEclipseContext intermed = p1.createChild("intermed"); + + final IEclipseContext leaf = intermed.createChild("leaf"); + Bug468048 b = ContextInjectionFactory.make(Bug468048.class, leaf); + + assertEquals(Integer.valueOf(1), b.sample); + System.err.println("=========="); + intermed.setParent(p2); + assertEquals(Integer.valueOf(2), b.sample); + } + + public static class Bug468048 { + @Inject + @Named("sample") + public Integer sample; + + } }