diff --git a/HISTORY.md b/HISTORY.md
index 446aa31f..cf31750f 100755
--- a/HISTORY.md
+++ b/HISTORY.md
@@ -49,6 +49,9 @@
* **Translation Updates:**
* German
+### 2022-05-25
+* threads: update programmatic custom block-type changes in data references
+
### 2022-05-23
* blocks: fixed block label color when expanding or inserting variadic infix slots
diff --git a/snap.html b/snap.html
index 14afaf8b..15b12113 100755
--- a/snap.html
+++ b/snap.html
@@ -17,7 +17,7 @@
-
+
diff --git a/src/threads.js b/src/threads.js
index 5a3e073a..2e642b3d 100644
--- a/src/threads.js
+++ b/src/threads.js
@@ -65,7 +65,7 @@ StagePickerMorph, CustomBlockDefinition*/
/*jshint esversion: 11, bitwise: false, evil: true*/
-modules.threads = '2022-May-20';
+modules.threads = '2022-May-25';
var ThreadManager;
var Process;
@@ -5640,6 +5640,7 @@ Process.prototype.doSetBlockAttribute = function (attribute, block, val) {
expr,
def,
template,
+ oldType,
type;
this.assertType(block, types);
@@ -5666,6 +5667,12 @@ Process.prototype.doSetBlockAttribute = function (attribute, block, val) {
}
}
+ function isMajorTypeChange() {
+ var rep = ['reporter', 'predicate'];
+ return (type === 'command' && rep.includes(oldType)) ||
+ (oldType == 'command' && rep.includes(type));
+ }
+
switch (choice) {
case 'label':
def.setBlockLabel(val);
@@ -5698,10 +5705,27 @@ Process.prototype.doSetBlockAttribute = function (attribute, block, val) {
if (rcvr.allBlockInstances(def).every(block =>
block.isChangeableTo(type))
) {
+ oldType = def.type;
def.type = type;
} else {
throw new Error('cannot change this\nfor a block that is in use');
}
+ if (isMajorTypeChange()) {
+ // since we've already scanned all contexts we know that those
+ // that contain block instances only contain single, unattached
+ // ones. Therefore we can simply replace them with new ones.
+ if (def.isGlobal) {
+ ide.stage.allContextsUsing(def).forEach(context =>
+ context.expression = def.blockInstance()
+ );
+ } else {
+ ide.stage.allContextsInvoking(def.blockSpec(), rcvr).forEach(
+ context => context.expression = def.blockInstance()
+ );
+ }
+ }
+
+
break;
case 'scope':
if (isInUse()) {