Skip to content

Commit

Permalink
- implement #possiblyUsingClasses for ClassVariable. This returns all…
Browse files Browse the repository at this point in the history
… classes that the var could be referenced from

- #testPossiblyUsingClasses tests all the possible cases with examples from the image
- #isReferenced and #usingMethods are now using #possiblyUsingClasses to search
- add a dedicated test for #usingMethods

fixes #10113
  • Loading branch information
MarcusDenker committed Oct 12, 2021
1 parent ee5e48b commit 37adfff
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 10 deletions.
29 changes: 19 additions & 10 deletions src/Kernel/ClassVariable.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,7 @@ ClassVariable >> isPoolVariable [

{ #category : #testing }
ClassVariable >> isReferenced [
"For pools, fall back to the slow full search of all methods"
self definingClass isPool ifTrue: [ ^ super isReferenced ].
"A class variable can only be accessed in the defintionClass and its subclasses (both class and instance side)"
^ self definingClass withAllSubclasses anySatisfy: [ :behavior |
(behavior class hasMethodAccessingVariable: self) or: [ behavior hasMethodAccessingVariable: self ] ]
^ self possiblyUsingClasses anySatisfy: [ :behavior | behavior hasMethodAccessingVariable: self]
]

{ #category : #testing }
Expand All @@ -99,11 +95,24 @@ ClassVariable >> owningClass: anObject [
owningClass := anObject
]

{ #category : #queries }
ClassVariable >> possiblyUsingClasses [

| classes |
classes := self definingClass withAllSubclasses.

"For pool variables we need to add the poolUsers and it's subclasses"
self definingClass isPool ifTrue: [
classes addAll:
(self definingClass poolUsers flatCollect: [ :each |
each withAllSubclasses ]) ].

"we can access from both the class and the metaclass"
classes addAll: (classes collect: [ :class | class class ]).
^ classes
]

{ #category : #queries }
ClassVariable >> usingMethods [
"For pools, fall back to the slow full search of all methods"
self definingClass isPool ifTrue: [ ^ super usingMethods ].
"if we are a class variable, we only need to search the sublasses and metaclasses"
^ self definingClass withAllSubclasses flatCollect: [ :class |
(class whichMethodsReferTo: self), (class class whichMethodsReferTo: self) ]
^self possiblyUsingClasses flatCollect: [ :class | class whichMethodsReferTo: self ]
]
46 changes: 46 additions & 0 deletions src/Slot-Tests/ClassVariableTest.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,37 @@ ClassVariableTest >> testNotWrittenInMethodWhenItIsOnlyRead [
self deny: ((TestCase classVariableNamed: #DefaultTimeLimit) isWrittenIn: self class >> testSelector)
]

{ #category : #tests }
ClassVariableTest >> testPossiblyUsingClasses [
| variable |

"this is a normal class var"
variable := CharacterScanner classVariableNamed: #CompositionStopConditions.

"it can be accessed from the class and the meta class"
self assert: (variable possiblyUsingClasses includes: CharacterScanner).
self assert: (variable possiblyUsingClasses includes: CharacterScanner class).
"and subclasses"
self assert: (variable possiblyUsingClasses includes: CompositionScanner).
self assert: (variable possiblyUsingClasses includes: CompositionScanner class).

"Pools are more complex"
variable := TextConstants classVariableNamed: #Basal.
self assert: variable isPoolVariable.
"same for pool var: class and meta class of the defining class"
self assert: (variable possiblyUsingClasses includes: TextConstants).
self assert: (variable possiblyUsingClasses includes: TextConstants class).
"but in addition the all the users"
self assert: (variable possiblyUsingClasses includes: CharacterScanner).
self assert: (variable possiblyUsingClasses includes: CharacterScanner class).
"and subclasses"
self assert: (variable possiblyUsingClasses includes: CompositionScanner).
self assert: (variable possiblyUsingClasses includes: CompositionScanner class).



]

{ #category : #'tests - properties' }
ClassVariableTest >> testPropertyAtPut [

Expand Down Expand Up @@ -118,6 +149,21 @@ ClassVariableTest >> testScope [
self assert: (variable scope lookupVar: variable name) equals: variable
]

{ #category : #tests }
ClassVariableTest >> testUsingMethods [
| variable |
"The semantics of where to search is tested as part of #tesPossiblyUsingClasses"

variable := CharacterScanner classVariableNamed: #CompositionStopConditions.
self assert: (variable usingMethods includes: CompositionScanner>>#setStopConditions).

variable := TextConstants classVariableNamed: #DefaultMarginTabsArray.
self assert: variable isPoolVariable.
self assert: (variable usingMethods includes: TextConstants class>>#DefaultMarginTabsArray).
self assert: (variable usingMethods includes: TextStyle>>#newFontArray:)

]

{ #category : #'tests - properties' }
ClassVariableTest >> testWritingToContext [

Expand Down

0 comments on commit 37adfff

Please sign in to comment.