diff --git a/host/chez/host-static-classes.ss b/host/chez/host-static-classes.ss index eb35534..deb5d40 100644 --- a/host/chez/host-static-classes.ss +++ b/host/chez/host-static-classes.ss @@ -535,6 +535,24 @@ ((string=? iface "IFn") (or (procedure? val) (keyword? val) (symbol-t? val) (pmap? val) (pset? val) (pvec? val))) + ;; host-class interfaces libraries branch on (data.json, etc.). + ;; Matched by last segment, so java.util.Map and Map both hit. + ((string=? iface "Named") (or (keyword? val) (symbol-t? val))) + ((string=? iface "CharSequence") (string? val)) + ((string=? iface "Number") (number? val)) + ((string=? iface "Map") (or (pmap? val) (htable-sorted-map? val))) + ((string=? iface "Set") (or (pset? val) (htable-sorted-set? val))) + ;; a Java List is a vector or a seq/list — not a set or map. + ((string=? iface "List") + (or (and (pvec? val) (not (jolt-map-entry? val))) + (cseq? val) (empty-list-t? val) (jolt-lazyseq? val))) + ;; a Java Collection is any of those plus a set — but NOT a map. + ((string=? iface "Collection") + (or (pvec? val) (pset? val) (cseq? val) (empty-list-t? val) + (jolt-lazyseq? val) (htable-sorted-set? val))) + ((string=? iface "Associative") + (or (pmap? val) (htable-sorted-map? val) + (and (pvec? val) (not (jolt-map-entry? val))))) (else 'none)))) (if (eq? hit 'none) 'pass (if hit #t #f)))))) diff --git a/test/chez/corpus.edn b/test/chez/corpus.edn index fa60339..e476c58 100644 --- a/test/chez/corpus.edn +++ b/test/chez/corpus.edn @@ -2971,4 +2971,14 @@ {:suite "protocols / extend on host classes" :label "dispatch by java.util.Map/Collection/CharSequence" :expected "[:map :coll :str :obj]" :actual "(do (defprotocol W (-w [x])) (extend java.util.Map W {:-w (fn [_] :map)}) (extend java.util.Collection W {:-w (fn [_] :coll)}) (extend java.lang.CharSequence W {:-w (fn [_] :str)}) (extend java.lang.Object W {:-w (fn [_] :obj)}) [(-w {:a 1}) (-w [1 2]) (-w \"s\") (-w 42)])"} {:suite "protocols / extend on host classes" :label "satisfies? via java.util.Map" :expected "true" :actual "(do (defprotocol Q (qq [x])) (extend java.util.Map Q {:qq (fn [_] :m)}) (satisfies? Q {}))"} {:suite "protocols / extend on host classes" :label "extends? on a qualified host class" :expected "true" :actual "(do (defprotocol Qe (qe [x])) (extend java.util.Collection Qe {:qe (fn [_] :c)}) (extends? Qe java.util.Collection))"} + {:suite "interop / instance? on host interfaces" :label "keyword is Named" :expected "true" :actual "(instance? clojure.lang.Named :a)"} + {:suite "interop / instance? on host interfaces" :label "string is CharSequence" :expected "true" :actual "(instance? java.lang.CharSequence \"s\")"} + {:suite "interop / instance? on host interfaces" :label "number is Number" :expected "true" :actual "(instance? java.lang.Number 42)"} + {:suite "interop / instance? on host interfaces" :label "map is java.util.Map" :expected "true" :actual "(instance? java.util.Map {:a 1})"} + {:suite "interop / instance? on host interfaces" :label "vector is java.util.List" :expected "true" :actual "(instance? java.util.List [1 2])"} + {:suite "interop / instance? on host interfaces" :label "list is java.util.Collection" :expected "true" :actual "(instance? java.util.Collection (list 1))"} + {:suite "interop / instance? on host interfaces" :label "set is java.util.Set" :expected "true" :actual "(instance? java.util.Set #{1})"} + {:suite "interop / instance? on host interfaces" :label "map is not a Collection" :expected "false" :actual "(instance? java.util.Collection {:a 1})"} + {:suite "interop / instance? on host interfaces" :label "vector is Associative" :expected "true" :actual "(instance? clojure.lang.Associative [1])"} + {:suite "interop / instance? on host interfaces" :label "string is not Number" :expected "false" :actual "(instance? java.lang.Number \"s\")"} ]