If I add a class variable with the same name as an existing class, I get a warning, which seems reasonable enough (although the warning looks like an error, so I didn't realize I could just hit "proceed"). However, if I subsequently remove the class variable, I get a dialog with two options: 1. move the name to Undeclared 2. cancel
It seems like, if a name is already used globally, it should not be Undeclared, no? What happens if a name is a class name and in Undeclared - any conflict?
Thanks. Sean
Example: Object subclass: #AClassInTheSystem instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'SpdSystemSpecs'. Object subclass: #ClassWithGlobalSameNameAsAClass instanceVariableNames: '' classVariableNames: 'AClassInTheSystem' poolDictionaries: '' category: 'SpdSystemSpecs'.
Upon further inspection, the behavior of Class>>declare: is different from Class>>addClassVarName: in how it signals the exception that a class var name is already used. #declare: throws a resumable error (which in my above example is correct because the name is not used in the class or its subclasses), while addClassVarName: throws a non-resumable Error.
The key seems to be the use (in both methods) of "self bindingOf: var" to determine if there is a conflict. Since #bindingOf: checks for globals, too (e.g. class names), it returns even if the current class and its hierarchy do not use the name. This misunderstanding is even reflected in the error message: '... is already used as a variable name in class'
I fixed both to use Class>>canFindWithoutEnvironment:, which is what we want to know, but should this error be resumable or not (i.e. if the class already has a class or pool var with that name)?
In original Class>>declare: (newVars reject: [:var | self classPool includesKey: var]) do: [:var | "adding" "check if new vars defined elsewhere" (self bindingOf: var) ifNotNil:[ (DuplicateVariableError new) superclass: superclass; "fake!!!" variable: var; signal: var , ' is defined elsewhere'. conflicts := true]].
In original Class>>addClassVarName: self withAllSubclasses do: [:subclass | (subclass bindingOf: symbol) ifNotNil:[ ^ self error: aString , ' is already used as a variable name in class ' , subclass name]].
I submitted a fix and tests to the inbox - KernelTests-spd.149.mcz & Kernel-spd.444.mcz. It fixes and unifies the behavior of both #declare: and #addClassVarName:
Sean
beginners@lists.squeakfoundation.org