Hi,
I accidentally accepted a class definition for an existing class MyClass which had subclasses and defined the class to be a subclass of itself: MyNamespace.SubNamespace defineClass: #MyClass superclass: #{SubNamespace.MyClass} indexedType: #none private: false instanceVariableNames: '' classInstanceVariableNames: '' imports: '' category: 'MyCategory' After several minutes I wondered what VisualWorks was doing all the time and interrupted it. BehaviorBuilderRecord>>verify was in an endless loop in the following statements when verifying a record for a subclass of MyClass, which was done before verifying the record for MyClass: [s == nil] whileFalse: [s fullName = self fullName ifTrue: [self buildError: ((#errSubclassItself << #dialogs >> 'The behavior <1s> is being made a subclass of itself.') expandMacrosWith: self fullName)]. s := s superclass]. "s := s superclass" always resulted in MyClass. A fix for BehaviorBuilderRecord>>verify is attached. Joachim Geidel <?xml version="1.0"?> <st-source> <time-stamp>From VisualWorks® NonCommercial, 7.4.1 of 30. Mai 2006 on 17. Juli 2006 at 18:40:41</time-stamp> <methods> <class-id>Kernel.BehaviorBuilderRecord</class-id> <category>mutation</category> <body package="Kernel-Classes" selector="verify">verify | list superType cType s | s := self superclass. [s == nil] whileFalse: [| fullName | fullName := s fullName. fullName = self fullName ifTrue: [self buildError: ((#errSubclassItself << #dialogs >> 'The behavior <1s> is being made a subclass of itself.') expandMacrosWith: self fullName)]. fullName = s superclass fullName ifTrue: [self buildError: ((#errSubclassItself << #dialogs >> 'The behavior <1s> is being made a subclass of itself.') expandMacrosWith: fullName)]. s := s superclass]. superType := self superBehaviorType. ((Behavior isType: self behaviorType legalSubclassTypeForSuperclassType: superType) or: [Behavior isType: self behaviorType promotableSubclassTypeForSuperclassType: superType]) ifFalse: [self buildError: (((#errCannotBeSubclasses << #dialogs >> 'Classes of type <1s> cannot be subclasses of classes of type <2s>.') expandMacrosWith: self behaviorType with: superType))]. cType := (Behavior isType: self behaviorType promotableSubclassTypeForSuperclassType: superType) ifTrue: [superType] ifFalse: [self behaviorType]. list := self allInstVarNames. ((#(#immediate #bytes) includes: cType) and: [list isEmpty not]) ifTrue: [self buildError: (#ByteTypeInstanceVariables << #dialogs >> 'Byte-type objects cannot have named instance variables')]. list size > 4095 ifTrue: [self buildError: (#errInstanceLimit << #dialogs >> 'An object is limited to only 255 named instance variables')]. list := list, #('self' 'super' 'thisContext' 'true' 'false' 'nil'). list size = list asSet size ifFalse: [list do: [:str | (list occurrencesOf: str) = 1 ifFalse: [self buildError: ((#variableOverloaded << #dialogs >> 'The variable name "<1s>" is overloaded for <2s>' ) expandMacrosWith: str with: self fullName)]]].</body> </methods> </st-source> |
As Kent Beck would say, "Then don't do that" :-)
This is now AR 50997. At 12:46 PM 7/17/2006, Joachim Geidel wrote: >Hi, > >I accidentally accepted a class definition for an existing class MyClass >which had subclasses and defined the class to be a subclass of itself: > >MyNamespace.SubNamespace defineClass: #MyClass > superclass: #{SubNamespace.MyClass} > indexedType: #none > private: false > instanceVariableNames: '' > classInstanceVariableNames: '' > imports: '' > category: 'MyCategory' > >After several minutes I wondered what VisualWorks was doing all the time >and interrupted it. BehaviorBuilderRecord>>verify was in an endless loop >in the following statements when verifying a record for a subclass of >MyClass, which was done before verifying the record for MyClass: > > [s == nil] whileFalse: > [s fullName = self fullName ifTrue: > [self buildError: ((#errSubclassItself << #dialogs >> 'The behavior ><1s> is being made a subclass of itself.') expandMacrosWith: self >fullName)]. > s := s superclass]. > >"s := s superclass" always resulted in MyClass. A fix for >BehaviorBuilderRecord>>verify is attached. > >Joachim Geidel > > ><?xml version="1.0"?> > ><st-source> ><time-stamp>From VisualWorks® NonCommercial, 7.4.1 of 30. Mai 2006 on 17. Juli 2006 at 18:40:41</time-stamp> > > ><methods> ><class-id>Kernel.BehaviorBuilderRecord</class-id> <category>mutation</category> > ><body package="Kernel-Classes" selector="verify">verify > > | list superType cType s | > s := self superclass. > [s == nil] whileFalse: > [| fullName | > fullName := s fullName. > fullName = self fullName ifTrue: > [self buildError: ((#errSubclassItself << #dialogs >> 'The behavior <1s> is being made a subclass of itself.') expandMacrosWith: self fullName)]. > fullName = s superclass fullName ifTrue: > [self buildError: ((#errSubclassItself << #dialogs >> 'The behavior <1s> is being made a subclass of itself.') expandMacrosWith: fullName)]. > s := s superclass]. > superType := self superBehaviorType. > ((Behavior isType: self behaviorType legalSubclassTypeForSuperclassType: superType) or: > [Behavior isType: self behaviorType promotableSubclassTypeForSuperclassType: superType]) > ifFalse: [self buildError: > (((#errCannotBeSubclasses << #dialogs >> 'Classes of type <1s> cannot be subclasses of classes of type <2s>.') > expandMacrosWith: self behaviorType > with: superType))]. > cType := (Behavior isType: self behaviorType promotableSubclassTypeForSuperclassType: superType) > ifTrue: [superType] > ifFalse: [self behaviorType]. > list := self allInstVarNames. > ((#(#immediate #bytes) includes: cType) and: [list isEmpty not]) ifTrue: > [self buildError: (#ByteTypeInstanceVariables << #dialogs >> 'Byte-type objects cannot have named instance variables')]. > list size > 4095 ifTrue: > [self buildError: (#errInstanceLimit << #dialogs >> 'An object is limited to only 255 named instance variables')]. > list := list, #('self' 'super' 'thisContext' 'true' 'false' 'nil'). > list size = list asSet size ifFalse: > [list do: > [:str | > (list occurrencesOf: str) = 1 ifFalse: > [self buildError: ((#variableOverloaded << #dialogs >> 'The variable name "<1s>" is overloaded for <2s>' ) expandMacrosWith: str with: self fullName)]]].</body> ></methods> > ></st-source> -- Alan Knight [|], Cincom Smalltalk Development [hidden email] [hidden email] http://www.cincom.com/smalltalk "The Static Typing Philosophy: Make it fast. Make it right. Make it run." - Niall Ross |
In reply to this post by Joachim Geidel
I should have tested my bug fix a bit more thoroughly. :-(
Forgot to check if the superclass record is nil before asking for its fullName. The patch of the patch is attached. Joachim > Hi, > > I accidentally accepted a class definition for an existing class MyClass > which had subclasses and defined the class to be a subclass of itself: > > MyNamespace.SubNamespace defineClass: #MyClass > superclass: #{SubNamespace.MyClass} > indexedType: #none > private: false > instanceVariableNames: '' > classInstanceVariableNames: '' > imports: '' > category: 'MyCategory' > > After several minutes I wondered what VisualWorks was doing all the time > and interrupted it. BehaviorBuilderRecord>>verify was in an endless loop > in the following statements when verifying a record for a subclass of > MyClass, which was done before verifying the record for MyClass: > > [s == nil] whileFalse: > [s fullName = self fullName ifTrue: > [self buildError: ((#errSubclassItself << #dialogs >> 'The behavior > <1s> is being made a subclass of itself.') expandMacrosWith: self > fullName)]. > s := s superclass]. > > "s := s superclass" always resulted in MyClass. A fix for > BehaviorBuilderRecord>>verify is attached. > > Joachim Geidel <?xml version="1.0"?> <st-source> <time-stamp>From VisualWorks® NonCommercial, 7.4.1 of 30. Mai 2006 on 17. Juli 2006 at 18:57:41</time-stamp> <methods> <class-id>Kernel.BehaviorBuilderRecord</class-id> <category>mutation</category> <body package="Kernel-Classes" selector="verify">verify | list superType cType s | s := self superclass. [s == nil] whileFalse: [| fullName | fullName := s fullName. fullName = self fullName ifTrue: [self buildError: ((#errSubclassItself << #dialogs >> 'The behavior <1s> is being made a subclass of itself.') expandMacrosWith: self fullName)]. (s superclass ~~ nil and: [fullName = s superclass fullName]) ifTrue: [self buildError: ((#errSubclassItself << #dialogs >> 'The behavior <1s> is being made a subclass of itself.') expandMacrosWith: fullName)]. s := s superclass]. superType := self superBehaviorType. ((Behavior isType: self behaviorType legalSubclassTypeForSuperclassType: superType) or: [Behavior isType: self behaviorType promotableSubclassTypeForSuperclassType: superType]) ifFalse: [self buildError: (((#errCannotBeSubclasses << #dialogs >> 'Classes of type <1s> cannot be subclasses of classes of type <2s>.') expandMacrosWith: self behaviorType with: superType))]. cType := (Behavior isType: self behaviorType promotableSubclassTypeForSuperclassType: superType) ifTrue: [superType] ifFalse: [self behaviorType]. list := self allInstVarNames. ((#(#immediate #bytes) includes: cType) and: [list isEmpty not]) ifTrue: [self buildError: (#ByteTypeInstanceVariables << #dialogs >> 'Byte-type objects cannot have named instance variables')]. list size > 4095 ifTrue: [self buildError: (#errInstanceLimit << #dialogs >> 'An object is limited to only 255 named instance variables')]. list := list, #('self' 'super' 'thisContext' 'true' 'false' 'nil'). list size = list asSet size ifFalse: [list do: [:str | (list occurrencesOf: str) = 1 ifFalse: [self buildError: ((#variableOverloaded << #dialogs >> 'The variable name "<1s>" is overloaded for <2s>' ) expandMacrosWith: str with: self fullName)]]].</body> </methods> </st-source> |
Free forum by Nabble | Edit this page |