diff --git a/languages/DclareMPS/generator/template/main@generator.mps b/languages/DclareMPS/generator/template/main@generator.mps
index 7c5d87ff..24cb1cf0 100644
--- a/languages/DclareMPS/generator/template/main@generator.mps
+++ b/languages/DclareMPS/generator/template/main@generator.mps
@@ -7107,6 +7107,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/languages/DclareMPS/models/constraints.mps b/languages/DclareMPS/models/constraints.mps
index adb7f937..fa0a0eab 100644
--- a/languages/DclareMPS/models/constraints.mps
+++ b/languages/DclareMPS/models/constraints.mps
@@ -265,6 +265,7 @@
+
@@ -6051,5 +6052,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/languages/DclareMPS/models/editor.mps b/languages/DclareMPS/models/editor.mps
index 8abdbd32..f5e7c2cf 100644
--- a/languages/DclareMPS/models/editor.mps
+++ b/languages/DclareMPS/models/editor.mps
@@ -9042,5 +9042,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/languages/DclareMPS/models/structure.mps b/languages/DclareMPS/models/structure.mps
index 60139838..1a082986 100644
--- a/languages/DclareMPS/models/structure.mps
+++ b/languages/DclareMPS/models/structure.mps
@@ -1701,5 +1701,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/languages/DclareMPS/models/typesystem.mps b/languages/DclareMPS/models/typesystem.mps
index 138b8996..d0cab168 100644
--- a/languages/DclareMPS/models/typesystem.mps
+++ b/languages/DclareMPS/models/typesystem.mps
@@ -9044,5 +9044,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/runtime/src/main/java/org/modelingvalue/dclare/mps/DObjectType.java b/runtime/src/main/java/org/modelingvalue/dclare/mps/DObjectType.java
index b165269f..e7292f68 100644
--- a/runtime/src/main/java/org/modelingvalue/dclare/mps/DObjectType.java
+++ b/runtime/src/main/java/org/modelingvalue/dclare/mps/DObjectType.java
@@ -30,9 +30,11 @@
public abstract class DObjectType implements MutableClass {
private static final Constant, Set> TYPE_RULE_SETS = Constant.of("TYPE_RULE_SETS", Set.of(), t -> t.getLanguages().flatMap(DClareMPS.ACTIVE_RULE_SETS::get).toSet());
- private static final Constant, Set> OBSERVERS = Constant.of("OBSERVERS", Set.of(), t -> t.getRules(TYPE_RULE_SETS.get(t)).map(DRule.OBSERVER::get).toSet());
+ private static final Constant, Set> RULES = Constant.of("RULES", Set.of(), t -> t.getRules(TYPE_RULE_SETS.get(t)).toSet());
+ private static final Constant, Set> OBSERVERS = Constant.of("OBSERVERS", Set.of(), t -> RULES.get(t).map(DRule.OBSERVER::get).toSet());
private static final Constant, List> NATIVES = Constant.of("NATIVES", List.of(), t -> t.getNatives(TYPE_RULE_SETS.get(t)).sorted(INative::compare).toList());
- private static final Constant, Set> ATTRIBUTES = Constant.of("ATTRIBUTES", Set.of(), t -> t.getAttributes(TYPE_RULE_SETS.get(t)).toSet());
+ private static final Constant, Set> RULE_LOCALS = Constant.of("RULE_LOCALS", Set.of(), t -> RULES.get(t).map(r -> (DAttribute) DRule.LOCAL_CONTAINER_ATTRIBUTES.get(r)).toSet());
+ private static final Constant, Set> ATTRIBUTES = Constant.of("ATTRIBUTES", Set.of(), t -> t.getAttributes(TYPE_RULE_SETS.get(t)).addAll(RULE_LOCALS.get(t)));
private static final Constant, Set> CONTAINERS = Constant.of("CONTAINERS", Set.of(), t -> ATTRIBUTES.get(t).filter(DAttribute::isComposite).toSet());
private static final Constant, Set> NON_SYNTHETICS = Constant.of("NON_SYNTHETICS", Set.of(), t -> ATTRIBUTES.get(t).filter(a -> !a.isSynthetic()).toSet());
private static final Constant, Set> IDENTIFYING = Constant.of("IDENTIFYING", Set.of(), t -> ATTRIBUTES.get(t).filter(a -> !a.isSynthetic() && a.isIndetifying()).toSet());
diff --git a/runtime/src/main/java/org/modelingvalue/dclare/mps/DRule.java b/runtime/src/main/java/org/modelingvalue/dclare/mps/DRule.java
index 25b95ac7..e4a5746b 100644
--- a/runtime/src/main/java/org/modelingvalue/dclare/mps/DRule.java
+++ b/runtime/src/main/java/org/modelingvalue/dclare/mps/DRule.java
@@ -16,20 +16,41 @@
package org.modelingvalue.dclare.mps;
import org.modelingvalue.collections.Collection;
+import org.modelingvalue.collections.List;
import org.modelingvalue.collections.Set;
import org.modelingvalue.collections.util.Concurrent;
+import org.modelingvalue.collections.util.Context;
+import org.modelingvalue.collections.util.Pair;
import org.modelingvalue.dclare.*;
+import java.util.ArrayList;
+
@SuppressWarnings("rawtypes")
public interface DRule extends DFeature {
- Constant OBSERVER = Constant.of("OBSERVER", DObserver::new);
+ Constant OBSERVER = Constant.of("OBSERVER", DObserver::new);
+ Constant>> LOCAL_CONTAINER_ATTRIBUTES = Constant.of("LOCAL_CONTAINER_ATTRIBUTES", dRule -> new DAttribute.DObservedAttribute<>(dRule, dRule.hashCode() + "", dRule.ruleSet(), false, false, null, Set.class, null, dRule::getSource, SetableModifier.containment, SetableModifier.plumbing));
+ Context> TO_LOCALLY_CONTAIN = Context.of(null);
+
+ static void contain(DObject object) {
+ var tlc = TO_LOCALLY_CONTAIN.get();
+ TO_LOCALLY_CONTAIN.setOnThread((tlc == null ? Set.of() : tlc).add(object));
+ }
class DObserver extends Observer {
@SuppressWarnings("unchecked")
private DObserver(DRule rule) {
- super(rule, rule::run, Collection.of(rule.targets()).toSet(), //
+ super(rule, (obj) -> {
+ TO_LOCALLY_CONTAIN.setOnThread(null);
+ try {
+ rule.run(obj);
+ } finally {
+ LOCAL_CONTAINER_ATTRIBUTES.get(rule).set((DObject) obj, TO_LOCALLY_CONTAIN.get());
+ TO_LOCALLY_CONTAIN.setOnThread(null);
+ }
+ }, //
+ Collection.of(rule.targets()).toSet(), //
rule.initialLowPriority() ? Priority.outer : Priority.immediate, //
IAspect.DIRECTION.get(rule.ruleSet().getAspect()), //
LeafModifier.anonymous.iff(rule.ruleSet().getAnonymousType() != null), //
diff --git a/solutions/DclareMPSRuntime/models/DclareMPSRuntime.util.mps b/solutions/DclareMPSRuntime/models/DclareMPSRuntime.util.mps
index 3fe8d41a..e689c344 100644
--- a/solutions/DclareMPSRuntime/models/DclareMPSRuntime.util.mps
+++ b/solutions/DclareMPSRuntime/models/DclareMPSRuntime.util.mps
@@ -7009,6 +7009,105 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+