find message sends in global custom blocks dependencies

"transitive hull" search
pull/95/head
jmoenig 2020-09-03 20:21:00 +02:00
rodzic ebc00e0d79
commit 2ab96c76e2
5 zmienionych plików z 67 dodań i 8 usunięć

Wyświetl plik

@ -14,6 +14,7 @@
### 2020-09-03
* byob: experimental: Inspect & export dependencies for global custom blocks (shift-right-click for context menu)
* byob: new feature: "export block definition" including dependencies
* blocks, byob, objects: find message sends in global custom blocks dependencies
### 2020-09-02
* threads: hyperized "distance/direction to _" reporter primitive

Wyświetl plik

@ -8,9 +8,9 @@
<script src="src/morphic.js?version=2020-07-23"></script>
<script src="src/symbols.js?version=2020-07-21"></script>
<script src="src/widgets.js?version=2020-07-27"></script>
<script src="src/blocks.js?version=2020-09-01"></script>
<script src="src/blocks.js?version=2020-09-03"></script>
<script src="src/threads.js?version=2020-09-02"></script>
<script src="src/objects.js?version=2020-09-01"></script>
<script src="src/objects.js?version=2020-09-03"></script>
<script src="src/gui.js?version=2020-09-01"></script>
<script src="src/paint.js?version=2020-05-17"></script>
<script src="src/lists.js?version=2020-07-01"></script>

Wyświetl plik

@ -158,7 +158,7 @@ CustomCommandBlockMorph, SymbolMorph, ToggleButtonMorph, DialMorph*/
// Global stuff ////////////////////////////////////////////////////////
modules.blocks = '2020-September-01';
modules.blocks = '2020-September-03';
var SyntaxElementMorph;
var BlockMorph;
@ -3135,7 +3135,7 @@ BlockMorph.prototype.showMessageUsers = function () {
getter = (this.selector.indexOf('receive') === 0) ?
'allSendersOf' : 'allHatBlocksFor',
inputs = this.inputs(),
message, receiverName;
message, receiverName, knownSenders;
if (this.selector === 'receiveGo') {
message = '__shout__go__';
@ -3152,11 +3152,19 @@ BlockMorph.prototype.showMessageUsers = function () {
}
if (message !== '') {
if (getter === 'allSendersOf') {
knownSenders = ide.stage.globalBlocksSending(message, receiverName);
}
corral.frame.contents.children.concat(corral.stageIcon).forEach(
icon => {
if (icon.object &&
((this.selector !== 'doSend' || receiverName === icon.object.name) &&
(icon.object[getter](message, receiverName).length > 0))
((this.selector !== 'doSend' ||
receiverName === icon.object.name) &&
(icon.object[getter](
message,
receiverName,
knownSenders
).length > 0))
) {
icon.flash();
}

Wyświetl plik

@ -588,6 +588,35 @@ CustomBlockDefinition.prototype.collectDependencies = function (
return result;
};
CustomBlockDefinition.prototype.isSending = function (message, receiverName) {
if (typeof message === 'number') {
message = message.toString();
}
return this.scripts.concat(
this.body ? [this.body.expression] : []
).some(script =>
script.allChildren().some(morph => {
var event, eventReceiver;
if ((morph.selector) &&
contains(
['doBroadcast', 'doBroadcastAndWait', 'doSend'],
morph.selector)
) {
event = morph.inputs()[0].evaluate();
if (morph.selector === 'doSend') {
eventReceiver = morph.inputs()[1].evaluate();
}
return ((morph.selector !== 'doSend') ||
(receiverName === eventReceiver)) &&
((event === message) ||
(message instanceof Array &&
message[0] === 'any message'));
}
return false;
})
);
};
// CustomCommandBlockMorph /////////////////////////////////////////////
// CustomCommandBlockMorph inherits from CommandBlockMorph:

Wyświetl plik

@ -84,7 +84,7 @@ BlockEditorMorph, BlockDialogMorph, PrototypeHatBlockMorph, BooleanSlotMorph,
localize, TableMorph, TableFrameMorph, normalizeCanvas, VectorPaintEditorMorph,
HandleMorph, AlignmentMorph, Process, XML_Element, WorldMap, copyCanvas*/
modules.objects = '2020-September-01';
modules.objects = '2020-September-03';
var SpriteMorph;
var StageMorph;
@ -5773,13 +5773,19 @@ SpriteMorph.prototype.allMessageNames = function () {
return msgs;
};
SpriteMorph.prototype.allSendersOf = function (message, receiverName) {
SpriteMorph.prototype.allSendersOf = function (message, receiverName, known) {
if (typeof message === 'number') {
message = message.toString();
}
return this.allScripts().filter(script =>
script.allChildren().some(morph => {
var event, eventReceiver;
if (morph.isCustomBlock &&
morph.isGlobal &&
contains(known, morph.definition)
) {
return true;
}
if ((morph.selector) &&
contains(
['doBroadcast', 'doBroadcastAndWait', 'doSend'],
@ -9354,6 +9360,21 @@ StageMorph.prototype.reportPenTrailsAsCostume = function () {
);
};
// StageMorph scanning global custom blocks for message sends
StageMorph.prototype.globalBlocksSending = function (message, receiverName) {
// "transitive hull"
var all = this.globalBlocks.filter(
def =>def.isSending(message, receiverName)
);
this.globalBlocks.forEach(def => {
if (def.collectDependencies().some(dep => contains(all, dep))) {
all.push(def);
}
});
return all;
};
// SpriteBubbleMorph ////////////////////////////////////////////////////////
/*