smalltalk: respondsTo:/isKindOf:/isMemberOf: + 26 tests
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled

This commit is contained in:
2026-04-25 09:06:40 +00:00
parent 4ced16f04e
commit 1c4ac47450
3 changed files with 76 additions and 1 deletions

View File

@@ -539,6 +539,32 @@
(= selector "perform:with:with:with:")
(= selector "perform:with:with:with:with:"))
(st-send receiver (str (nth args 0)) (slice args 1 (len args))))
;; respondsTo: aSymbol — searches user method dicts only. Native
;; primitive selectors aren't enumerated, so e.g. `42 respondsTo:
;; #+` returns false. (The send still works because dispatch falls
;; through to st-num-send.) Documented limitation.
((= selector "respondsTo:")
(let
((sel-str (str (nth args 0)))
(target-cls (if (st-class-ref? receiver) (get receiver :name) cls))
(class-side? (st-class-ref? receiver)))
(not (= (st-method-lookup target-cls sel-str class-side?) nil))))
;; isKindOf: aClass — true iff the receiver's class chain reaches it.
((= selector "isKindOf:")
(let
((arg (nth args 0))
(target-cls (if (st-class-ref? receiver) "Metaclass" cls)))
(cond
((not (st-class-ref? arg)) false)
(else (st-class-inherits-from? target-cls (get arg :name))))))
;; isMemberOf: aClass — exact class match.
((= selector "isMemberOf:")
(let
((arg (nth args 0))
(target-cls (if (st-class-ref? receiver) "Metaclass" cls)))
(cond
((not (st-class-ref? arg)) false)
(else (= target-cls (get arg :name))))))
((or (= cls "SmallInteger") (= cls "Float"))
(st-num-send receiver selector args))
((or (= cls "String") (= cls "Symbol"))