From 1f8da01b8e831807c6970db01a538c606e3a9af0 Mon Sep 17 00:00:00 2001 From: davidnolen Date: Wed, 23 Oct 2024 15:24:40 -0400 Subject: [PATCH 01/42] (wip) --- deps.edn | 3 +- src/test/clojure/cljs/analyzer/specs.cljc | 130 ++++++++++++++++++++++ 2 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 src/test/clojure/cljs/analyzer/specs.cljc diff --git a/deps.edn b/deps.edn index 8925f7e20..9a8f42b00 100644 --- a/deps.edn +++ b/deps.edn @@ -13,7 +13,8 @@ :main-opts ["-i" "src/test/cljs_cli/cljs_cli/test_runner.clj" "-e" "(cljs-cli.test-runner/-main)"]} :compiler.test {:extra-paths ["src/test/cljs" "src/test/cljs_build" "src/test/cljs_cp" - "src/test/clojure" "src/test/self"]} + "src/test/clojure" "src/test/self"] + :extra-deps {org.clojure/spec.alpha {:mvn/version "0.5.238"}}} :compiler.test.run {:main-opts ["-i" "src/test/clojure/cljs/test_runner.clj" "-e" "(cljs.test-runner/-main)"]} :runtime.test.build {:extra-paths ["src/test/cljs"] diff --git a/src/test/clojure/cljs/analyzer/specs.cljc b/src/test/clojure/cljs/analyzer/specs.cljc new file mode 100644 index 000000000..79be68eaa --- /dev/null +++ b/src/test/clojure/cljs/analyzer/specs.cljc @@ -0,0 +1,130 @@ +;; Copyright (c) Rich Hickey. All rights reserved. +;; The use and distribution terms for this software are covered by the +;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) +;; which can be found in the file epl-v10.html at the root of this distribution. +;; By using this software in any fashion, you are agreeing to be bound by +;; the terms of this license. +;; You must not remove this notice, or any other, from this software. + +(ns cljs.analyzer.specs + (:require [clojure.spec.alpha :as s])) + +(s/def ::op keyword?) +(s/def ::form any?) +(s/def ::env map?) +(s/def ::context #{:expr :return :statement}) + +(defmulti node :op) +(s/def ::node (s/multi-spec node :op)) + +(s/def ::test ::node) +(s/def ::then ::node) +(s/def ::else ::node) + +;; TODO: :tag +(s/def ::base + (s/keys + :req-un [::op ::env ::form])) + +(defmethod node :if [_] + (s/merge ::base + (s/keys + :req-un [::test ::then] + :opt-un [::else]))) + +(s/def ::literal? boolean?) +(s/def ::val any?) + +(defmethod node :const [_] + (s/merge ::base + (s/keys + :req-un [::literal? ::val] + :opt-un []))) + +(s/def ::keys (s/* ::node)) +(s/def ::vals (s/* ::node)) + +(defmethod node :map [_] + (s/merge ::base + (s/keys :req-un [::keys ::vals]))) + +(s/def ::items (s/* ::node)) + +(defmethod node :list [_] + (s/merge ::base + (s/keys + :req-un [::items]))) + +(defmethod node :vector [_] + (s/merge ::base + (s/keys + :req-un [::items]))) + +(defmethod node :set [_] + (s/merge ::base + (s/keys + :req-un [::items]))) + +(defmethod node :js-object [_] + (s/merge ::base + (s/keys + :req-un [::keys ::vals]))) + +(defmethod node :js-array [_] + (s/merge ::base + (s/keys + :req-un [::items]))) + +(s/def ::var ::node) +(s/def ::sym ::node) +(s/def ::meta map?) + +(defmethod node :the-var [_] + (s/merge ::base + (s/keys + :opt-un [::var ::sym ::meta]))) + +(s/def ::nodes (s/* ::node)) +(s/def ::default ::node) + +(defmethod node ::case [_] + (s/merge ::base + (s/keys + :req-un [::test ::nodes ::default]))) + +(defmethod node ::case-node [_] + (s/merge ::base + (s/keys + :req-un [::tests ::then]))) + +(comment + + (s/valid? ::node 1) + (s/valid? ::node + {:op :const + :env {} + :form 1 + :literal? true + :val 1}) + + (s/explain-data ::node + {:op :if + :env {} + :form '(if true true false) + :test {:op :const + :env {} + :form true + :literal? true + :val true} + :then {:op :const + :env {} + :form true + :literal? true + :val true} + :else {:op :const + :env 1 + :form false + :literal? true + :val false}}) + + ) From 6087f8eb727860a305b91e9710371a51a62ddeea Mon Sep 17 00:00:00 2001 From: davidnolen Date: Wed, 23 Oct 2024 16:14:25 -0400 Subject: [PATCH 02/42] (wip) --- src/test/clojure/cljs/analyzer/specs.cljc | 73 +++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/src/test/clojure/cljs/analyzer/specs.cljc b/src/test/clojure/cljs/analyzer/specs.cljc index 79be68eaa..42717c49d 100644 --- a/src/test/clojure/cljs/analyzer/specs.cljc +++ b/src/test/clojure/cljs/analyzer/specs.cljc @@ -26,6 +26,20 @@ (s/keys :req-un [::op ::env ::form])) +(s/def ::name symbol?) +(s/def :cljs.analyzer.specs.binding/local + #{:arg :catch :fn :let :letfn :loop :field}) +(s/def ::variadic? boolean?) +(s/def ::init ::node) +(s/def ::shadow ::node) + +(defmethod node ::binding [_] + (s/merge + ::base + (s/keys + :req-un [::name :cljs.analyzer.specs.binding/local] + :opt-un [::variadic? ::init ::shadow]))) + (defmethod node :if [_] (s/merge ::base (s/keys @@ -97,6 +111,65 @@ (s/keys :req-un [::tests ::then]))) +(defmethod node ::case-test [_] + (s/merge ::base + (s/keys + :req-un [::test]))) + +(defmethod node ::case-then [_] + (s/merge ::base + (s/keys + :req-un [::then]))) + +(s/def ::the-var ::node) + +(defmethod node ::def [_] + (s/merge ::base + (s/keys + :req-un [::name] + :opt-un [::init ::the-var]))) + +(s/def ::body ::node) +(s/def ::t symbol?) + +(defmethod node ::defrecord [_] + (s/merge ::base + (s/keys + :req-un [::t ::body]))) + +(defmethod node ::deftype [_] + (s/merge ::base + (s/keys + :req-un [::t ::body]))) + +(s/def ::statements ::node) +(s/def ::ret ::node) +(s/def ::body? boolean?) + +(defmethod node ::do [_] + (s/merge ::base + (s/keys + :req-un [::statements ::ret] + :opt-un [::body?]))) + +(s/def ::local ::node) +(s/def ::max-fixed-arity int?) +(s/def ::methods (s/+ ::node)) + +(defmethod node ::fn [_] + (s/merge ::base + (s/keys + :req-un [::variadic? ::max-fixed-arity ::methods] + :opt-un [::local]))) + +(s/def ::fixed-arity int?) +(s/def ::params (s/* ::node)) + +(defmethod node ::fn-method [_] + (s/merge ::base + (s/keys + :req-un [::fixed-arity ::params ::body]))) + (comment (s/valid? ::node 1) From 56a67215e5890ad4fe445d5c65eec0825c4cce22 Mon Sep 17 00:00:00 2001 From: davidnolen Date: Wed, 23 Oct 2024 17:09:23 -0400 Subject: [PATCH 03/42] * typos * (wip) --- src/test/clojure/cljs/analyzer/specs.cljc | 52 ++++++++++++++++++----- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/src/test/clojure/cljs/analyzer/specs.cljc b/src/test/clojure/cljs/analyzer/specs.cljc index 42717c49d..65868c7ab 100644 --- a/src/test/clojure/cljs/analyzer/specs.cljc +++ b/src/test/clojure/cljs/analyzer/specs.cljc @@ -33,7 +33,7 @@ (s/def ::init ::node) (s/def ::shadow ::node) -(defmethod node ::binding [_] +(defmethod node :binding [_] (s/merge ::base (s/keys @@ -84,6 +84,13 @@ (s/keys :req-un [::keys ::vals]))) +(s/def ::ns symbol?) + +(defmethod node :js-var [_] + (s/merge ::base + (s/keys + :req-un [::ns ::name]))) + (defmethod node :js-array [_] (s/merge ::base (s/keys @@ -101,29 +108,29 @@ (s/def ::nodes (s/* ::node)) (s/def ::default ::node) -(defmethod node ::case [_] +(defmethod node :case [_] (s/merge ::base (s/keys :req-un [::test ::nodes ::default]))) -(defmethod node ::case-node [_] +(defmethod node :case-node [_] (s/merge ::base (s/keys :req-un [::tests ::then]))) -(defmethod node ::case-test [_] +(defmethod node :case-test [_] (s/merge ::base (s/keys :req-un [::test]))) -(defmethod node ::case-then [_] +(defmethod node :case-then [_] (s/merge ::base (s/keys :req-un [::then]))) (s/def ::the-var ::node) -(defmethod node ::def [_] +(defmethod node :def [_] (s/merge ::base (s/keys :req-un [::name] @@ -132,12 +139,12 @@ (s/def ::body ::node) (s/def ::t symbol?) -(defmethod node ::defrecord [_] +(defmethod node :defrecord [_] (s/merge ::base (s/keys :req-un [::t ::body]))) -(defmethod node ::deftype [_] +(defmethod node :deftype [_] (s/merge ::base (s/keys :req-un [::t ::body]))) @@ -146,7 +153,7 @@ (s/def ::ret ::node) (s/def ::body? boolean?) -(defmethod node ::do [_] +(defmethod node :do [_] (s/merge ::base (s/keys :req-un [::statements ::ret] @@ -156,7 +163,7 @@ (s/def ::max-fixed-arity int?) (s/def ::methods (s/+ ::node)) -(defmethod node ::fn [_] +(defmethod node :fn [_] (s/merge ::base (s/keys :req-un [::variadic? ::max-fixed-arity ::methods] @@ -165,11 +172,34 @@ (s/def ::fixed-arity int?) (s/def ::params (s/* ::node)) -(defmethod node ::fn-method [_] +(defmethod node :fn-method [_] (s/merge ::base (s/keys :req-un [::fixed-arity ::params ::body]))) +(s/def ::method symbol?) +(s/def ::target ::node) +(s/def ::args (s/* ::node)) + +(defmethod node :host-call [_] + (s/merge ::base + (s/keys + :req-un [::method ::target ::args]))) + +(s/def ::field symbol?) + +(defmethod node :host-field [_] + (s/merge ::base + (s/keys + :req-un [::field ::target]))) + +(s/def ::fn ::node) + +(defmethod node :invoke [_] + (s/merge ::base + (s/keys + :req-un [::fn ::args]))) + (comment (s/valid? ::node 1) From 8d8a55a390772046393b203cf4fdca8e38851ecf Mon Sep 17 00:00:00 2001 From: davidnolen Date: Wed, 23 Oct 2024 18:16:02 -0400 Subject: [PATCH 04/42] * rest of the bits from the ast-ref --- src/test/clojure/cljs/analyzer/specs.cljc | 99 +++++++++++++++++++++-- 1 file changed, 94 insertions(+), 5 deletions(-) diff --git a/src/test/clojure/cljs/analyzer/specs.cljc b/src/test/clojure/cljs/analyzer/specs.cljc index 65868c7ab..60d264b0f 100644 --- a/src/test/clojure/cljs/analyzer/specs.cljc +++ b/src/test/clojure/cljs/analyzer/specs.cljc @@ -84,6 +84,11 @@ (s/keys :req-un [::keys ::vals]))) +(defmethod node :js-array [_] + (s/merge ::base + (s/keys + :req-un [::items]))) + (s/def ::ns symbol?) (defmethod node :js-var [_] @@ -91,11 +96,6 @@ (s/keys :req-un [::ns ::name]))) -(defmethod node :js-array [_] - (s/merge ::base - (s/keys - :req-un [::items]))) - (s/def ::var ::node) (s/def ::sym ::node) (s/def ::meta map?) @@ -200,6 +200,95 @@ (s/keys :req-un [::fn ::args]))) +(s/def ::bindings (s/* ::node)) + +(defmethod node :let [_] + (s/merge ::base + (s/keys + :req-un [::bindings ::body]))) + +(defmethod node :letfn [_] + (s/merge ::base + (s/keys + :req-un [::bindings ::body]))) + +(defmethod node :local [_] + (s/merge ::base + (s/keys + :req-un [:cljs.analyzer.specs.binding/local ::name]))) + +(defmethod node :loop [_] + (s/merge ::base + (s/keys + :req-un [::bindings ::body]))) + +(s/def ::class ::node) + +(defmethod node :new [_] + (s/merge ::base + (s/keys + :req-un [::class ::args]))) + +(defmethod node :no-op [_] + ::base) + +(defmethod node :no-op [_] + ::base) + +(defmethod node :no-op [_] + ::base) + +(s/def ::expr ::node) + +(defmethod node :quote [_] + (s/merge ::base + (s/keys + :req-un [::expr ::literal?]))) + +(s/def ::exprs (s/* ::nodes)) + +(defmethod node :recur [_] + (s/merge ::base + (s/keys + :req-un [::exprs]))) + +(defmethod node :set [_] + (s/merge ::base + (s/keys + :req-un [::items]))) + +(defmethod node :set! [_] + (s/merge ::base + (s/keys + :req-un [::target ::val]))) + +(s/def ::exception ::node) + +(defmethod node :throw [_] + (s/merge ::base + (s/keys + :req-un [::exception]))) + +(s/def ::catch ::node) +(s/def ::finally ::node) + +(defmethod node :try [_] + (s/merge ::base + (s/keys + :req-un [::body ::catch ::name ::finally]))) + +(defmethod node :var [_] + (s/merge ::base + (s/keys + :req-un [::ns ::name]))) + +(s/def ::meta ::node) + +(defmethod node :with-meta [_] + (s/merge ::base + (s/keys + :req-un [::meta ::expr]))) + (comment (s/valid? ::node 1) From b28addc50fb74106895895b774f8570d9c8c7fe3 Mon Sep 17 00:00:00 2001 From: davidnolen Date: Thu, 24 Oct 2024 07:24:03 -0400 Subject: [PATCH 05/42] * add spec tests ns * add first test --- src/test/clojure/cljs/analyzer/spec_tests.clj | 22 +++++++++++++++++++ src/test/clojure/cljs/analyzer/specs.cljc | 6 +++-- 2 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 src/test/clojure/cljs/analyzer/spec_tests.clj diff --git a/src/test/clojure/cljs/analyzer/spec_tests.clj b/src/test/clojure/cljs/analyzer/spec_tests.clj new file mode 100644 index 000000000..e16c834ff --- /dev/null +++ b/src/test/clojure/cljs/analyzer/spec_tests.clj @@ -0,0 +1,22 @@ +;; Copyright (c) Rich Hickey. All rights reserved. +;; The use and distribution terms for this software are covered by the +;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) +;; which can be found in the file epl-v10.html at the root of this distribution. +;; By using this software in any fashion, you are agreeing to be bound by +;; the terms of this license. +;; You must not remove this notice, or any other, from this software. + +(ns cljs.analyzer.spec-tests + (:require [cljs.analyzer-tests :refer [analyze ns-env]] + [cljs.analyzer.specs :as a] + [clojure.test :as test :refer [deftest is]] + [clojure.spec.alpha :as s])) + +(deftest test-if + (is '(s/valid? ::a/node (analyze ns-env '(if true true false))))) + +(comment + + (test/run-tests) + + ) diff --git a/src/test/clojure/cljs/analyzer/specs.cljc b/src/test/clojure/cljs/analyzer/specs.cljc index 60d264b0f..64b2e8835 100644 --- a/src/test/clojure/cljs/analyzer/specs.cljc +++ b/src/test/clojure/cljs/analyzer/specs.cljc @@ -52,8 +52,10 @@ (defmethod node :const [_] (s/merge ::base (s/keys - :req-un [::literal? ::val] - :opt-un []))) + :req-un [::val] + ;; ::literal? is required in the AST REF, but we don't actually use it + ;; should check tools.analyzer + :opt-un [::literal?]))) (s/def ::keys (s/* ::node)) (s/def ::vals (s/* ::node)) From 2009627858d8eefc98072ebdf0aebcbfce293c41 Mon Sep 17 00:00:00 2001 From: davidnolen Date: Thu, 24 Oct 2024 07:32:36 -0400 Subject: [PATCH 06/42] * fix assertion, another one --- src/test/clojure/cljs/analyzer/spec_tests.clj | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/clojure/cljs/analyzer/spec_tests.clj b/src/test/clojure/cljs/analyzer/spec_tests.clj index e16c834ff..ff8888ec5 100644 --- a/src/test/clojure/cljs/analyzer/spec_tests.clj +++ b/src/test/clojure/cljs/analyzer/spec_tests.clj @@ -13,7 +13,8 @@ [clojure.spec.alpha :as s])) (deftest test-if - (is '(s/valid? ::a/node (analyze ns-env '(if true true false))))) + (is (s/valid? ::a/node (analyze ns-env '(if true true)))) + (is (s/valid? ::a/node (analyze ns-env '(if true true false))))) (comment From 9f988d8eadbfb632651318e005e9111bd6a1307a Mon Sep 17 00:00:00 2001 From: davidnolen Date: Thu, 24 Oct 2024 07:40:42 -0400 Subject: [PATCH 07/42] * add basic do * failing let, due to missing :form --- src/test/clojure/cljs/analyzer/spec_tests.clj | 14 ++++++++++++++ src/test/clojure/cljs/analyzer/specs.cljc | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/test/clojure/cljs/analyzer/spec_tests.clj b/src/test/clojure/cljs/analyzer/spec_tests.clj index ff8888ec5..b514d6a7d 100644 --- a/src/test/clojure/cljs/analyzer/spec_tests.clj +++ b/src/test/clojure/cljs/analyzer/spec_tests.clj @@ -16,8 +16,22 @@ (is (s/valid? ::a/node (analyze ns-env '(if true true)))) (is (s/valid? ::a/node (analyze ns-env '(if true true false))))) +(deftest test-do + (is (s/valid? ::a/node (analyze ns-env '(do)))) + (is (s/valid? ::a/node (analyze ns-env '(do 1)))) + (is (s/valid? ::a/node (analyze ns-env '(do 1 2 3))))) + +(deftest test-let + (is (s/valid? ::a/node (analyze ns-env '(let [])))) + ;(is (s/valid? ::a/node (analyze ns-env '(let [x 1])))) + ;(is (s/valid? ::a/node (analyze ns-env '(let [x 1] x)))) + ) + (comment (test/run-tests) + ;; binding is missing :form + (s/explain ::a/node (analyze ns-env '(let [x 1]))) + ) diff --git a/src/test/clojure/cljs/analyzer/specs.cljc b/src/test/clojure/cljs/analyzer/specs.cljc index 64b2e8835..a99818c3f 100644 --- a/src/test/clojure/cljs/analyzer/specs.cljc +++ b/src/test/clojure/cljs/analyzer/specs.cljc @@ -151,7 +151,7 @@ (s/keys :req-un [::t ::body]))) -(s/def ::statements ::node) +(s/def ::statements (s/* ::node)) (s/def ::ret ::node) (s/def ::body? boolean?) From 2a8db4df2ea2591507c71d8e6847e7ac4f9da3b4 Mon Sep 17 00:00:00 2001 From: davidnolen Date: Fri, 25 Oct 2024 08:48:43 -0400 Subject: [PATCH 08/42] * :binding missing :form * next problem, some children might just be nil --- src/main/clojure/cljs/analyzer.cljc | 1 + src/test/clojure/cljs/analyzer/spec_tests.clj | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/clojure/cljs/analyzer.cljc b/src/main/clojure/cljs/analyzer.cljc index 376956d8e..4e52de69f 100644 --- a/src/main/clojure/cljs/analyzer.cljc +++ b/src/main/clojure/cljs/analyzer.cljc @@ -2417,6 +2417,7 @@ shadow (or (handle-symbol-local name (get-in env [:locals name])) (get-in env [:js-globals name])) be {:name name + :form name :line line :column col :init init-expr diff --git a/src/test/clojure/cljs/analyzer/spec_tests.clj b/src/test/clojure/cljs/analyzer/spec_tests.clj index b514d6a7d..55ad63637 100644 --- a/src/test/clojure/cljs/analyzer/spec_tests.clj +++ b/src/test/clojure/cljs/analyzer/spec_tests.clj @@ -31,7 +31,7 @@ (test/run-tests) - ;; binding is missing :form + ;; next, problem - some fields are nil (s/explain ::a/node (analyze ns-env '(let [x 1]))) ) From fd5b19f0b6e1849c965fdd62515a7aa1cbb7345c Mon Sep 17 00:00:00 2001 From: davidnolen Date: Fri, 25 Oct 2024 08:58:10 -0400 Subject: [PATCH 09/42] * :binding :shadow can be nil * basic let tests --- src/test/clojure/cljs/analyzer/spec_tests.clj | 8 ++------ src/test/clojure/cljs/analyzer/specs.cljc | 4 +++- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/test/clojure/cljs/analyzer/spec_tests.clj b/src/test/clojure/cljs/analyzer/spec_tests.clj index 55ad63637..2653299d3 100644 --- a/src/test/clojure/cljs/analyzer/spec_tests.clj +++ b/src/test/clojure/cljs/analyzer/spec_tests.clj @@ -23,15 +23,11 @@ (deftest test-let (is (s/valid? ::a/node (analyze ns-env '(let [])))) - ;(is (s/valid? ::a/node (analyze ns-env '(let [x 1])))) - ;(is (s/valid? ::a/node (analyze ns-env '(let [x 1] x)))) - ) + (is (s/valid? ::a/node (analyze ns-env '(let [x 1])))) + (is (s/valid? ::a/node (analyze ns-env '(let [x 1] x))))) (comment (test/run-tests) - ;; next, problem - some fields are nil - (s/explain ::a/node (analyze ns-env '(let [x 1]))) - ) diff --git a/src/test/clojure/cljs/analyzer/specs.cljc b/src/test/clojure/cljs/analyzer/specs.cljc index a99818c3f..74abd328a 100644 --- a/src/test/clojure/cljs/analyzer/specs.cljc +++ b/src/test/clojure/cljs/analyzer/specs.cljc @@ -31,7 +31,9 @@ #{:arg :catch :fn :let :letfn :loop :field}) (s/def ::variadic? boolean?) (s/def ::init ::node) -(s/def ::shadow ::node) +(s/def ::shadow + (s/or :nil nil? + :node ::node)) (defmethod node :binding [_] (s/merge From 45bc823677c555befcdc4c68b9c9a1a5e359ee35 Mon Sep 17 00:00:00 2001 From: davidnolen Date: Fri, 25 Oct 2024 10:40:03 -0400 Subject: [PATCH 10/42] * :case-node is synthetic - no :form --- src/test/clojure/cljs/analyzer/specs.cljc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/test/clojure/cljs/analyzer/specs.cljc b/src/test/clojure/cljs/analyzer/specs.cljc index 74abd328a..77c5b67e3 100644 --- a/src/test/clojure/cljs/analyzer/specs.cljc +++ b/src/test/clojure/cljs/analyzer/specs.cljc @@ -118,9 +118,8 @@ :req-un [::test ::nodes ::default]))) (defmethod node :case-node [_] - (s/merge ::base - (s/keys - :req-un [::tests ::then]))) + (s/keys + :req-un [::op ::env ::tests ::then])) (defmethod node :case-test [_] (s/merge ::base From 68e120f6bf63164a5a1afbb5f1be8b38209b2685 Mon Sep 17 00:00:00 2001 From: davidnolen Date: Fri, 25 Oct 2024 11:06:51 -0400 Subject: [PATCH 11/42] * add tests for new --- src/test/clojure/cljs/analyzer/spec_tests.clj | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/test/clojure/cljs/analyzer/spec_tests.clj b/src/test/clojure/cljs/analyzer/spec_tests.clj index 2653299d3..ef5ba35ec 100644 --- a/src/test/clojure/cljs/analyzer/spec_tests.clj +++ b/src/test/clojure/cljs/analyzer/spec_tests.clj @@ -7,7 +7,8 @@ ;; You must not remove this notice, or any other, from this software. (ns cljs.analyzer.spec-tests - (:require [cljs.analyzer-tests :refer [analyze ns-env]] + (:require [cljs.analyzer.api :as ana :refer [no-warn]] + [cljs.analyzer-tests :refer [analyze ns-env]] [cljs.analyzer.specs :as a] [clojure.test :as test :refer [deftest is]] [clojure.spec.alpha :as s])) @@ -26,6 +27,12 @@ (is (s/valid? ::a/node (analyze ns-env '(let [x 1])))) (is (s/valid? ::a/node (analyze ns-env '(let [x 1] x))))) +(deftest test-new + (is (s/valid? ::a/node (no-warn (analyze ns-env '(new String))))) + (is (s/valid? ::a/node (no-warn (analyze ns-env '(new js/String))))) + (is (s/valid? ::a/node (no-warn (analyze ns-env '(String.))))) + (is (s/valid? ::a/node (no-warn (analyze ns-env '(js/String.)))))) + (comment (test/run-tests) From 2bd179a7f824487f3e08f4f5459c5529d9394cff Mon Sep 17 00:00:00 2001 From: davidnolen Date: Fri, 25 Oct 2024 13:50:45 -0400 Subject: [PATCH 12/42] * add test-throw * add test-def --- src/test/clojure/cljs/analyzer/spec_tests.clj | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/test/clojure/cljs/analyzer/spec_tests.clj b/src/test/clojure/cljs/analyzer/spec_tests.clj index ef5ba35ec..44ab18ef4 100644 --- a/src/test/clojure/cljs/analyzer/spec_tests.clj +++ b/src/test/clojure/cljs/analyzer/spec_tests.clj @@ -27,6 +27,15 @@ (is (s/valid? ::a/node (analyze ns-env '(let [x 1])))) (is (s/valid? ::a/node (analyze ns-env '(let [x 1] x))))) +(deftest test-throw + (is (s/valid? ::a/node (no-warn (analyze ns-env '(throw (js/Error. "foo"))))))) + +(deftest test-def + (is (s/valid? ::a/node (no-warn (analyze ns-env '(def x))))) + (is (s/valid? ::a/node (no-warn (analyze ns-env '(def x 1))))) + (is (s/valid? ::a/node (no-warn (analyze ns-env '(fn []))))) + (is (s/valid? ::a/node (no-warn (analyze ns-env '(fn [] 1)))))) + (deftest test-new (is (s/valid? ::a/node (no-warn (analyze ns-env '(new String))))) (is (s/valid? ::a/node (no-warn (analyze ns-env '(new js/String))))) @@ -37,4 +46,13 @@ (test/run-tests) + (s/valid? ::a/node (no-warn (analyze ns-env '(case x 1 :foo 2 :bar)))) + (s/explain ::a/node (no-warn (analyze ns-env '(case x 1 :foo 2 :bar)))) + + (s/valid? ::a/node (no-warn (analyze ns-env '(def x (fn []))))) + (s/explain ::a/node (no-warn (analyze ns-env '(def x (fn []))))) + + (s/valid? ::a/node (no-warn (analyze ns-env '(fn [x])))) + (s/valid? ::a/node (no-warn (analyze ns-env '(fn [x] 1)))) + ) From 83dadc92efca3cde64d72bb5c45ff02f0a2688b1 Mon Sep 17 00:00:00 2001 From: davidnolen Date: Fri, 25 Oct 2024 17:12:40 -0400 Subject: [PATCH 13/42] * some :binding node missing :env and :form * def, fn, defn tests --- src/main/clojure/cljs/analyzer.cljc | 17 +++++++++++------ src/test/clojure/cljs/analyzer/spec_tests.clj | 19 ++++++++++++------- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/main/clojure/cljs/analyzer.cljc b/src/main/clojure/cljs/analyzer.cljc index 4e52de69f..f1182116f 100644 --- a/src/main/clojure/cljs/analyzer.cljc +++ b/src/main/clojure/cljs/analyzer.cljc @@ -2143,6 +2143,7 @@ {:line line :column column}) param {:op :binding :name name + :form name :line line :column column :tag tag @@ -2205,8 +2206,10 @@ shadow (or (handle-symbol-local name (get locals name)) (get-in env [:js-globals name])) fn-scope (:fn-scope env) - name-var {:name name - :op :binding + name-var {:op :binding + :env env + :form name + :name name :local :fn :info {:fn-self-name true :fn-scope fn-scope @@ -2326,8 +2329,10 @@ (let [ret-tag (-> n meta :tag) fexpr (no-warn (analyze env (n->fexpr n))) be (cond-> - {:name n - :op :binding + {:op :binding + :name n + :form n + :env env :fn-var true :line (get-line n env) :column (get-col n env) @@ -2416,7 +2421,8 @@ col (get-col name env) shadow (or (handle-symbol-local name (get-in env [:locals name])) (get-in env [:js-globals name])) - be {:name name + be {:op :binding + :name name :form name :line line :column col @@ -2426,7 +2432,6 @@ :shadow shadow ;; Give let* bindings same shape as var so ;; they get routed correctly in the compiler - :op :binding :env {:line line :column col} :info {:name name :shadow shadow} diff --git a/src/test/clojure/cljs/analyzer/spec_tests.clj b/src/test/clojure/cljs/analyzer/spec_tests.clj index 44ab18ef4..95bcd6d53 100644 --- a/src/test/clojure/cljs/analyzer/spec_tests.clj +++ b/src/test/clojure/cljs/analyzer/spec_tests.clj @@ -33,8 +33,19 @@ (deftest test-def (is (s/valid? ::a/node (no-warn (analyze ns-env '(def x))))) (is (s/valid? ::a/node (no-warn (analyze ns-env '(def x 1))))) + (is (s/valid? ::a/node (no-warn (analyze ns-env '(def x (fn [])))))) + (is (s/valid? ::a/node (no-warn (analyze ns-env '(def x (fn [y] y))))))) + +(deftest test-fn (is (s/valid? ::a/node (no-warn (analyze ns-env '(fn []))))) - (is (s/valid? ::a/node (no-warn (analyze ns-env '(fn [] 1)))))) + (is (s/valid? ::a/node (no-warn (analyze ns-env '(fn [] 1))))) + (is (s/valid? ::a/node (no-warn (analyze ns-env '(fn [x]))))) + (is (s/valid? ::a/node (no-warn (analyze ns-env '(fn [x] 1)))))) + +(deftest test-defn + (is (s/valid? ::a/node (no-warn (analyze ns-env '(defn x []))))) + (is (s/valid? ::a/node (no-warn (analyze ns-env '(defn x [] 1))))) + (is (s/valid? ::a/node (no-warn (analyze ns-env '(defn x [y] y)))))) (deftest test-new (is (s/valid? ::a/node (no-warn (analyze ns-env '(new String))))) @@ -49,10 +60,4 @@ (s/valid? ::a/node (no-warn (analyze ns-env '(case x 1 :foo 2 :bar)))) (s/explain ::a/node (no-warn (analyze ns-env '(case x 1 :foo 2 :bar)))) - (s/valid? ::a/node (no-warn (analyze ns-env '(def x (fn []))))) - (s/explain ::a/node (no-warn (analyze ns-env '(def x (fn []))))) - - (s/valid? ::a/node (no-warn (analyze ns-env '(fn [x])))) - (s/valid? ::a/node (no-warn (analyze ns-env '(fn [x] 1)))) - ) From 55c8b127ad3ea798941d9ab414e6c6e6b741cc2c Mon Sep 17 00:00:00 2001 From: davidnolen Date: Fri, 25 Oct 2024 17:20:13 -0400 Subject: [PATCH 14/42] * const tests --- src/test/clojure/cljs/analyzer/spec_tests.clj | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/test/clojure/cljs/analyzer/spec_tests.clj b/src/test/clojure/cljs/analyzer/spec_tests.clj index 95bcd6d53..59346f1d6 100644 --- a/src/test/clojure/cljs/analyzer/spec_tests.clj +++ b/src/test/clojure/cljs/analyzer/spec_tests.clj @@ -13,6 +13,18 @@ [clojure.test :as test :refer [deftest is]] [clojure.spec.alpha :as s])) +(deftest test-const + (is (s/valid? ::a/node (analyze ns-env 1))) + (is (s/valid? ::a/node (analyze ns-env 1.2))) + (is (s/valid? ::a/node (analyze ns-env true))) + (is (s/valid? ::a/node (analyze ns-env "foo"))) + (is (s/valid? ::a/node (analyze ns-env []))) + (is (s/valid? ::a/node (analyze ns-env [1 2 3]))) + (is (s/valid? ::a/node (analyze ns-env {}))) + (is (s/valid? ::a/node (analyze ns-env {1 2 3 4}))) + (is (s/valid? ::a/node (analyze ns-env #{}))) + (is (s/valid? ::a/node (analyze ns-env #{1 2 3})))) + (deftest test-if (is (s/valid? ::a/node (analyze ns-env '(if true true)))) (is (s/valid? ::a/node (analyze ns-env '(if true true false))))) From 3e630af66227ea589a197bf463cc9b7fd74d8089 Mon Sep 17 00:00:00 2001 From: davidnolen Date: Fri, 25 Oct 2024 18:51:59 -0400 Subject: [PATCH 15/42] * check the :op --- src/test/clojure/cljs/analyzer/spec_tests.clj | 40 ++++++++++++++----- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/src/test/clojure/cljs/analyzer/spec_tests.clj b/src/test/clojure/cljs/analyzer/spec_tests.clj index 59346f1d6..815f39f5a 100644 --- a/src/test/clojure/cljs/analyzer/spec_tests.clj +++ b/src/test/clojure/cljs/analyzer/spec_tests.clj @@ -18,38 +18,56 @@ (is (s/valid? ::a/node (analyze ns-env 1.2))) (is (s/valid? ::a/node (analyze ns-env true))) (is (s/valid? ::a/node (analyze ns-env "foo"))) - (is (s/valid? ::a/node (analyze ns-env []))) + (let [node (analyze ns-env [])] + (is (= :vector (:op node))) + (is (s/valid? ::a/node node))) (is (s/valid? ::a/node (analyze ns-env [1 2 3]))) (is (s/valid? ::a/node (analyze ns-env {}))) - (is (s/valid? ::a/node (analyze ns-env {1 2 3 4}))) + (let [node (analyze ns-env {1 2 3 4})] + (is (= :map (:op node))) + (is (s/valid? ::a/node node))) (is (s/valid? ::a/node (analyze ns-env #{}))) - (is (s/valid? ::a/node (analyze ns-env #{1 2 3})))) + (let [node (analyze ns-env #{1 2 3})] + (is (= :set (:op node))) + (is (s/valid? ::a/node node)))) (deftest test-if - (is (s/valid? ::a/node (analyze ns-env '(if true true)))) + (let [node (analyze ns-env '(if true true))] + (is (= :if (:op node))) + (is (s/valid? ::a/node node))) (is (s/valid? ::a/node (analyze ns-env '(if true true false))))) (deftest test-do - (is (s/valid? ::a/node (analyze ns-env '(do)))) + (let [node (analyze ns-env '(do))] + (is (= :do (:op node))) + (is (s/valid? ::a/node node))) (is (s/valid? ::a/node (analyze ns-env '(do 1)))) (is (s/valid? ::a/node (analyze ns-env '(do 1 2 3))))) (deftest test-let - (is (s/valid? ::a/node (analyze ns-env '(let [])))) + (let [node (analyze ns-env '(let []))] + (is (= :let (:op node))) + (is (s/valid? ::a/node node))) (is (s/valid? ::a/node (analyze ns-env '(let [x 1])))) (is (s/valid? ::a/node (analyze ns-env '(let [x 1] x))))) (deftest test-throw - (is (s/valid? ::a/node (no-warn (analyze ns-env '(throw (js/Error. "foo"))))))) + (let [node (no-warn (analyze ns-env '(throw (js/Error. "foo"))))] + (is (= :throw (:op node))) + (is (s/valid? ::a/node node)))) (deftest test-def - (is (s/valid? ::a/node (no-warn (analyze ns-env '(def x))))) + (let [node (no-warn (analyze ns-env '(def x)))] + (is (= :def (:op node))) + (is (s/valid? ::a/node node))) (is (s/valid? ::a/node (no-warn (analyze ns-env '(def x 1))))) (is (s/valid? ::a/node (no-warn (analyze ns-env '(def x (fn [])))))) (is (s/valid? ::a/node (no-warn (analyze ns-env '(def x (fn [y] y))))))) (deftest test-fn - (is (s/valid? ::a/node (no-warn (analyze ns-env '(fn []))))) + (let [node (no-warn (analyze ns-env '(fn [])))] + (is (= :fn (:op node))) + (is (s/valid? ::a/node node))) (is (s/valid? ::a/node (no-warn (analyze ns-env '(fn [] 1))))) (is (s/valid? ::a/node (no-warn (analyze ns-env '(fn [x]))))) (is (s/valid? ::a/node (no-warn (analyze ns-env '(fn [x] 1)))))) @@ -60,7 +78,9 @@ (is (s/valid? ::a/node (no-warn (analyze ns-env '(defn x [y] y)))))) (deftest test-new - (is (s/valid? ::a/node (no-warn (analyze ns-env '(new String))))) + (let [node (no-warn (analyze ns-env '(new String)))] + (is (= :new (:op node))) + (is (s/valid? ::a/node node))) (is (s/valid? ::a/node (no-warn (analyze ns-env '(new js/String))))) (is (s/valid? ::a/node (no-warn (analyze ns-env '(String.))))) (is (s/valid? ::a/node (no-warn (analyze ns-env '(js/String.)))))) From 2cc8c5c5cf4248e060adc4c75f17434131201aaa Mon Sep 17 00:00:00 2001 From: davidnolen Date: Tue, 29 Oct 2024 07:47:53 -0400 Subject: [PATCH 16/42] * remove unneeded warnings * add defrecord --- src/test/clojure/cljs/analyzer/spec_tests.clj | 32 ++++++++++++------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/src/test/clojure/cljs/analyzer/spec_tests.clj b/src/test/clojure/cljs/analyzer/spec_tests.clj index 815f39f5a..8b5aab826 100644 --- a/src/test/clojure/cljs/analyzer/spec_tests.clj +++ b/src/test/clojure/cljs/analyzer/spec_tests.clj @@ -60,30 +60,40 @@ (let [node (no-warn (analyze ns-env '(def x)))] (is (= :def (:op node))) (is (s/valid? ::a/node node))) - (is (s/valid? ::a/node (no-warn (analyze ns-env '(def x 1))))) - (is (s/valid? ::a/node (no-warn (analyze ns-env '(def x (fn [])))))) - (is (s/valid? ::a/node (no-warn (analyze ns-env '(def x (fn [y] y))))))) + (is (s/valid? ::a/node (analyze ns-env '(def x 1)))) + (is (s/valid? ::a/node (analyze ns-env '(def x (fn []))))) + (is (s/valid? ::a/node (analyze ns-env '(def x (fn [y] y)))))) (deftest test-fn (let [node (no-warn (analyze ns-env '(fn [])))] (is (= :fn (:op node))) (is (s/valid? ::a/node node))) - (is (s/valid? ::a/node (no-warn (analyze ns-env '(fn [] 1))))) - (is (s/valid? ::a/node (no-warn (analyze ns-env '(fn [x]))))) - (is (s/valid? ::a/node (no-warn (analyze ns-env '(fn [x] 1)))))) + (is (s/valid? ::a/node (analyze ns-env '(fn [] 1)))) + (is (s/valid? ::a/node (analyze ns-env '(fn [x])))) + (is (s/valid? ::a/node (analyze ns-env '(fn [x] 1))))) (deftest test-defn - (is (s/valid? ::a/node (no-warn (analyze ns-env '(defn x []))))) - (is (s/valid? ::a/node (no-warn (analyze ns-env '(defn x [] 1))))) - (is (s/valid? ::a/node (no-warn (analyze ns-env '(defn x [y] y)))))) + (is (s/valid? ::a/node (analyze ns-env '(defn x [])))) + (is (s/valid? ::a/node (analyze ns-env '(defn x [] 1)))) + (is (s/valid? ::a/node (analyze ns-env '(defn x [y] y))))) (deftest test-new (let [node (no-warn (analyze ns-env '(new String)))] (is (= :new (:op node))) (is (s/valid? ::a/node node))) - (is (s/valid? ::a/node (no-warn (analyze ns-env '(new js/String))))) + (is (s/valid? ::a/node (analyze ns-env '(new js/String)))) (is (s/valid? ::a/node (no-warn (analyze ns-env '(String.))))) - (is (s/valid? ::a/node (no-warn (analyze ns-env '(js/String.)))))) + (is (s/valid? ::a/node (analyze ns-env '(js/String.))))) + +(deftest test-defrecord + (let [node (no-warn (analyze ns-env '(defrecord A []))) + body (:body node)] + (is (= :defrecord (->> body :statements first :ret :op))) + (is (s/valid? ::a/node node)))) + +; TODO: #js +;(deftest test-js-object +; ) (comment From d0ece88f3f9e5cb3f0e795b7b492b9b76c1809c2 Mon Sep 17 00:00:00 2001 From: davidnolen Date: Fri, 1 Nov 2024 06:54:43 -0400 Subject: [PATCH 17/42] * add deftype --- src/test/clojure/cljs/analyzer/spec_tests.clj | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/test/clojure/cljs/analyzer/spec_tests.clj b/src/test/clojure/cljs/analyzer/spec_tests.clj index 8b5aab826..371520fbb 100644 --- a/src/test/clojure/cljs/analyzer/spec_tests.clj +++ b/src/test/clojure/cljs/analyzer/spec_tests.clj @@ -85,10 +85,15 @@ (is (s/valid? ::a/node (no-warn (analyze ns-env '(String.))))) (is (s/valid? ::a/node (analyze ns-env '(js/String.))))) +(deftest test-deftype + (let [node (no-warn (analyze ns-env '(deftype A [])))] + (is (= :deftype (-> node :statements first :op))) + (is (s/valid? ::a/node node)))) + (deftest test-defrecord (let [node (no-warn (analyze ns-env '(defrecord A []))) body (:body node)] - (is (= :defrecord (->> body :statements first :ret :op))) + (is (= :defrecord (-> body :statements first :ret :op))) (is (s/valid? ::a/node node)))) ; TODO: #js From 3bf3b4e9c297c912ce26acf8b0c6d0609a56b5dc Mon Sep 17 00:00:00 2001 From: davidnolen Date: Fri, 1 Nov 2024 06:58:48 -0400 Subject: [PATCH 18/42] * host field & call --- src/test/clojure/cljs/analyzer/spec_tests.clj | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/test/clojure/cljs/analyzer/spec_tests.clj b/src/test/clojure/cljs/analyzer/spec_tests.clj index 371520fbb..61459a46b 100644 --- a/src/test/clojure/cljs/analyzer/spec_tests.clj +++ b/src/test/clojure/cljs/analyzer/spec_tests.clj @@ -96,6 +96,22 @@ (is (= :defrecord (-> body :statements first :ret :op))) (is (s/valid? ::a/node node)))) +(deftest test-host-call + (let [node (analyze ns-env '(.substring "foo" 0 1))] + (is (= :host-call (:op node))) + (is (s/valid? ::a/node node))) + (let [node (analyze ns-env '(. "foo" (substring 0 1)))] + (is (= :host-call (:op node))) + (is (s/valid? ::a/node node)))) + +(deftest test-host-field + (let [node (analyze ns-env '(.-length "foo"))] + (is (= :host-field (:op node))) + (is (s/valid? ::a/node node))) + (let [node (analyze ns-env '(. "foo" -length))] + (is (= :host-field (:op node))) + (is (s/valid? ::a/node node)))) + ; TODO: #js ;(deftest test-js-object ; ) From 8822838eb9b6da87ebda50889ced286c2b59ab6e Mon Sep 17 00:00:00 2001 From: davidnolen Date: Fri, 1 Nov 2024 07:09:52 -0400 Subject: [PATCH 19/42] * add invoke * initial loop * todos --- src/test/clojure/cljs/analyzer/spec_tests.clj | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/test/clojure/cljs/analyzer/spec_tests.clj b/src/test/clojure/cljs/analyzer/spec_tests.clj index 61459a46b..faca7b06a 100644 --- a/src/test/clojure/cljs/analyzer/spec_tests.clj +++ b/src/test/clojure/cljs/analyzer/spec_tests.clj @@ -112,6 +112,31 @@ (is (= :host-field (:op node))) (is (s/valid? ::a/node node)))) +(deftest test-invoke + (let [node (no-warn (analyze ns-env '(count "foo")))] + (is (= :invoke (:op node))) + (is (s/valid? ::a/node node)))) + +(deftest test-loop + (let [node (analyze ns-env '(loop []))] + (is (= :loop (:op node))) + (is (s/valid? ::a/node node))) + (let [node (analyze ns-env '(loop [x 1] x))] + (is (s/valid? ::a/node node))) + #_(let [node (analyze ns-env '(loop [x 1] (recur (inc x))))] + (is (s/valid? ::a/node node))) + #_(let [node (no-warn + (analyze ns-env + '(loop [x 100] + (if (pos? x) + (recur (dec x)) + x))))] + (is (s/valid? ::a/node node)))) + +;; leftfn + +;; local + ; TODO: #js ;(deftest test-js-object ; ) From ac8b0debc7054a61ad35629018f2f1f694cdcd96 Mon Sep 17 00:00:00 2001 From: davidnolen Date: Fri, 1 Nov 2024 07:54:29 -0400 Subject: [PATCH 20/42] * ::node not ::nodes, fixes stackoverflow --- src/test/clojure/cljs/analyzer/specs.cljc | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/test/clojure/cljs/analyzer/specs.cljc b/src/test/clojure/cljs/analyzer/specs.cljc index 77c5b67e3..11b6ab029 100644 --- a/src/test/clojure/cljs/analyzer/specs.cljc +++ b/src/test/clojure/cljs/analyzer/specs.cljc @@ -235,12 +235,6 @@ (defmethod node :no-op [_] ::base) -(defmethod node :no-op [_] - ::base) - -(defmethod node :no-op [_] - ::base) - (s/def ::expr ::node) (defmethod node :quote [_] @@ -248,7 +242,7 @@ (s/keys :req-un [::expr ::literal?]))) -(s/def ::exprs (s/* ::nodes)) +(s/def ::exprs (s/* ::node)) (defmethod node :recur [_] (s/merge ::base From 6a353c377bc7e49bb15032b9345fb8d7a775874c Mon Sep 17 00:00:00 2001 From: davidnolen Date: Fri, 1 Nov 2024 08:01:17 -0400 Subject: [PATCH 21/42] * add missing :js spec * basic tests for loop, recur, case --- src/test/clojure/cljs/analyzer/spec_tests.clj | 17 +++++++++++------ src/test/clojure/cljs/analyzer/specs.cljc | 7 +++++++ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/test/clojure/cljs/analyzer/spec_tests.clj b/src/test/clojure/cljs/analyzer/spec_tests.clj index faca7b06a..72167104c 100644 --- a/src/test/clojure/cljs/analyzer/spec_tests.clj +++ b/src/test/clojure/cljs/analyzer/spec_tests.clj @@ -123,9 +123,9 @@ (is (s/valid? ::a/node node))) (let [node (analyze ns-env '(loop [x 1] x))] (is (s/valid? ::a/node node))) - #_(let [node (analyze ns-env '(loop [x 1] (recur (inc x))))] + (let [node (analyze ns-env '(loop [x 1] (recur (inc x))))] (is (s/valid? ::a/node node))) - #_(let [node (no-warn + (let [node (no-warn (analyze ns-env '(loop [x 100] (if (pos? x) @@ -133,7 +133,15 @@ x))))] (is (s/valid? ::a/node node)))) -;; leftfn +(deftest test-recur + (let [node (no-warn (analyze ns-env '(fn [x] (recur (inc x)))))] + (is (s/valid? ::a/node node)))) + +(deftest test-case + (let [node (no-warn (analyze ns-env '(case x 1 :foo 2 :bar)))] + (is (s/valid? ::a/node node)))) + +;; letfn ;; local @@ -145,7 +153,4 @@ (test/run-tests) - (s/valid? ::a/node (no-warn (analyze ns-env '(case x 1 :foo 2 :bar)))) - (s/explain ::a/node (no-warn (analyze ns-env '(case x 1 :foo 2 :bar)))) - ) diff --git a/src/test/clojure/cljs/analyzer/specs.cljc b/src/test/clojure/cljs/analyzer/specs.cljc index 11b6ab029..2ef433cd0 100644 --- a/src/test/clojure/cljs/analyzer/specs.cljc +++ b/src/test/clojure/cljs/analyzer/specs.cljc @@ -286,6 +286,13 @@ (s/keys :req-un [::meta ::expr]))) +(s/def ::code string?) + +(defmethod node :js [_] + (s/merge ::base + (s/keys + :opt-un [::code]))) + (comment (s/valid? ::node 1) From 69c0f84bfa3acbc9c8dd1bb5d475876b2c6632c2 Mon Sep 17 00:00:00 2001 From: davidnolen Date: Fri, 15 Nov 2024 07:33:52 -0500 Subject: [PATCH 22/42] * alphabetize specs --- src/test/clojure/cljs/analyzer/specs.cljc | 144 +++++++++++----------- 1 file changed, 70 insertions(+), 74 deletions(-) diff --git a/src/test/clojure/cljs/analyzer/specs.cljc b/src/test/clojure/cljs/analyzer/specs.cljc index 2ef433cd0..e64c02521 100644 --- a/src/test/clojure/cljs/analyzer/specs.cljc +++ b/src/test/clojure/cljs/analyzer/specs.cljc @@ -42,73 +42,6 @@ :req-un [::name :cljs.analyzer.specs.binding/local] :opt-un [::variadic? ::init ::shadow]))) -(defmethod node :if [_] - (s/merge ::base - (s/keys - :req-un [::test ::then] - :opt-un [::else]))) - -(s/def ::literal? boolean?) -(s/def ::val any?) - -(defmethod node :const [_] - (s/merge ::base - (s/keys - :req-un [::val] - ;; ::literal? is required in the AST REF, but we don't actually use it - ;; should check tools.analyzer - :opt-un [::literal?]))) - -(s/def ::keys (s/* ::node)) -(s/def ::vals (s/* ::node)) - -(defmethod node :map [_] - (s/merge ::base - (s/keys :req-un [::keys ::vals]))) - -(s/def ::items (s/* ::node)) - -(defmethod node :list [_] - (s/merge ::base - (s/keys - :req-un [::items]))) - -(defmethod node :vector [_] - (s/merge ::base - (s/keys - :req-un [::items]))) - -(defmethod node :set [_] - (s/merge ::base - (s/keys - :req-un [::items]))) - -(defmethod node :js-object [_] - (s/merge ::base - (s/keys - :req-un [::keys ::vals]))) - -(defmethod node :js-array [_] - (s/merge ::base - (s/keys - :req-un [::items]))) - -(s/def ::ns symbol?) - -(defmethod node :js-var [_] - (s/merge ::base - (s/keys - :req-un [::ns ::name]))) - -(s/def ::var ::node) -(s/def ::sym ::node) -(s/def ::meta map?) - -(defmethod node :the-var [_] - (s/merge ::base - (s/keys - :opt-un [::var ::sym ::meta]))) - (s/def ::nodes (s/* ::node)) (s/def ::default ::node) @@ -131,7 +64,16 @@ (s/keys :req-un [::then]))) -(s/def ::the-var ::node) +(s/def ::literal? boolean?) +(s/def ::val any?) + +(defmethod node :const [_] + (s/merge ::base + (s/keys + :req-un [::val] + ;; ::literal? is required in the AST REF, but we don't actually use it + ;; should check tools.analyzer + :opt-un [::literal?]))) (defmethod node :def [_] (s/merge ::base @@ -196,6 +138,12 @@ (s/keys :req-un [::field ::target]))) +(defmethod node :if [_] + (s/merge ::base + (s/keys + :req-un [::test ::then] + :opt-un [::else]))) + (s/def ::fn ::node) (defmethod node :invoke [_] @@ -203,6 +151,30 @@ (s/keys :req-un [::fn ::args]))) +(s/def ::code string?) + +(defmethod node :js [_] + (s/merge ::base + (s/keys + :opt-un [::code]))) + +(defmethod node :js-array [_] + (s/merge ::base + (s/keys + :req-un [::items]))) + +(defmethod node :js-object [_] + (s/merge ::base + (s/keys + :req-un [::keys ::vals]))) + +(s/def ::ns symbol?) + +(defmethod node :js-var [_] + (s/merge ::base + (s/keys + :req-un [::ns ::name]))) + (s/def ::bindings (s/* ::node)) (defmethod node :let [_] @@ -215,6 +187,14 @@ (s/keys :req-un [::bindings ::body]))) +(s/def ::items (s/* ::node)) + +;; TODO: not in ast-ref +(defmethod node :list [_] + (s/merge ::base + (s/keys + :req-un [::items]))) + (defmethod node :local [_] (s/merge ::base (s/keys @@ -225,6 +205,13 @@ (s/keys :req-un [::bindings ::body]))) +(s/def ::keys (s/* ::node)) +(s/def ::vals (s/* ::node)) + +(defmethod node :map [_] + (s/merge ::base + (s/keys :req-un [::keys ::vals]))) + (s/def ::class ::node) (defmethod node :new [_] @@ -259,6 +246,17 @@ (s/keys :req-un [::target ::val]))) +(s/def ::var ::node) +(s/def ::sym ::node) +(s/def ::meta map?) + +(defmethod node :the-var [_] + (s/merge ::base + (s/keys + :opt-un [::var ::sym ::meta]))) + +(s/def ::the-var ::node) + (s/def ::exception ::node) (defmethod node :throw [_] @@ -281,17 +279,15 @@ (s/def ::meta ::node) -(defmethod node :with-meta [_] +(defmethod node :vector [_] (s/merge ::base (s/keys - :req-un [::meta ::expr]))) - -(s/def ::code string?) + :req-un [::items]))) -(defmethod node :js [_] +(defmethod node :with-meta [_] (s/merge ::base (s/keys - :opt-un [::code]))) + :req-un [::meta ::expr]))) (comment From fb836ea657dba8e3582f2eed682b0dd1f57ca59a Mon Sep 17 00:00:00 2001 From: davidnolen Date: Fri, 15 Nov 2024 07:43:50 -0500 Subject: [PATCH 23/42] * alphabetize tests * add missing cases / todos as comments --- src/test/clojure/cljs/analyzer/spec_tests.clj | 140 +++++++++++------- src/test/clojure/cljs/analyzer/specs.cljc | 4 + 2 files changed, 92 insertions(+), 52 deletions(-) diff --git a/src/test/clojure/cljs/analyzer/spec_tests.clj b/src/test/clojure/cljs/analyzer/spec_tests.clj index 72167104c..991a81db8 100644 --- a/src/test/clojure/cljs/analyzer/spec_tests.clj +++ b/src/test/clojure/cljs/analyzer/spec_tests.clj @@ -13,6 +13,14 @@ [clojure.test :as test :refer [deftest is]] [clojure.spec.alpha :as s])) +(deftest test-case + (let [node (no-warn (analyze ns-env '(case x 1 :foo 2 :bar)))] + (is (s/valid? ::a/node node)))) + +;; case-node +;; case-test +;; case-then + (deftest test-const (is (s/valid? ::a/node (analyze ns-env 1))) (is (s/valid? ::a/node (analyze ns-env 1.2))) @@ -31,31 +39,6 @@ (is (= :set (:op node))) (is (s/valid? ::a/node node)))) -(deftest test-if - (let [node (analyze ns-env '(if true true))] - (is (= :if (:op node))) - (is (s/valid? ::a/node node))) - (is (s/valid? ::a/node (analyze ns-env '(if true true false))))) - -(deftest test-do - (let [node (analyze ns-env '(do))] - (is (= :do (:op node))) - (is (s/valid? ::a/node node))) - (is (s/valid? ::a/node (analyze ns-env '(do 1)))) - (is (s/valid? ::a/node (analyze ns-env '(do 1 2 3))))) - -(deftest test-let - (let [node (analyze ns-env '(let []))] - (is (= :let (:op node))) - (is (s/valid? ::a/node node))) - (is (s/valid? ::a/node (analyze ns-env '(let [x 1])))) - (is (s/valid? ::a/node (analyze ns-env '(let [x 1] x))))) - -(deftest test-throw - (let [node (no-warn (analyze ns-env '(throw (js/Error. "foo"))))] - (is (= :throw (:op node))) - (is (s/valid? ::a/node node)))) - (deftest test-def (let [node (no-warn (analyze ns-env '(def x)))] (is (= :def (:op node))) @@ -64,37 +47,38 @@ (is (s/valid? ::a/node (analyze ns-env '(def x (fn []))))) (is (s/valid? ::a/node (analyze ns-env '(def x (fn [y] y)))))) -(deftest test-fn - (let [node (no-warn (analyze ns-env '(fn [])))] - (is (= :fn (:op node))) - (is (s/valid? ::a/node node))) - (is (s/valid? ::a/node (analyze ns-env '(fn [] 1)))) - (is (s/valid? ::a/node (analyze ns-env '(fn [x])))) - (is (s/valid? ::a/node (analyze ns-env '(fn [x] 1))))) - (deftest test-defn (is (s/valid? ::a/node (analyze ns-env '(defn x [])))) (is (s/valid? ::a/node (analyze ns-env '(defn x [] 1)))) (is (s/valid? ::a/node (analyze ns-env '(defn x [y] y))))) -(deftest test-new - (let [node (no-warn (analyze ns-env '(new String)))] - (is (= :new (:op node))) - (is (s/valid? ::a/node node))) - (is (s/valid? ::a/node (analyze ns-env '(new js/String)))) - (is (s/valid? ::a/node (no-warn (analyze ns-env '(String.))))) - (is (s/valid? ::a/node (analyze ns-env '(js/String.))))) +(deftest test-defrecord + (let [node (no-warn (analyze ns-env '(defrecord A []))) + body (:body node)] + (is (= :defrecord (-> body :statements first :ret :op))) + (is (s/valid? ::a/node node)))) (deftest test-deftype (let [node (no-warn (analyze ns-env '(deftype A [])))] (is (= :deftype (-> node :statements first :op))) (is (s/valid? ::a/node node)))) -(deftest test-defrecord - (let [node (no-warn (analyze ns-env '(defrecord A []))) - body (:body node)] - (is (= :defrecord (-> body :statements first :ret :op))) - (is (s/valid? ::a/node node)))) +(deftest test-do + (let [node (analyze ns-env '(do))] + (is (= :do (:op node))) + (is (s/valid? ::a/node node))) + (is (s/valid? ::a/node (analyze ns-env '(do 1)))) + (is (s/valid? ::a/node (analyze ns-env '(do 1 2 3))))) + +(deftest test-fn + (let [node (no-warn (analyze ns-env '(fn [])))] + (is (= :fn (:op node))) + (is (s/valid? ::a/node node))) + (is (s/valid? ::a/node (analyze ns-env '(fn [] 1)))) + (is (s/valid? ::a/node (analyze ns-env '(fn [x])))) + (is (s/valid? ::a/node (analyze ns-env '(fn [x] 1))))) + +;; fn-method (deftest test-host-call (let [node (analyze ns-env '(.substring "foo" 0 1))] @@ -112,11 +96,38 @@ (is (= :host-field (:op node))) (is (s/valid? ::a/node node)))) +(deftest test-if + (let [node (analyze ns-env '(if true true))] + (is (= :if (:op node))) + (is (s/valid? ::a/node node))) + (is (s/valid? ::a/node (analyze ns-env '(if true true false))))) + (deftest test-invoke (let [node (no-warn (analyze ns-env '(count "foo")))] (is (= :invoke (:op node))) (is (s/valid? ::a/node node)))) +;; js-array + +;; js-object +;(deftest test-js-object +; ) + +;; js-var + +(deftest test-let + (let [node (analyze ns-env '(let []))] + (is (= :let (:op node))) + (is (s/valid? ::a/node node))) + (is (s/valid? ::a/node (analyze ns-env '(let [x 1])))) + (is (s/valid? ::a/node (analyze ns-env '(let [x 1] x))))) + +;; letfn + +;; list + +;; local + (deftest test-loop (let [node (analyze ns-env '(loop []))] (is (= :loop (:op node))) @@ -133,21 +144,46 @@ x))))] (is (s/valid? ::a/node node)))) +;; map + +(deftest test-new + (let [node (no-warn (analyze ns-env '(new String)))] + (is (= :new (:op node))) + (is (s/valid? ::a/node node))) + (is (s/valid? ::a/node (analyze ns-env '(new js/String)))) + (is (s/valid? ::a/node (no-warn (analyze ns-env '(String.))))) + (is (s/valid? ::a/node (analyze ns-env '(js/String.))))) + +;; no-op + +;; ns + +;; ns* + +;; quote + (deftest test-recur (let [node (no-warn (analyze ns-env '(fn [x] (recur (inc x)))))] (is (s/valid? ::a/node node)))) -(deftest test-case - (let [node (no-warn (analyze ns-env '(case x 1 :foo 2 :bar)))] +;; set + +;; set! + +;; the-var + +(deftest test-throw + (let [node (no-warn (analyze ns-env '(throw (js/Error. "foo"))))] + (is (= :throw (:op node))) (is (s/valid? ::a/node node)))) -;; letfn +;; try -;; local +;; var -; TODO: #js -;(deftest test-js-object -; ) +;; vector + +;; with-meta (comment diff --git a/src/test/clojure/cljs/analyzer/specs.cljc b/src/test/clojure/cljs/analyzer/specs.cljc index e64c02521..b6cb386d4 100644 --- a/src/test/clojure/cljs/analyzer/specs.cljc +++ b/src/test/clojure/cljs/analyzer/specs.cljc @@ -222,6 +222,10 @@ (defmethod node :no-op [_] ::base) +;; :ns + +;; :ns* + (s/def ::expr ::node) (defmethod node :quote [_] From 2c92f31fb8e6e4d6cd6d9c794abdbbc90c4b17b9 Mon Sep 17 00:00:00 2001 From: davidnolen Date: Fri, 15 Nov 2024 07:44:32 -0500 Subject: [PATCH 24/42] * :binding --- src/test/clojure/cljs/analyzer/spec_tests.clj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/clojure/cljs/analyzer/spec_tests.clj b/src/test/clojure/cljs/analyzer/spec_tests.clj index 991a81db8..4947a1860 100644 --- a/src/test/clojure/cljs/analyzer/spec_tests.clj +++ b/src/test/clojure/cljs/analyzer/spec_tests.clj @@ -13,6 +13,8 @@ [clojure.test :as test :refer [deftest is]] [clojure.spec.alpha :as s])) +;; binding + (deftest test-case (let [node (no-warn (analyze ns-env '(case x 1 :foo 2 :bar)))] (is (s/valid? ::a/node node)))) From 66487bb783aabbaaf540389aeccdda5834d75fb7 Mon Sep 17 00:00:00 2001 From: davidnolen Date: Sun, 17 Nov 2024 09:55:47 -0500 Subject: [PATCH 25/42] * :op :quote should be :literal? true * map, vector, quote tests --- src/main/clojure/cljs/analyzer.cljc | 1 + src/test/clojure/cljs/analyzer/spec_tests.clj | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/main/clojure/cljs/analyzer.cljc b/src/main/clojure/cljs/analyzer.cljc index f1182116f..47bb73dc4 100644 --- a/src/main/clojure/cljs/analyzer.cljc +++ b/src/main/clojure/cljs/analyzer.cljc @@ -2571,6 +2571,7 @@ (throw (error env "Wrong number of args to quote"))) (let [expr (analyze-const env x)] {:op :quote + :literal? true :expr expr :env env :form form diff --git a/src/test/clojure/cljs/analyzer/spec_tests.clj b/src/test/clojure/cljs/analyzer/spec_tests.clj index 4947a1860..55e5b6f4a 100644 --- a/src/test/clojure/cljs/analyzer/spec_tests.clj +++ b/src/test/clojure/cljs/analyzer/spec_tests.clj @@ -146,7 +146,10 @@ x))))] (is (s/valid? ::a/node node)))) -;; map +(deftest test-map + (let [node (no-warn (analyze ns-env '{:foo 1 :bar 2}))] + (is (= :map (:op node))) + (is (s/valid? ::a/node node)))) (deftest test-new (let [node (no-warn (analyze ns-env '(new String)))] @@ -162,7 +165,10 @@ ;; ns* -;; quote +(deftest test-quote + (let [node (analyze ns-env ''(1 2 3))] + (is (= :quote (:op node))) + (is (s/valid? ::a/node node)))) (deftest test-recur (let [node (no-warn (analyze ns-env '(fn [x] (recur (inc x)))))] @@ -183,7 +189,10 @@ ;; var -;; vector +(deftest test-map + (let [node (no-warn (analyze ns-env '[1 2]))] + (is (= :vector (:op node))) + (is (s/valid? ::a/node node)))) ;; with-meta From 6226322208e09240546801c79482306ad0f54793 Mon Sep 17 00:00:00 2001 From: davidnolen Date: Sun, 17 Nov 2024 10:21:22 -0500 Subject: [PATCH 26/42] * add binding, note about list, add set, typo --- src/test/clojure/cljs/analyzer/spec_tests.clj | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/test/clojure/cljs/analyzer/spec_tests.clj b/src/test/clojure/cljs/analyzer/spec_tests.clj index 55e5b6f4a..310763eb4 100644 --- a/src/test/clojure/cljs/analyzer/spec_tests.clj +++ b/src/test/clojure/cljs/analyzer/spec_tests.clj @@ -13,7 +13,11 @@ [clojure.test :as test :refer [deftest is]] [clojure.spec.alpha :as s])) -;; binding +(deftest test-binding + (let [node (analyze ns-env '(let [x 1] x)) + binding (-> node :bindings first)] + (is (= :binding (:op binding))) + (is (s/valid? ::a/node binding)))) (deftest test-case (let [node (no-warn (analyze ns-env '(case x 1 :foo 2 :bar)))] @@ -126,7 +130,7 @@ ;; letfn -;; list +;; list, no longer needed, subsumed by :quote ;; local @@ -174,7 +178,10 @@ (let [node (no-warn (analyze ns-env '(fn [x] (recur (inc x)))))] (is (s/valid? ::a/node node)))) -;; set +(deftest test-set + (let [node (no-warn (analyze ns-env #{1 2 3}))] + (is (= :set (:op node))) + (is (s/valid? ::a/node node)))) ;; set! @@ -189,7 +196,7 @@ ;; var -(deftest test-map +(deftest test-vector (let [node (no-warn (analyze ns-env '[1 2]))] (is (= :vector (:op node))) (is (s/valid? ::a/node node)))) From 17c79e7cd80d4c3f0e05b70cda14852605f2fa0e Mon Sep 17 00:00:00 2001 From: davidnolen Date: Sun, 17 Nov 2024 11:28:08 -0500 Subject: [PATCH 27/42] * add basic :ns & :ns* specs * test-letfn, test-ns, test-set! * some problematic ones --- src/test/clojure/cljs/analyzer/spec_tests.clj | 34 +++++++++++++++---- src/test/clojure/cljs/analyzer/specs.cljc | 6 ++-- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/test/clojure/cljs/analyzer/spec_tests.clj b/src/test/clojure/cljs/analyzer/spec_tests.clj index 310763eb4..4eb45279f 100644 --- a/src/test/clojure/cljs/analyzer/spec_tests.clj +++ b/src/test/clojure/cljs/analyzer/spec_tests.clj @@ -7,7 +7,8 @@ ;; You must not remove this notice, or any other, from this software. (ns cljs.analyzer.spec-tests - (:require [cljs.analyzer.api :as ana :refer [no-warn]] + (:require [cljs.analyzer :as ana] + [cljs.analyzer.api :as ana-api :refer [no-warn]] [cljs.analyzer-tests :refer [analyze ns-env]] [cljs.analyzer.specs :as a] [clojure.test :as test :refer [deftest is]] @@ -128,7 +129,10 @@ (is (s/valid? ::a/node (analyze ns-env '(let [x 1])))) (is (s/valid? ::a/node (analyze ns-env '(let [x 1] x))))) -;; letfn +(deftest test-letfn + (let [node (analyze ns-env '(letfn [(foo [] (bar)) (bar [] (foo))]))] + (is (= :letfn (:op node))) + (is (s/valid? ::a/node node)))) ;; list, no longer needed, subsumed by :quote @@ -165,9 +169,19 @@ ;; no-op -;; ns +(deftest test-ns + (let [node (no-warn + (binding [ana/*cljs-ns* 'cljs.user] + (analyze ns-env '(ns foo (:require [goog.string])))))] + (is (= :ns (:op node))) + (is (s/valid? ::a/node node)))) -;; ns* +#_(deftest test-ns* + (let [node (no-warn + (binding [ana/*cljs-ns* 'cljs.user] + (analyze ns-env '(ns* foo '(:require [goog.string])))))] + (is (= :ns (:op node))) + (is (s/valid? ::a/node node)))) (deftest test-quote (let [node (analyze ns-env ''(1 2 3))] @@ -179,11 +193,14 @@ (is (s/valid? ::a/node node)))) (deftest test-set - (let [node (no-warn (analyze ns-env #{1 2 3}))] + (let [node (analyze ns-env #{1 2 3})] (is (= :set (:op node))) (is (s/valid? ::a/node node)))) -;; set! +(deftest test-set! + (let [node (no-warn (analyze ns-env '(set! x 1)))] + (is (= :set! (:op node))) + (is (s/valid? ::a/node node)))) ;; the-var @@ -192,7 +209,10 @@ (is (= :throw (:op node))) (is (s/valid? ::a/node node)))) -;; try +#_(deftest test-try + (let [node (no-warn (analyze ns-env '(try 1 (catch :default e) (finally))))] + (is (= :try (:op node))) + (is (s/valid? ::a/node node)))) ;; var diff --git a/src/test/clojure/cljs/analyzer/specs.cljc b/src/test/clojure/cljs/analyzer/specs.cljc index b6cb386d4..08e94910e 100644 --- a/src/test/clojure/cljs/analyzer/specs.cljc +++ b/src/test/clojure/cljs/analyzer/specs.cljc @@ -222,9 +222,11 @@ (defmethod node :no-op [_] ::base) -;; :ns +(defmethod node :ns [_] + ::base) -;; :ns* +(defmethod node :ns* [_] + ::base) (s/def ::expr ::node) From 687917430a4969a941d679d8fc489822531ffaa9 Mon Sep 17 00:00:00 2001 From: davidnolen Date: Sun, 17 Nov 2024 14:08:31 -0500 Subject: [PATCH 28/42] * ns* stest --- src/test/clojure/cljs/analyzer/spec_tests.clj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/clojure/cljs/analyzer/spec_tests.clj b/src/test/clojure/cljs/analyzer/spec_tests.clj index 4eb45279f..e7c7dd820 100644 --- a/src/test/clojure/cljs/analyzer/spec_tests.clj +++ b/src/test/clojure/cljs/analyzer/spec_tests.clj @@ -176,11 +176,11 @@ (is (= :ns (:op node))) (is (s/valid? ::a/node node)))) -#_(deftest test-ns* +(deftest test-ns* (let [node (no-warn (binding [ana/*cljs-ns* 'cljs.user] - (analyze ns-env '(ns* foo '(:require [goog.string])))))] - (is (= :ns (:op node))) + (analyze ns-env '(ns* (:require '[goog.string])))))] + (is (= :ns* (:op node))) (is (s/valid? ::a/node node)))) (deftest test-quote From 70b16c70f1faeec28840998c8516c2ee48eefdd5 Mon Sep 17 00:00:00 2001 From: davidnolen Date: Sun, 17 Nov 2024 14:42:05 -0500 Subject: [PATCH 29/42] * add js-array --- src/test/clojure/cljs/analyzer/spec_tests.clj | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/test/clojure/cljs/analyzer/spec_tests.clj b/src/test/clojure/cljs/analyzer/spec_tests.clj index e7c7dd820..844c2e0d4 100644 --- a/src/test/clojure/cljs/analyzer/spec_tests.clj +++ b/src/test/clojure/cljs/analyzer/spec_tests.clj @@ -12,7 +12,8 @@ [cljs.analyzer-tests :refer [analyze ns-env]] [cljs.analyzer.specs :as a] [clojure.test :as test :refer [deftest is]] - [clojure.spec.alpha :as s])) + [clojure.spec.alpha :as s]) + (:import [java.io StringReader])) (deftest test-binding (let [node (analyze ns-env '(let [x 1] x)) @@ -114,11 +115,19 @@ (is (= :invoke (:op node))) (is (s/valid? ::a/node node)))) -;; js-array +(deftest test-js-array + (let [node (analyze ns-env + (ana-api/with-state (ana-api/empty-state) + (first (ana-api/forms-seq (StringReader. "#js [1 2 3]")))))] + (is (= :js-array (:op node))) + (is (s/valid? ::a/node node)))) -;; js-object -;(deftest test-js-object -; ) +#_(deftest test-js-object + (let [node (analyze ns-env + (ana-api/with-state (ana-api/empty-state) + (first (ana-api/forms-seq (StringReader. "#js {:foo 1 :bar 2}")))))] + (is (= :js-object (:op node))) + (is (s/valid? ::a/node node)))) ;; js-var From 4cb5d043f6479c5881fbe24e5cb2194ff8a6d14b Mon Sep 17 00:00:00 2001 From: davidnolen Date: Sun, 17 Nov 2024 14:59:28 -0500 Subject: [PATCH 30/42] * test-js-var * test-with-meta * not working the-var case --- src/test/clojure/cljs/analyzer/spec_tests.clj | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/test/clojure/cljs/analyzer/spec_tests.clj b/src/test/clojure/cljs/analyzer/spec_tests.clj index 844c2e0d4..dbf6c5417 100644 --- a/src/test/clojure/cljs/analyzer/spec_tests.clj +++ b/src/test/clojure/cljs/analyzer/spec_tests.clj @@ -129,7 +129,10 @@ (is (= :js-object (:op node))) (is (s/valid? ::a/node node)))) -;; js-var +(deftest test-js-var + (let [node (analyze ns-env 'js/String)] + (is (= :js-var (:op node))) + (is (s/valid? ::a/node node)))) (deftest test-let (let [node (analyze ns-env '(let []))] @@ -211,7 +214,9 @@ (is (= :set! (:op node))) (is (s/valid? ::a/node node)))) -;; the-var +#_(deftest test-the-var + (let [node (no-warn (analyze ns-env '(var x)))] + (is (= :the-var (:op node))))) (deftest test-throw (let [node (no-warn (analyze ns-env '(throw (js/Error. "foo"))))] @@ -230,7 +235,10 @@ (is (= :vector (:op node))) (is (s/valid? ::a/node node)))) -;; with-meta +(deftest test-with-meta + (let [node (analyze ns-env ^{:meta 2} {:foo 1})] + (is (= :with-meta (:op node))) + (is (s/valid? ::a/node node)))) (comment From 5219786b46c261dcf39c307f7b0a83f7faa22cf7 Mon Sep 17 00:00:00 2001 From: davidnolen Date: Sun, 17 Nov 2024 15:16:32 -0500 Subject: [PATCH 31/42] * test-the-var --- src/test/clojure/cljs/analyzer/spec_tests.clj | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/test/clojure/cljs/analyzer/spec_tests.clj b/src/test/clojure/cljs/analyzer/spec_tests.clj index dbf6c5417..5f4c33da9 100644 --- a/src/test/clojure/cljs/analyzer/spec_tests.clj +++ b/src/test/clojure/cljs/analyzer/spec_tests.clj @@ -9,6 +9,7 @@ (ns cljs.analyzer.spec-tests (:require [cljs.analyzer :as ana] [cljs.analyzer.api :as ana-api :refer [no-warn]] + [cljs.compiler.api :as comp-api] [cljs.analyzer-tests :refer [analyze ns-env]] [cljs.analyzer.specs :as a] [clojure.test :as test :refer [deftest is]] @@ -214,8 +215,9 @@ (is (= :set! (:op node))) (is (s/valid? ::a/node node)))) -#_(deftest test-the-var - (let [node (no-warn (analyze ns-env '(var x)))] +(deftest test-the-var + (let [node (comp-api/with-core-cljs {} + #(analyze ns-env '(var first)))] (is (= :the-var (:op node))))) (deftest test-throw From e888faed4b1ddaa4c515fe963c3319b064fc30ea Mon Sep 17 00:00:00 2001 From: davidnolen Date: Sun, 17 Nov 2024 15:20:50 -0500 Subject: [PATCH 32/42] * missing assertion --- src/test/clojure/cljs/analyzer/spec_tests.clj | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/clojure/cljs/analyzer/spec_tests.clj b/src/test/clojure/cljs/analyzer/spec_tests.clj index 5f4c33da9..62204dca2 100644 --- a/src/test/clojure/cljs/analyzer/spec_tests.clj +++ b/src/test/clojure/cljs/analyzer/spec_tests.clj @@ -218,7 +218,8 @@ (deftest test-the-var (let [node (comp-api/with-core-cljs {} #(analyze ns-env '(var first)))] - (is (= :the-var (:op node))))) + (is (= :the-var (:op node))) + (is (s/valid? ::a/node node)))) (deftest test-throw (let [node (no-warn (analyze ns-env '(throw (js/Error. "foo"))))] From 82efd243ea71c8954bc8c68ec7558d09f74b3508 Mon Sep 17 00:00:00 2001 From: davidnolen Date: Mon, 18 Nov 2024 10:38:47 -0800 Subject: [PATCH 33/42] * more assertions for case --- src/test/clojure/cljs/analyzer/spec_tests.clj | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/test/clojure/cljs/analyzer/spec_tests.clj b/src/test/clojure/cljs/analyzer/spec_tests.clj index 62204dca2..e365e2414 100644 --- a/src/test/clojure/cljs/analyzer/spec_tests.clj +++ b/src/test/clojure/cljs/analyzer/spec_tests.clj @@ -23,11 +23,13 @@ (is (s/valid? ::a/node binding)))) (deftest test-case - (let [node (no-warn (analyze ns-env '(case x 1 :foo 2 :bar)))] + (let [let-node (no-warn (analyze ns-env '(case x 1 :foo 2 :bar))) + node (-> let-node :body :ret)] + (is (= :case (:op node))) (is (s/valid? ::a/node node)))) -;; case-node ;; case-test +;; case-node ;; case-then (deftest test-const From 4d7210e29b9f8ce3ab3bdfa7231e76dc94fe3acf Mon Sep 17 00:00:00 2001 From: davidnolen Date: Mon, 18 Nov 2024 10:51:29 -0800 Subject: [PATCH 34/42] * case-node, case-test, case-then --- src/test/clojure/cljs/analyzer/spec_tests.clj | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/test/clojure/cljs/analyzer/spec_tests.clj b/src/test/clojure/cljs/analyzer/spec_tests.clj index e365e2414..bafaf9245 100644 --- a/src/test/clojure/cljs/analyzer/spec_tests.clj +++ b/src/test/clojure/cljs/analyzer/spec_tests.clj @@ -26,11 +26,18 @@ (let [let-node (no-warn (analyze ns-env '(case x 1 :foo 2 :bar))) node (-> let-node :body :ret)] (is (= :case (:op node))) - (is (s/valid? ::a/node node)))) - -;; case-test -;; case-node -;; case-then + (is (s/valid? ::a/node node)) + (let [nodes (-> node :nodes) + case-node (first nodes)] + (is (= :case-node (:op case-node))) + (is (s/valid? ::a/node case-node)) + (let [case-tests (:tests case-node) + case-test (first case-tests) + case-then (:then case-node)] + (is (= :case-test (:op case-test))) + (is (s/valid? ::a/node case-test)) + (is (= :case-then (:op case-then))) + (is (s/valid? ::a/node case-then)))))) (deftest test-const (is (s/valid? ::a/node (analyze ns-env 1))) From cf2d7fcc02a229a3a3b7ed2b415d8e6d968214bb Mon Sep 17 00:00:00 2001 From: davidnolen Date: Mon, 18 Nov 2024 14:47:55 -0800 Subject: [PATCH 35/42] * fn-method --- src/test/clojure/cljs/analyzer/spec_tests.clj | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/test/clojure/cljs/analyzer/spec_tests.clj b/src/test/clojure/cljs/analyzer/spec_tests.clj index bafaf9245..c47fff5fb 100644 --- a/src/test/clojure/cljs/analyzer/spec_tests.clj +++ b/src/test/clojure/cljs/analyzer/spec_tests.clj @@ -96,7 +96,15 @@ (is (s/valid? ::a/node (analyze ns-env '(fn [x])))) (is (s/valid? ::a/node (analyze ns-env '(fn [x] 1))))) -;; fn-method +(deftest test-fn-method + (let [node (analyze ns-env '(fn ([]) ([x] x))) + methods (:methods node) + fn0 (first methods) + fn1 (second methods)] + (is (= :fn-method (:op fn0))) + (is (s/valid? ::a/node fn0)) + (is (= :fn-method (:op fn1))) + (is (s/valid? ::a/node fn1)))) (deftest test-host-call (let [node (analyze ns-env '(.substring "foo" 0 1))] From a91025a3af39fab1f5690c0ea30e44800099144f Mon Sep 17 00:00:00 2001 From: davidnolen Date: Wed, 20 Nov 2024 06:05:22 -0800 Subject: [PATCH 36/42] * test-local --- src/test/clojure/cljs/analyzer/spec_tests.clj | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/test/clojure/cljs/analyzer/spec_tests.clj b/src/test/clojure/cljs/analyzer/spec_tests.clj index c47fff5fb..b59c5022f 100644 --- a/src/test/clojure/cljs/analyzer/spec_tests.clj +++ b/src/test/clojure/cljs/analyzer/spec_tests.clj @@ -166,7 +166,13 @@ ;; list, no longer needed, subsumed by :quote -;; local +(deftest test-local + (let [node (analyze ns-env '(fn [x] x)) + fn-method (-> node :methods first) + body (-> fn-method :body) + ret (:ret body)] + (is (= :local (:op ret))) + (is (s/valid? ::a/node node)))) (deftest test-loop (let [node (analyze ns-env '(loop []))] From 1ce0ca772d03004de9c42b1030a8564a9f78888a Mon Sep 17 00:00:00 2001 From: davidnolen Date: Wed, 20 Nov 2024 06:21:46 -0800 Subject: [PATCH 37/42] * test-var --- src/test/clojure/cljs/analyzer/spec_tests.clj | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/test/clojure/cljs/analyzer/spec_tests.clj b/src/test/clojure/cljs/analyzer/spec_tests.clj index b59c5022f..4ea5f8d91 100644 --- a/src/test/clojure/cljs/analyzer/spec_tests.clj +++ b/src/test/clojure/cljs/analyzer/spec_tests.clj @@ -254,7 +254,13 @@ (is (= :try (:op node))) (is (s/valid? ::a/node node)))) -;; var +(deftest test-var + (let [node (no-warn (analyze ns-env '(fn [] x))) + fn-method (-> node :methods first) + body (-> fn-method :body) + ret (:ret body)] + (is (= :var (:op ret))) + (is (s/valid? ::a/node node)))) (deftest test-vector (let [node (no-warn (analyze ns-env '[1 2]))] From 0ad7f0415bed1b83d050bc84fbeb1ef13f86649c Mon Sep 17 00:00:00 2001 From: davidnolen Date: Wed, 20 Nov 2024 07:48:15 -0800 Subject: [PATCH 38/42] * missing information from try/catch processing, we need to add `:local` `:catch` so that `analyze-symbol` can pick it up later * add test-try --- src/main/clojure/cljs/analyzer.cljc | 6 +++++- src/test/clojure/cljs/analyzer/spec_tests.clj | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/clojure/cljs/analyzer.cljc b/src/main/clojure/cljs/analyzer.cljc index 47bb73dc4..3b88875b7 100644 --- a/src/main/clojure/cljs/analyzer.cljc +++ b/src/main/clojure/cljs/analyzer.cljc @@ -1880,7 +1880,11 @@ (assoc locals e {:name e :line (get-line e env) - :column (get-col e env)}) + :column (get-col e env) + ;; :local is required for {:op :local ...} nodes + ;; but previously we had no way to figure this out + ;; by adding it here we can recover it later + :local :catch}) locals) catch (when cblock (disallowing-recur (analyze (assoc catchenv :locals locals) cblock))) diff --git a/src/test/clojure/cljs/analyzer/spec_tests.clj b/src/test/clojure/cljs/analyzer/spec_tests.clj index 4ea5f8d91..48f3930bf 100644 --- a/src/test/clojure/cljs/analyzer/spec_tests.clj +++ b/src/test/clojure/cljs/analyzer/spec_tests.clj @@ -249,7 +249,7 @@ (is (= :throw (:op node))) (is (s/valid? ::a/node node)))) -#_(deftest test-try +(deftest test-try (let [node (no-warn (analyze ns-env '(try 1 (catch :default e) (finally))))] (is (= :try (:op node))) (is (s/valid? ::a/node node)))) From 125b4a20e767dde520564bd5f6abb8ead0093521 Mon Sep 17 00:00:00 2001 From: davidnolen Date: Wed, 20 Nov 2024 07:51:27 -0800 Subject: [PATCH 39/42] * clarify comment --- src/main/clojure/cljs/analyzer.cljc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/clojure/cljs/analyzer.cljc b/src/main/clojure/cljs/analyzer.cljc index 3b88875b7..887ae349a 100644 --- a/src/main/clojure/cljs/analyzer.cljc +++ b/src/main/clojure/cljs/analyzer.cljc @@ -1883,7 +1883,8 @@ :column (get-col e env) ;; :local is required for {:op :local ...} nodes ;; but previously we had no way to figure this out - ;; by adding it here we can recover it later + ;; for `catch` locals, by adding it here we can recover + ;; it later :local :catch}) locals) catch (when cblock From 867a26bc12485194e3a6d9dd076a4bdd87ca4a4c Mon Sep 17 00:00:00 2001 From: davidnolen Date: Wed, 20 Nov 2024 07:54:29 -0800 Subject: [PATCH 40/42] * test-js --- src/test/clojure/cljs/analyzer/spec_tests.clj | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/test/clojure/cljs/analyzer/spec_tests.clj b/src/test/clojure/cljs/analyzer/spec_tests.clj index 48f3930bf..c24a1b458 100644 --- a/src/test/clojure/cljs/analyzer/spec_tests.clj +++ b/src/test/clojure/cljs/analyzer/spec_tests.clj @@ -133,6 +133,11 @@ (is (= :invoke (:op node))) (is (s/valid? ::a/node node)))) +(deftest test-js + (let [node (analyze ns-env '(js* "~{}" 1))] + (is (= :js (:op node))) + (is (s/valid? ::a/node node)))) + (deftest test-js-array (let [node (analyze ns-env (ana-api/with-state (ana-api/empty-state) From 7bf09f0936dd1a490ebe4e407f7adc644d76c674 Mon Sep 17 00:00:00 2001 From: davidnolen Date: Wed, 20 Nov 2024 14:05:38 -0800 Subject: [PATCH 41/42] * :no-op only has :env & :op * test-no-op --- src/test/clojure/cljs/analyzer/spec_tests.clj | 6 +++++- src/test/clojure/cljs/analyzer/specs.cljc | 3 ++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/test/clojure/cljs/analyzer/spec_tests.clj b/src/test/clojure/cljs/analyzer/spec_tests.clj index c24a1b458..82509afbd 100644 --- a/src/test/clojure/cljs/analyzer/spec_tests.clj +++ b/src/test/clojure/cljs/analyzer/spec_tests.clj @@ -208,7 +208,11 @@ (is (s/valid? ::a/node (no-warn (analyze ns-env '(String.))))) (is (s/valid? ::a/node (analyze ns-env '(js/String.))))) -;; no-op +(deftest test-no-op + (let [node (binding [ana/*unchecked-if* true] + (no-warn (analyze ns-env '(set! *unchecked-if* false))))] + (is (= :no-op (:op node))) + (is (s/valid? ::a/node node)))) (deftest test-ns (let [node (no-warn diff --git a/src/test/clojure/cljs/analyzer/specs.cljc b/src/test/clojure/cljs/analyzer/specs.cljc index 08e94910e..c721a0a3f 100644 --- a/src/test/clojure/cljs/analyzer/specs.cljc +++ b/src/test/clojure/cljs/analyzer/specs.cljc @@ -220,7 +220,8 @@ :req-un [::class ::args]))) (defmethod node :no-op [_] - ::base) + (s/keys + :req-un [::env ::op])) (defmethod node :ns [_] ::base) From eb1b4a67892471ec0aeef8e27e2579eff08e6a98 Mon Sep 17 00:00:00 2001 From: davidnolen Date: Wed, 20 Nov 2024 14:16:19 -0800 Subject: [PATCH 42/42] * :js-object :keys are _not_ nodes --- src/test/clojure/cljs/analyzer/spec_tests.clj | 2 +- src/test/clojure/cljs/analyzer/specs.cljc | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/test/clojure/cljs/analyzer/spec_tests.clj b/src/test/clojure/cljs/analyzer/spec_tests.clj index 82509afbd..57134c703 100644 --- a/src/test/clojure/cljs/analyzer/spec_tests.clj +++ b/src/test/clojure/cljs/analyzer/spec_tests.clj @@ -145,7 +145,7 @@ (is (= :js-array (:op node))) (is (s/valid? ::a/node node)))) -#_(deftest test-js-object +(deftest test-js-object (let [node (analyze ns-env (ana-api/with-state (ana-api/empty-state) (first (ana-api/forms-seq (StringReader. "#js {:foo 1 :bar 2}")))))] diff --git a/src/test/clojure/cljs/analyzer/specs.cljc b/src/test/clojure/cljs/analyzer/specs.cljc index c721a0a3f..ec5079bf9 100644 --- a/src/test/clojure/cljs/analyzer/specs.cljc +++ b/src/test/clojure/cljs/analyzer/specs.cljc @@ -166,7 +166,7 @@ (defmethod node :js-object [_] (s/merge ::base (s/keys - :req-un [::keys ::vals]))) + :req-un [::vals]))) (s/def ::ns symbol?) @@ -205,7 +205,6 @@ (s/keys :req-un [::bindings ::body]))) -(s/def ::keys (s/* ::node)) (s/def ::vals (s/* ::node)) (defmethod node :map [_]