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]].
Cheers,
Sean