Marcel Taeumel uploaded a new version of Tools to project The Trunk:
http://source.squeak.org/trunk/Tools-mt.1048.mcz
==================== Summary ====================
Name: Tools-mt.1048
Author: mt
Time: 29 April 2021, 6:14:12.930356 pm
UUID: 14815123-219f-0b41-a441-c56e1392000f
Ancestors: Tools-mt.1047
Fixes selection update after removing a whole class from the current change-set.
=============== Diff against Tools-mt.1047 ===============
Item was changed:
----- Method: ChangeSorter>>forgetClass (in category 'class list') -----
forgetClass
"Remove all mention of this class from the changeSet.
After forgetting, select at the same point in the class
list, which helps if e.g. doing something repetitive such
as moving a number of classes to the other side."
| index classList |
self okToChange ifFalse: [^ self].
currentClassName ifNil: [^self].
index := self classList indexOf: currentClassName.
myChangeSet removeClassChanges: (self withoutItemAnnotation: currentClassName).
+ self changed: #classList.
- currentSelector := nil.
classList := self classList.
+ self currentClassName: (classList isEmpty ifFalse:
+ [classList at: (index min: classList size)]).!
- currentClassName := classList isEmpty ifFalse:
- [classList at: (index min: classList size)].
- self showChangeSet: myChangeSet!
Marcel Taeumel uploaded a new version of MorphicExtras to project The Trunk:
http://source.squeak.org/trunk/MorphicExtras-mt.297.mcz
==================== Summary ====================
Name: MorphicExtras-mt.297
Author: mt
Time: 29 April 2021, 6:03:23.320356 pm
UUID: 90db92d6-2b46-7741-a2bd-147dbc644da9
Ancestors: MorphicExtras-mt.296
Avoid using ActiveWorld, ActiveHand, ActiveEvent.
=============== Diff against MorphicExtras-mt.296 ===============
Item was changed:
----- Method: Workspace class>>extraExampleContents2 (in category '*MorphicExtras-examples') -----
extraExampleContents2
"This is example code for #extraExample2"
"Inspect any (sub)expression result by pressing <cmd>i"
(20 to: 40 by: 2) asOrderedCollection
addFirst: 16;
addLast: 42;
sort: [:x | x \\ 3] descending;
yourself.
"Explore any (sub)expression result by pressing <cmd>I"
Project current world.
"Debug any (sub)expression using <cmd>D"
(1 to: 9) join asNumber sqrt truncateTo: 1e-3.
+ (SystemWindow windowsIn: self currentWorld)
- (SystemWindow windowsIn: ActiveWorld)
select: [:window | window bounds isWide]
thenDo: [:window | window color: window color negated].!
Marcel Taeumel uploaded a new version of Tools to project The Trunk:
http://source.squeak.org/trunk/Tools-mt.1046.mcz
==================== Summary ====================
Name: Tools-mt.1046
Author: mt
Time: 29 April 2021, 4:27:09.983356 pm
UUID: 103a7fea-3c92-f94f-a5f5-0568d1b1d8c2
Ancestors: Tools-mt.1045
Auto-select the first entry when browsing change sets.
This is similar to the dependency browser, where we often work with smaller lists. There it is cumbersome to have to make extra clicks just to show the contents of the first entry.
=============== Diff against Tools-mt.1045 ===============
Item was changed:
----- Method: ChangeSorter>>currentClassName: (in category 'class list') -----
currentClassName: aString
currentClassName := aString.
- currentSelector := nil. "fix by wod"
self changed: #currentClassName.
self changed: #messageList.
+
+ self currentSelector: (self messageList ifNotEmpty: [:list | list first]).
+ !
- self setContents.
- self contentsChanged.!
Item was changed:
----- Method: ChangeSorter>>showChangeSet: (in category 'access') -----
showChangeSet: chgSet
myChangeSet == chgSet ifFalse: [
myChangeSet := chgSet.
currentClassName := nil.
currentSelector := nil].
self changed: #relabel.
self changed: #currentCngSet. "new -- list of sets"
self changed: #mainButtonName. "old, button"
self changed: #classList.
+
+ self currentClassName: (self classList ifNotEmpty: [:list | list first]).!
- self changed: #messageList.
- self setContents.
- self contentsChanged.!
Marcel Taeumel uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-mt.1766.mcz
==================== Summary ====================
Name: Morphic-mt.1766
Author: mt
Time: 29 April 2021, 4:11:40.190356 pm
UUID: 4cb3ac38-5af3-0045-925d-ea4a97fd68aa
Ancestors: Morphic-mt.1765
Fixes a hick-up with the grid layout for morphs that do not #spaceFill the grid cells such as any "Morph new"
(Note that I think that #cellPositioning should be part of any LayoutProperties, not just the TableLayoutProperties. So, this fix is more like a temporary workaround.)
=============== Diff against Morphic-mt.1765 ===============
Item was added:
+ ----- Method: GridLayoutProperties>>cellPositioning (in category 'accessing') -----
+ cellPositioning
+
+ ^ #topLeft!
Nicolas Cellier uploaded a new version of ToolBuilder-Kernel to project The Trunk:
http://source.squeak.org/trunk/ToolBuilder-Kernel-nice.145.mcz
==================== Summary ====================
Name: ToolBuilder-Kernel-nice.145
Author: nice
Time: 28 April 2021, 9:23:48.35444 pm
UUID: f27e3b02-2905-d94b-97f3-93e95bd58880
Ancestors: ToolBuilder-Kernel-nice.141
Fix ProgressInitiationException>>sendNotificationsTo: so that:
- the ProgressInitiationException remains inactive during workBlock evaluation
- unless explicitely rearmed
- active inner handlers remain active during workBlock evaluation
For the last goal, it is necessary to first resume, then evaluate the workBlock, hence usage of #resumeEvaluating:
This goes with Kernel-nice.1394 which implements this method as well as upgraded signal handling.
But if we resume, then we also unwind the stack and evaluate all the ensure: blocks...
This will reactivate current handler, and desarm it if we rearmed, in other words, the exact contrary of what was requested!
Hence the intricated activate/deactivate dance.
If the purpose is to completely suppress Progress bars and progress notifications, then provide an appropriate handling action that will do so: #resumeSuppressingProgress
=============== Diff against ToolBuilder-Kernel-nice.141 ===============
Item was added:
+ ----- Method: ProgressInitiationException>>resumeSuppressingProgress (in category 'handling') -----
+ resumeSuppressingProgress
+ "Catch and suppress every ProgressInitiationException and ProgressNotification
+ during the evaluation of workBlock"
+
+ ^self resumeEvaluating:
+ [self rearmHandlerDuring:
+ [[workBlock value: [ :barVal | "do nothing"]]
+ on: ProgressNotification do: [:e | e resume]]]!
Item was changed:
+ ----- Method: ProgressInitiationException>>sendNotificationsTo: (in category 'handling') -----
- ----- Method: ProgressInitiationException>>sendNotificationsTo: (in category 'initialize-release') -----
sendNotificationsTo: aNewBlock
+ "Resume execution using aNewBlock as workBlock value.
+ Note that the execution is resumed in signalContext (or outerContext).
+ This is done so that inner exception handlers be active during workBlock execution.
+ However, our own handlerContext should be deactivated, unless explicitely rearmed."
+ | mustDeactivateHandler |
+ mustDeactivateHandler := handlerContext notNil and: [handlerContext isHandlerActive not].
+ mustDeactivateHandler
+ ifTrue:
+ ["The handlerContext is de-activated during handleSignal:
+ But it will be reactivated during unwinding when we will resumeEvaluating:
+ That's unwanted, we don't generally want to rearm the handler during workBlock evaluation.
+ Hence we have to deactivate it again inside the deferred block."
+ self resumeEvaluating:
+ [handlerContext deactivateHandler.
+ [workBlock value: [ :barVal |
+ aNewBlock value: minVal value: maxVal value: barVal]]
+ ensure: [handlerContext reactivateHandler]]]
+ ifFalse:
+ ["If the handler is active at this step, then it must have been rearmed
+ with a #rearmHandlerDuring:
+ It's thus intentional to keep the handler active during workBlock evaluation
+ But the ensure: [self desarmHandler] will be evaluated during unwinding when we will resumeEvaluating:
+ It is thus necessary to rearm again inside the evaluated block"
+ self resumeEvaluating:
+ [self rearmHandlerDuring:
+ [workBlock value: [ :barVal |
+ aNewBlock value: minVal value: maxVal value: barVal]]]]!
-
- self reactivateHandlers; resumeUnchecked: (
- workBlock value: [ :barVal |
- aNewBlock value: minVal value: maxVal value: barVal
- ]
- )
- !
Nicolas Cellier uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-nice.1394.mcz
==================== Summary ====================
Name: Kernel-nice.1394
Author: nice
Time: 26 April 2021, 1:50:12.861556 am
UUID: 3a981b94-0213-44f3-8263-838dda062f8a
Ancestors: Kernel-bp.1393
Revise exception handling so as to
- inactivate inner handler blocks when the exception is signalled in an outer handler
- except when the inner handler has been explicitely rearmed (see rearmHandlerDuring:)
Implementation notes: add a marker <primitive: 199> to handleSignal:, so as to detect the case when an exception is signalled within the execution of a handler block.
This induces a subtle difference:
- findNextHandlerContext might now return a handleSignal: context,
- while nextHandlerContext will only return a on:do: context (or nil).
The new workhorse for finding the proper handler is now #nextHandlerContextForSignal:
It finds and answers the (handler) context that will handle the exception, but if it finds a handleSignal: during the scan, it will restrict the search to rearmed handlers, until it reaches the handler of prior exception, at which step it continues to search normally.
Due to the scanning of inner blocks, we still need a marker for blocking re-entrancy (handlerActive temp in on:do:), but also a marker for rearmed blocks (handlerRearmed in on:do:). This can't be the same marker: an example is testHandlerReentrancy: when the rearmed inner handler pass the exception to its outer handler, the outer handler must still be inactive if it raised the Exception.
Borrow resumeEvaluating: to Cuis and use it in resignalAs:
Use many small methods in order to make the intention more explicit than with those mysterious tempAt: tempAt:put:
=============== Diff against Kernel-bp.1393 ===============
Item was changed:
----- Method: BlockClosure>>on:do: (in category 'exceptions') -----
on: exceptionOrExceptionSet do: handlerAction
"Evaluate the receiver in the scope of an exception handler."
+ | handlerActive handlerRearmed |
- | handlerActive |
<primitive: 199> "just a marker, fail and execute the following"
handlerActive := true.
+ handlerRearmed := false.
^ self value!
Item was changed:
----- Method: Context>>canHandleSignal: (in category 'private-exceptions') -----
canHandleSignal: exception
"Sent to handler (on:do:) contexts only. If my exception class (first arg) handles exception then return true, otherwise forward this message to the next handler context. If none left, return false (see nil>>canHandleSignal:)"
+ ^ (self willHandleSignal: exception)
- ^ (((self tempAt: 1) handles: exception) and: [self tempAt: 3])
or: [self nextHandlerContext canHandleSignal: exception].
!
Item was added:
+ ----- Method: Context>>deactivateHandler (in category 'private-exceptions') -----
+ deactivateHandler
+ "Private - sent to exception handler context only (on:do:)"
+
+ stackp >= 3 ifTrue: [self tempAt: 3 put: false] "this is temporary handlerActive in #on:do:"!
Item was added:
+ ----- Method: Context>>desarmHandler (in category 'private-exceptions') -----
+ desarmHandler
+ "Private - sent to exception handler context only (on:do:)"
+
+ stackp >= 4 ifTrue: [self tempAt: 4 put: false] "this is temporary handlerRearmed in #on:do:"!
Item was added:
+ ----- Method: Context>>findNextHandlerContext (in category 'private-exceptions') -----
+ findNextHandlerContext
+ "find next context marked with <primitive: 199>.
+ This can be either a handler context (on:do:),
+ or a handling context (handleSignal:)"
+
+ ^ self sender findNextHandlerContextStarting!
Item was added:
+ ----- Method: Context>>fireHandlerActionForSignal: (in category 'private-exceptions') -----
+ fireHandlerActionForSignal: exception
+ "Sent to handler (on:do:) contexts only.
+ Perform the second argument, which is the handler action"
+
+ ^(self tempAt: 2) cull: exception!
Item was changed:
----- Method: Context>>handleSignal: (in category 'private-exceptions') -----
handleSignal: exception
+ "Sent to handler (on:do:) contexts only.
+ Execute the handler action block"
- "Sent to handler (on:do:) contexts only. If my exception class (first arg) handles exception
- and the handler is active then execute my handle block (second arg), otherwise forward
- this message to the next handler context. If none left, execute exception's defaultAction
- (see nil>>handleSignal:)."
+ | val |
+ <primitive: 199> "just a marker, fail and execute the following"
- | handlerActive val |
- "If the context has been returned from the handlerActive temp var may not be accessible."
- handlerActive := stackp >= 3 and: [(self tempAt: 3) == true].
- (((self tempAt: 1) handles: exception) and: [handlerActive]) ifFalse:
- [stackp >= 3 ifTrue: [self tempAt: 3 put: false].
- ^self nextHandlerContext handleSignal: exception].
-
exception privHandlerContext: self contextTag.
+ self deactivateHandler. "Prevent re-entering the action block, unless it is explicitely rearmed"
+ val := [self fireHandlerActionForSignal: exception] ensure: [self reactivateHandler].
+ self return: val "return from self if not otherwise directed in handle block"!
- self tempAt: 3 put: false. "disable self while executing handle block"
- val := [(self tempAt: 2) cull: exception]
- ifCurtailed: [self tempAt: 3 put: true].
- self return: val "return from self if not otherwise directed in handle block"
- !
Item was added:
+ ----- Method: Context>>isHandlerActive (in category 'private-exceptions') -----
+ isHandlerActive
+ "Private - sent to exception handler context only (on:do:)"
+
+ ^stackp >= 3 and: [(self tempAt: 3) == true] "this is temporary handlerActive in #on:do:"!
Item was added:
+ ----- Method: Context>>isHandlerRearmed (in category 'private-exceptions') -----
+ isHandlerRearmed
+ "Private - sent to exception handler context only (on:do:)"
+
+ ^stackp >= 4 and: [(self tempAt: 4) == true] "this is temporary handlerRearmed in #on:do:"!
Item was changed:
----- Method: Context>>nextHandlerContext (in category 'private-exceptions') -----
nextHandlerContext
+ "Answer the next handler context (on:do:) in the call chain.
+ Answer nil if none found"
+
+ | handler |
+ handler := self findNextHandlerContext.
+ [handler ifNil: [^nil].
+ handler selector == #handleSignal:]
+ whileTrue: [handler := handler findNextHandlerContext].
+ ^handler!
-
- ^ self sender findNextHandlerContextStarting!
Item was added:
+ ----- Method: Context>>nextHandlerContextForSignal: (in category 'private-exceptions') -----
+ nextHandlerContextForSignal: exception
+ "Answer the handler context (on:do:) for this exception
+ Answer nil if none found"
+
+ | handler priorHandler |
+ handler := self.
+ [(handler := handler findNextHandlerContext) ifNil: [^nil].
+ handler selector == #handleSignal:]
+ whileFalse: [(handler willHandleSignal: exception) ifTrue: [^handler]].
+
+ "exception has been signalled in the scope of another signal handler (while #handleSignal:)
+ Check for a rearmed inner handler. If none, jump to outer handler context."
+ priorHandler := (handler tempAt: 1) "the exception argument to handleSignal:"
+ privHandlerContext.
+
+ [(handler := handler nextHandlerContext) ifNil: [^nil].
+ (handler isHandlerRearmed and: [handler willHandleSignal: exception]) ifTrue: [^handler].
+ handler == priorHandler] whileFalse.
+
+ ^priorHandler nextHandlerContextForSignal: exception!
Item was added:
+ ----- Method: Context>>reactivateHandler (in category 'private-exceptions') -----
+ reactivateHandler
+ "Private - sent to exception handler context only (on:do:)"
+
+ stackp >= 3 ifTrue: [self tempAt: 3 put: true] "this is temporary handlerActive in #on:do:"!
Item was changed:
----- Method: Context>>reactivateHandlers (in category 'private-exceptions') -----
reactivateHandlers
+ "Private - exception handling
+ do nothing, this method is only here for smooth transition.
+ It shall be removed at next update map."
- "Private - sent to exception handler context only (on:do:).
- Reactivate all the handlers into the chain"
+ ^self!
- self tempAt: 3 put: true. "this is temporary handlerActive in #on:do:"
- self nextHandlerContext reactivateHandlers!
Item was added:
+ ----- Method: Context>>rearmHandler (in category 'private-exceptions') -----
+ rearmHandler
+ "Private - sent to exception handler context only (on:do:)"
+
+ self reactivateHandler.
+ stackp >= 4 ifTrue: [self tempAt: 4 put: true] "this is temporary handlerRearmed in #on:do:"!
Item was changed:
----- Method: Context>>rearmHandlerDuring: (in category 'private-exceptions') -----
rearmHandlerDuring: aBlock
"Sent to handler (on:do:) contexts only. Makes me re-entrant for the duration of aBlock. Only works in a closure-enabled image"
+ ^ [self rearmHandler. aBlock value]
+ ensure: [self desarmHandler]!
- ^ [self tempAt: 3 put: true. aBlock value]
- ensure: [self tempAt: 3 put: false]!
Item was added:
+ ----- Method: Context>>rearmHandlersWhich:upTo: (in category 'private-exceptions') -----
+ rearmHandlersWhich: selectBlock upTo: aHandlerContext
+ "Private - sent to exception handler context only (on:do:).
+ Rearm the inner handlers into the chain, up to, but not including, aHandlerContext, that satisfy the selectBlock predicate"
+
+ self == aHandlerContext ifTrue: [^self].
+ (selectBlock value: self) ifTrue: [self rearmHandler].
+ self nextHandlerContext rearmHandlersWhich: selectBlock upTo: aHandlerContext!
Item was changed:
----- Method: Context>>resume: (in category 'controlling') -----
resume: value
"Unwind thisContext to self and resume with value as result of last send. Execute unwind blocks when unwinding. ASSUMES self is a sender of thisContext"
+ ^self resumeEvaluating: [value]
- | ctxt unwindBlock |
- self isDead ifTrue: [self cannotReturn: value to: self].
- ctxt := thisContext.
- [ ctxt := ctxt findNextUnwindContextUpTo: self.
- ctxt isNil
- ] whileFalse: [
- (ctxt tempAt: 2) ifNil:[
- ctxt tempAt: 2 put: true.
- unwindBlock := ctxt tempAt: 1.
- thisContext terminateTo: ctxt.
- unwindBlock value].
- ].
- thisContext terminateTo: self.
- ^ value
!
Item was added:
+ ----- Method: Context>>resumeEvaluating: (in category 'controlling') -----
+ resumeEvaluating: aBlock
+ "Unwind thisContext to self and resume with value as result of last send.
+ Execute unwind blocks when unwinding.
+ ASSUMES self is a sender of thisContext"
+
+ | ctxt unwindBlock |
+ self isDead ifTrue: [self cannotReturn: aBlock value to: self].
+ ctxt := thisContext.
+ [ ctxt := ctxt findNextUnwindContextUpTo: self.
+ ctxt isNil
+ ] whileFalse: [
+ (ctxt tempAt: 2) ifNil:[
+ ctxt tempAt: 2 put: true.
+ unwindBlock := ctxt tempAt: 1.
+ thisContext terminateTo: ctxt.
+ unwindBlock value].
+ ].
+ thisContext terminateTo: self.
+ ^ aBlock value
+ !
Item was added:
+ ----- Method: Context>>returnEvaluating: (in category 'controlling') -----
+ returnEvaluating: aBlock
+ "Unwind thisContext to self and return aBlock value to self's sender.
+ Execute any unwind blocks while unwinding.
+ ASSUMES self is a sender of thisContext"
+
+ sender ifNil: [self cannotReturn: aBlock value to: sender].
+ sender resumeEvaluating: aBlock!
Item was added:
+ ----- Method: Context>>willHandleSignal: (in category 'private-exceptions') -----
+ willHandleSignal: exception
+ "Sent to handler (on:do:) contexts only."
+
+ ^self isHandlerActive and: [(self tempAt: 1) handles: exception]
+ !
Item was changed:
----- Method: Exception>>pass (in category 'handling') -----
pass
"Yield control to the enclosing exception action for the receiver."
+ (handlerContext nextHandlerContextForSignal: self) handleSignal: self!
- handlerContext nextHandlerContext handleSignal: self!
Item was added:
+ ----- Method: Exception>>privHandlerContext (in category 'priv handling') -----
+ privHandlerContext
+ ^handlerContext!
Item was changed:
----- Method: Exception>>reactivateHandlers (in category 'priv handling') -----
reactivateHandlers
+ "Private - exception handling
+ do nothing, this method is only here for smooth transition.
+ It shall be removed at next update map."
+
+ ^self!
- "reactivate all the exception handlers in the context chain"
- self canSearchForSignalerContext
- ifTrue: [signalContext nextHandlerContext reactivateHandlers]!
Item was changed:
----- Method: Exception>>resignalAs: (in category 'handling') -----
resignalAs: replacementException
"Signal an alternative exception in place of the receiver."
+ self resumeEvaluating: [replacementException signal]!
- self reactivateHandlers.
- self resumeUnchecked: replacementException signal!
Item was changed:
----- Method: Exception>>resume: (in category 'handling') -----
resume: resumptionValue
"Return resumptionValue as the value of the signal message."
self isResumable ifFalse: [IllegalResumeAttempt signal].
- self reactivateHandlers.
self resumeUnchecked: resumptionValue!
Item was added:
+ ----- Method: Exception>>resumeEvaluating: (in category 'handling') -----
+ resumeEvaluating: aBlock
+ "Return result of evaluating aBlock as the value of #signal, unless this was called after an #outer message, then return resumptionValue as the value of #outer.
+ The block is only evaluated after unwinding the stack."
+
+ | ctxt |
+ outerContext ifNil: [
+ signalContext returnEvaluating: aBlock
+ ] ifNotNil: [
+ ctxt := outerContext.
+ outerContext := ctxt tempAt: 1. "prevOuterContext in #outer"
+ ctxt returnEvaluating: aBlock
+ ].
+ !
Item was changed:
----- Method: Exception>>signal (in category 'signaling') -----
signal
"Ask ContextHandlers in the sender chain to handle this signal. The default is to execute and return my defaultAction."
signalContext := thisContext contextTag.
+ ^(thisContext nextHandlerContextForSignal: self) handleSignal: self!
- ^ thisContext nextHandlerContext handleSignal: self!
Item was changed:
----- Method: UndefinedObject>>handleSignal: (in category 'bottom context') -----
handleSignal: exception
+ "When no more handler (on:do:) context left in sender chain this gets called. Return from signal with default action."
- "When no more handler (on:do:) context left in sender chain this gets called. Return from signal with default action.
- Before doing that, reactivate the handlers so that they can catch eventual secondary exceptions raised by defaultAction."
+ ^ exception resumeUnchecked: exception defaultAction!
- ^ exception reactivateHandlers; resumeUnchecked: exception defaultAction!
Item was removed:
- ----- Method: UndefinedObject>>reactivateHandlers (in category 'bottom context') -----
- reactivateHandlers
- "nothing to do for bottom context"
-
- ^ self!
Item was added:
+ ----- Method: UndefinedObject>>rearmHandlersWhich:upTo: (in category 'bottom context') -----
+ rearmHandlersWhich: selectBlock upTo: aHandlerContext
+
+ ^ self!