[Bug] EtAbstractMethodsBrowser>>#renameTemporary

VA Smalltalk is a "100% VisualAge compatible" IDE that includes the original VisualAge technology and the popular VA Assist and WidgetKit add-ons.

Moderators: Eric Clayberg, wembley, tc, Diane Engles, solveig

[Bug] EtAbstractMethodsBrowser>>#renameTemporary

Postby jtuchel » Thu Nov 25, 2010 12:08 am

The method crashes if you answer the new name dialog by pressing cancel, since it only tests the answer for an empty string, but not for nil.

How to get the bug?

select a Block temp or a method temp variable and select to rename the temp variable. Press cancel when system asks for new name.

Solution: do not perform the refactoring if the answer of teh dialog is either nil or an empty String.

Fix: Change the method EtAbstractMethodsBrowser>>#renameTemporary to

Code: Select all
renameTemporary

   | tempNode |

   tempNode := self findNode.
   (tempNode isNil or: [tempNode isVariable not]) ifTrue: [^self warn: 'Could not find the node'].
   (self request: 'Enter new name:' initialAnswer: tempNode name) ifNotNil: [:newName |
      newName isEmpty ifTrue: [^self].
      self performRefactoring: (self renameTempNode: tempNode to: newName)]


The same problem exists in BrowserCodeTool>>#renameTemporary and can be fixed the same way.

Remark: The Refactoring integration with the Browsers has lots of such little bugs.
jtuchel
[|]
 
Posts: 245
Joined: Fri Oct 05, 2007 1:05 am
Location: Ludwigsburg, Germany

Re: [Bug] EtAbstractMethodsBrowser>>#renameTemporary

Postby tc » Fri Nov 26, 2010 8:32 am

Hello,

I opened case #47906 for this issue.

Thanks.

--tc
tc
Moderator
 
Posts: 304
Joined: Tue Oct 17, 2006 7:40 am
Location: Raleigh, NC

Re: [Bug] EtAbstractMethodsBrowser>>#renameTemporary

Postby wembley » Fri Nov 26, 2010 9:34 am

Joachim -

Good catch, thanks. Wouldn't this change be a little simpler?
Code: Select all
renameTemporary
   | newName tempNode |
   tempNode := self findNode.
   (tempNode isNil or: [tempNode isVariable not])
      ifTrue: [^self warn: 'Could not find the node'].
   newName := self request: 'Enter new name:' initialAnswer: tempNode name.
   newName isEmptyorNil ifTrue: [^self].
   self performRefactoring: (self renameTempNode: tempNode to: newName)
John O'Keefe [|], Principal Smalltalk Architect, Instantiations Inc.
wembley
Moderator
 
Posts: 405
Joined: Mon Oct 16, 2006 3:01 am
Location: Durham, NC

Re: [Bug] EtAbstractMethodsBrowser>>#renameTemporary

Postby wembley » Fri Nov 26, 2010 10:16 am

Joachim -

Whoa, let's step back and look at the implementation of #request:initialAnswer:

Code: Select all
request: aString initialAnswer: anAnswerString
   | answer |
   answer := (CwTextPrompter new) title: self label;
            messageString: aString;
            answerString: anAnswerString;
            prompt.
   ^answer isNil ifTrue: [''] ifFalse: [answer]

So I don't see how this method can answer nil, and if it can't answer nil, then I guess I don't understand where the crash is.
John O'Keefe [|], Principal Smalltalk Architect, Instantiations Inc.
wembley
Moderator
 
Posts: 405
Joined: Mon Oct 16, 2006 3:01 am
Location: Durham, NC

Re: [Bug] EtAbstractMethodsBrowser>>#renameTemporary

Postby jtuchel » Sat Nov 27, 2010 5:03 am

John,

thanks for looking into this. I try to keep away from VAST on weekends until christmas, so I will have to take a look on monday. I am sure I had the crash, that's why I looked into the method after having it too often. So maybe I had an older version of the MED extensions loaded. I'll be back ;)

Joachim
jtuchel
[|]
 
Posts: 245
Joined: Fri Oct 05, 2007 1:05 am
Location: Ludwigsburg, Germany

Re: [Bug] EtAbstractMethodsBrowser>>#renameTemporary

Postby jtuchel » Sat Nov 27, 2010 5:05 am

ah, and your other question: yes, isEmptyOrNil would come in handy. I knew we're using it, but thought it's self-written rather than provided with VAST. But if it is: even better ;-)
jtuchel
[|]
 
Posts: 245
Joined: Fri Oct 05, 2007 1:05 am
Location: Ludwigsburg, Germany

Re: [Bug] EtAbstractMethodsBrowser>>#renameTemporary

Postby jtuchel » Sun Nov 28, 2010 11:47 pm

John,

it's phenomenon day: after you've brought up the question how request:initialAnswer: could ever return nil, I just reloaded MedRBExtensionsApp V 8.0.1 [134] and tried again: Rename Temporary, and click cancel when asked for a name. Boom: UndefinedObject doesNotUnderstand: isEmpty.

Of course, if I put a Breakpoint in request:initialAnswer:, the result will never be nil, and therefor you are right and wrong at the same time. It cannot return nil, but it obviously does sometimes. I'll give it another try in a clean image later today.

Joachim

-----------------stack trace-----------

Debugger Stack Trace Report:
Error String: 'UndefinedObject does not understand isEmpty'
Resumable: false

UIProcess
Name: (29.11.2010 08:30:22)
Process State: suspended
Priority: 3

Executing in: StsTabbedClassesBrowserWin(EtAbstractMethodsBrowser)>>#renameTemporary

System Configuration Dump


Copyright:

VA Smalltalk V8.0.2 ; Image: 8.0.2
VM Timestamp: 4.0,(NC) 5/3/2010 (80)
(C) Copyright Instantiations 1994, 2010. All rights reserved.
(C) Copyright International Business Machines Corp. 1994, 2006. All rights reserved.

Time: 08:46:38
Date: 29.11.2010

Platform:

Virtual machine: ES
Bytecode version: 4.0
Manager version: 4.00
'OS' subsystem: 'WIN32s'
'CLIM' subsystem: 'ES'
'CP' subsystem: 'WIN32s'
'CLDT' subsystem: 'ES'
'CFS' subsystem: 'WIN32s'
'SCI' subsystem: 'WIN'
'CW' subsystem: 'WIN32s'
'CPM' subsystem: 'ES'
'CG' subsystem: 'WIN32s'
'CPIC' subsystem: 'WIN32s'

Current user: Joachim Tuchel

Connected Library:

Pathname: ...

INFO: Trapped error dumping system configuration.
=============<STACK TRACE BEGINS>============
[] in <optimized block>(ExceptionalEvent class)>>#initializeSystemExceptions
signal=Signal on Exception: (ExError) An error has occurred.
Signal>>#evaluate:
self=Signal on Exception: (ExError) An error has occurred.
aBlock=[] in ExceptionalEvent class>>#initializeSystemExceptions
Signal>>#evaluateDefaultHandler:
self=Signal on Exception: (ExError) An error has occurred.
aBlock=[] in ExceptionalEvent class>>#initializeSystemExceptions
ExceptionalEvent>>#applyDefaultHandler:
self=Exception: (ExError) An error has occurred.
aSignal=Signal on Exception: (ExError) An error has occurred.
exception=Exception: (ExError) An error has occurred.
ExceptionalEvent>>#signalFor:
self=Exception: (ExError) An error has occurred.
aSignalOrExceptionSelector=Signal on Exception: (ExError) An error has occurred.
handler=nil
ExceptionalEvent>>#signalWithArguments:
self=Exception: (ExError) An error has occurred.
arguments=('UndefinedObject does not understand isEmpty')
ExceptionalEvent>>#signalWith:
self=Exception: (ExError) An error has occurred.
arg1='UndefinedObject does not understand isEmpty'
UndefinedObject(Object)>>#error:
self=nil
aString='UndefinedObject does not understand isEmpty'
MessageNotUnderstood>>#defaultAction
self=Signal on Exception: (ExMessageNotUnderstood) An exception has occurred
[] in <optimized block>(Exception class)>>#newExceptionalEvent
signal=Signal on Exception: (ExMessageNotUnderstood) An exception has occurred
MessageNotUnderstood(Exception)>>#evaluateDefaultHandler:
self=Signal on Exception: (ExMessageNotUnderstood) An exception has occurred
aBlock=[] in Exception class>>#newExceptionalEvent
ExceptionalEvent>>#applyDefaultHandler:
self=Exception: (ExMessageNotUnderstood) An exception has occurred
aSignal=Signal on Exception: (ExMessageNotUnderstood) An exception has occurred
exception=Exception: (ExMessageNotUnderstood) An exception has occurred
ExceptionalEvent>>#signalFor:
self=Exception: (ExMessageNotUnderstood) An exception has occurred
aSignalOrExceptionSelector=Signal on Exception: (ExMessageNotUnderstood) An exception has occurred
handler=nil
MessageNotUnderstood(Exception)>>#signal
self=Signal on Exception: (ExMessageNotUnderstood) An exception has occurred
MessageNotUnderstood class(Exception class)>>#signalWith:
self=MessageNotUnderstood
signallerTag=(nil Message (#isEmpty, ()))
UndefinedObject(Object)>>#doesNotUnderstand:
self=nil
aMessage=Message (#isEmpty, ())
StsTabbedClassesBrowserWin(EtAbstractMethodsBrowser)>>#renameTemporary
self=a StsTabbedClassesBrowserWin
newName=nil
tempNode=RBVariableNode(...)
CwMenuPushButton>>#dispatchTo:
self=a CwMenuPushButton
receiver=a StsTabbedClassesBrowserWin
selectorOrDirectedMessage=#renameTemporary
CwMenu>>#simpleCallback:clientData:callData:
self=a CwMenu
w=CwPushButton(button_2)
index=2
callData=CwAnyCallbackData(
reason -> 10
)
CwCallbackRec>>#callWith:callData:
self=a CwCallbackRec
aWidget=CwPushButton(button_2)
callData=CwAnyCallbackData(
reason -> 10
)
CwPushButton(CwBasicWidget)>>#callCallbackList:callData:
self=CwPushButton(button_2)
aCallbackList=OrderedCollection(a CwCallbackRec )
callData=CwAnyCallbackData(
reason -> 10
)
callbacks=nil
size=1
rec1=nil
rec2=nil
rec3=nil
[] in CwRowColumn>>#simple:clientData:callData:
self=CwRowColumn(untitled)
aRowColumn=CwRowColumn(untitled)
clientData=nil
callData=CwRowColumnCallbackData(
reason -> 10
widget -> CwPushButton(button_2)
data -> nil
callbackData -> CwAnyCallbackData(
reason -> 10
)
)
data=CwAnyCallbackData(
reason -> 10
)
index=2
list=OrderedCollection(a CwCallbackRec )
child=CwPushButton(button_2)
OrderedCollection>>#do:
self=OrderedCollection(CwPushButton(button_0) CwPushButton(button_1) CwPushButton(button_2) CwPushButton(button_3) )
aBlock=[] in CwRowColumn>>#simple:clientData:callData:
CwRowColumn>>#simple:clientData:callData:
self=CwRowColumn(untitled)
aRowColumn=CwRowColumn(untitled)
clientData=nil
callData=CwRowColumnCallbackData(
reason -> 10
widget -> CwPushButton(button_2)
data -> nil
callbackData -> CwAnyCallbackData(
reason -> 10
)
)
data=CwAnyCallbackData(
reason -> 10
)
index=2
list=OrderedCollection(a CwCallbackRec )
CwCallbackRec>>#callWith:callData:
self=a CwCallbackRec
aWidget=CwRowColumn(untitled)
callData=CwRowColumnCallbackData(
reason -> 10
widget -> CwPushButton(button_2)
data -> nil
callbackData -> CwAnyCallbackData(
reason -> 10
)
)
CwRowColumn(CwBasicWidget)>>#callCallbackList:callData:
self=CwRowColumn(untitled)
aCallbackList=OrderedCollection(a CwCallbackRec )
callData=CwRowColumnCallbackData(
reason -> 10
widget -> CwPushButton(button_2)
data -> nil
callbackData -> CwAnyCallbackData(
reason -> 10
)
)
callbacks=nil
size=1
rec1=nil
rec2=nil
rec3=nil
CwRowColumn>>#entry:clientData:callData:
self=CwRowColumn(untitled)
aWidget=CwPushButton(button_2)
callbackList=nil
callData=CwAnyCallbackData(
reason -> 10
)
entryCallData=CwRowColumnCallbackData(
reason -> 10
widget -> CwPushButton(button_2)
data -> nil
callbackData -> CwAnyCallbackData(
reason -> 10
)
)
CwPushButton>>#callActivateCallback:
self=CwPushButton(button_2)
anEvent=an OSEvent
OSMenuItem(OSWidget)>>#callHandlers:with:
self=OSMenuItem(Rename...)
handlers=#callActivateCallback:
data=an OSEvent
DirectedMessage>>#send
self=DirectedMessage (OSMenuItem(Rename...), #callHandlers:with:, (#callActivateCallback: an OSEvent))
OSEventManager class>>#runDeferredMessages
self=OSEventManager
messageAvailable=true
message=DirectedMessage (OSMenuItem(Rename...), #callHandlers:with:, (#callActivateCallback: an OSEvent))
state=true
OSWidget class>>#readAndDispatch
self=OSWidget
state=true
gotEvent=true
CwAppContext>>#readAndDispatch
self=a CwAppContext
AbtWindowSystemStartUp class(EsWindowSystemStartUp class)>>#messageLoop
self=AbtWindowSystemStartUp
lastEventTime=1122187
appContext=a CwAppContext
[] in <optimized block>(UIProcess class)>>#forkUserInterface
[] in UIProcess(Process)>>#executeBlock:withArguments:
self=UIProcess:(29.11.2010 08:30:22){suspended,3}
aBlock=[] in UIProcess class>>#forkUserInterface
args=()
UIProcess(Process)>>#executeBlock:withArguments:
self=UIProcess:(29.11.2010 08:30:22){suspended,3}
aBlock=[] in UIProcess class>>#forkUserInterface
args=()
UIProcess(Process)>>#newProcessOn:stackSize:withArguments:named:
self=UIProcess:(29.11.2010 08:30:22){suspended,3}
aBlock=[] in UIProcess class>>#forkUserInterface
stackSize=1024
args=()
procName='(29.11.2010 08:30:22)'
==============<STACK TRACE ENDS>=============
jtuchel
[|]
 
Posts: 245
Joined: Fri Oct 05, 2007 1:05 am
Location: Ludwigsburg, Germany

Re: [Bug] EtAbstractMethodsBrowser>>#renameTemporary

Postby jtuchel » Mon Nov 29, 2010 5:15 am

John,

in a clean Image there is no problem with pressing cancel. So I somehow broke my image in a really catastrophic way.
Maybe because I am brutally messing with subclassing UndefindeObject in it ;-)
I may have found a state in between being nil and otherwise, something like a DecreasinglyUndefinedObjectOverTime or such ;-O
jtuchel
[|]
 
Posts: 245
Joined: Fri Oct 05, 2007 1:05 am
Location: Ludwigsburg, Germany


Return to VA Smalltalk 7.0, 7.5 & 8.0

Who is online

Users browsing this forum: Google [Bot] and 1 guest

cron