[squeak-dev] Why is testMoveVarFromSubToSuperclass doing that? (was: The Inbox: Kernel-cmm.1190.mcz)
Eliot Miranda
eliot.miranda at gmail.com
Fri Aug 31 17:36:12 UTC 2018
Hi Chris,
On Wed, Aug 29, 2018 at 7:33 PM Chris Muller <asqueaker at gmail.com> wrote:
> Kernel-cmm.1190.mcz is my proposed fix for the bug identified by the
> new #testDuplicateInstanceVariableError, for your review.
>
> But while working on that I was shocked to notice what
> testMoveVarFromSubToSuperclass is doing and testing for. Resuming the
> DuplicateVariableException so it could, truly, make interrogations
> about an object that shouldn't exist (right?). Very strange!
>
Imagine this:
Object subclass: #Fu
instanceVariableNames: ''.
Fu subclass: #Bar
instanceVariableNames: 'fubar'.
and we want to refactor to this:
Object subclass: #Fu
instanceVariableNames: 'fubar'.
Fu subclass: #Bar
instanceVariableNames: ''.
either we provide a class builder that can morph more than one class at a
time or we have a problem.
If we refactor via this route:
1. { Object subclass: #Fu instanceVariableNames: ''. Fu subclass: #Bar
instanceVariableNames: 'fubar' }
=> { Object subclass: #Fu instanceVariableNames: ''. Fu subclass: #Bar
instanceVariableNames: '' }
=> { Object subclass: #Fu instanceVariableNames: 'fubar'. Fu subclass: #Bar
instanceVariableNames: '' }
then fubar becomes undeclared (which is a single l-value in Undeclared),
and hence all instances of Bar but the first one have their inst var trashed
If we refactor via this route:
2.
1. { Object subclass: #Fu instanceVariableNames: ''. Fu subclass: #Bar
instanceVariableNames: 'fubar' }
=> { Object subclass: #Fu instanceVariableNames: 'fubar'. Fu subclass: #Bar
instanceVariableNames: 'fubar' }
=> { Object subclass: #Fu instanceVariableNames: 'fubar'. Fu subclass: #Bar
instanceVariableNames: '' }
we have a DuplicateVariableException to handle, but state could conceivably
be preserved across the refactoring.
Does that explain the problem?
Best,
> Chris
>
> On Wed, Aug 29, 2018 at 9:20 PM <commits at source.squeak.org> wrote:
> >
> > Chris Muller uploaded a new version of Kernel to project The Inbox:
> > http://source.squeak.org/inbox/Kernel-cmm.1190.mcz
> >
> > ==================== Summary ====================
> >
> > Name: Kernel-cmm.1190
> > Author: cmm
> > Time: 29 August 2018, 9:20:01.027647 pm
> > UUID: b5a78e5d-c7fe-4e5d-9673-ee6208534ae1
> > Ancestors: Kernel-eem.1189
> >
> > - Remove unnecessary string literals from ClassBuilder>>#reservedNames.
> > - Fix and simplify ClassBuilder>>#validateInstvars:from:forSuper:.
> > ClassBuilder>>#validateClassvars:from:forSuper: may benefit from
> a similar change.
> >
> > =============== Diff against Kernel-eem.1189 ===============
> >
> > Item was changed:
> > ----- Method: ClassBuilder>>reservedNames (in category 'private') -----
> > reservedNames
> > "Return a list of names that must not be used for variables"
> > + ^#(self super thisContext #true #false #nil)!
> > - ^#('self' 'super' 'thisContext' 'true' 'false' 'nil'
> > - self super thisContext #true #false #nil).!
> >
> > Item was changed:
> > ----- Method: ClassBuilder>>validateInstvars:from:forSuper: (in
> category 'validation') -----
> > + validateInstvars: instVarArray from: oldClass forSuper: newSuper
> > - validateInstvars: instVarArray from: oldClass forSuper: newSuper
> > "Check if any of the instVars of oldClass conflict with the new
> superclass"
> > + | usedNames |
> > - | instVars usedNames temp |
> > - instVarArray isEmpty ifTrue:[^true]. "Okay"
> > - newSuper allowsSubInstVars ifFalse: [
> > - self error: newSuper printString, ' does not allow
> subclass inst vars. See allowsSubInstVars.'. ^ false].
> > -
> > - "Validate the inst var names"
> > usedNames := instVarArray asSet.
> > + oldClass ifNotNil: [ oldClass withAllSubclassesDo: [ : each |
> each == oldClass ifFalse: [usedNames addAll: each instVarNames] ] ].
> > + "Anything to possibly conflict?"
> > + usedNames isEmpty ifTrue: [ ^ true ].
> > + newSuper allowsSubInstVars ifFalse:
> > + [ self error: newSuper printString , ' does not allow
> subclass inst vars. See allowsSubInstVars.'.
> > + ^ false ].
> > + instVarArray asSet size = instVarArray size ifFalse:
> > + [ self error: instVarArray asBag sortedCounts first
> value, ' is multply defined.'.
> > + ^ false ].
> > + (usedNames intersection: self reservedNames) ifNotEmpty:
> > + [ : reservedWords | self error: reservedWords anyOne , '
> is a reserved name'.
> > + ^ false ].
> > + newSuper ifNotNil:
> > + [ | offendingVars |
> > + "If any variable names in subclasses conflict names in
> the new superclass, report the offending class and instVar name."
> > + newSuper withAllSuperclasses
> > + detect: [ : each | (offendingVars := each
> instVarNames intersection: usedNames) notEmpty ]
> > + ifFound:
> > + [ : offendingSuperclass |
> > + DuplicateVariableError new
> > + superclass: offendingSuperclass
> ;
> > + variable: offendingVars anyOne ;
> > + signal: offendingVars anyOne ,
> ' is already defined in ' , offendingSuperclass name ]
> > + ifNone: [ "no name conflicts" ] ].
> > + ^ true!
> > - usedNames size = instVarArray size
> > - ifFalse:[ instVarArray do:[:var|
> > - usedNames remove: var
> ifAbsent:[temp := var]].
> > - self error: temp,' is multiply defined'.
> ^false].
> > - (usedNames includesAnyOf: self reservedNames)
> > - ifTrue:[ self reservedNames do:[:var|
> > - (usedNames includes: var)
> ifTrue:[temp := var]].
> > - self error: temp,' is a reserved name'.
> ^false].
> > -
> > - newSuper == nil ifFalse:[
> > - usedNames := newSuper allInstVarNames asSet.
> > - instVarArray do:[:iv|
> > - (usedNames includes: iv) ifTrue:[
> > - newSuper withAllSuperclassesDo:[:cl|
> > - (cl instVarNames includes: iv)
> ifTrue:[temp := cl]].
> > - (DuplicateVariableError new)
> > - superclass: temp;
> > - variable: iv;
> > - signal: iv,' is already defined
> in ', temp name]]].
> > - oldClass == nil ifFalse:[
> > - usedNames := Set new: 20.
> > - oldClass allSubclassesDo:[:cl| usedNames addAll: cl
> instVarNames].
> > - instVars := instVarArray.
> > - newSuper == nil ifFalse:[instVars := instVars, newSuper
> allInstVarNames].
> > - instVars do:[:iv|
> > - (usedNames includes: iv) ifTrue:[
> > - (DuplicateVariableError new)
> > - superclass: oldClass;
> > - variable: iv;
> > - signal: iv,' is already defined
> in a subclass of ', temp name]]].
> > - ^true!
> >
> >
>
>
--
_,,,^..^,,,_
best, Eliot
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20180831/f0dd736c/attachment.html>
More information about the Squeak-dev
mailing list
|