From 146877c62f853dbb1654850bea82052ad7614d92 Mon Sep 17 00:00:00 2001 From: Chris Oakman Date: Tue, 22 Oct 2024 10:01:09 -0500 Subject: [PATCH] GitHub Issue #137 - only process the first ns form --- lib/standard-clojure-style.js | 2 +- test_format/format.eno | 234 ++++++++++++++++++++++++++++++++++ 2 files changed, 235 insertions(+), 1 deletion(-) diff --git a/lib/standard-clojure-style.js b/lib/standard-clojure-style.js index 78901b8..723a277 100644 --- a/lib/standard-clojure-style.js +++ b/lib/standard-clojure-style.js @@ -3345,7 +3345,7 @@ nodesArr = recordOriginalColIndexes(nodesArr, idx) } - if (parenNestingDepth === 1 && isNsNode(node)) { + if (nsStartStringIdx === -1 && parenNestingDepth === 1 && isNsNode(node)) { insideNsForm = true nsStartStringIdx = strLen(strConcat(outTxt, lineTxt)) } diff --git a/test_format/format.eno b/test_format/format.eno index d57f37e..bc831e3 100644 --- a/test_format/format.eno +++ b/test_format/format.eno @@ -1718,3 +1718,237 @@ hee, haz, gee, gaz hee, haz --Expected + +# GitHub Issue #137 - defmacro ns + +> https://github.com/oakmac/standard-clojure-style-js/issues/137 + +--Input +; 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 ^{:doc "The core Clojure language." + :author "Rich Hickey"} + clojure.core) + +(def unquote) +(def unquote-splicing) + +(def + ^{:arglists '([& items]) + :doc "Creates a new list containing the items." + :added "1.0"} + list (. clojure.lang.PersistentList creator)) + +(def + ^{:arglists '([x seq]) + :doc "Returns a new seq where x is the first element and seq is + the rest." + :added "1.0" + :static true} + + cons (fn* ^:static cons [x seq] (. clojure.lang.RT (cons x seq)))) + +;during bootstrap we don't have destructuring let, loop or fn, will redefine later +(def + ^{:macro true + :added "1.0"} + let (fn* let [&form &env & decl] (cons 'let* decl))) + +;; ... + +(declare gen-class) + +(defmacro with-loading-context [& body] + `((fn loading# [] + (. clojure.lang.Var (pushThreadBindings {clojure.lang.Compiler/LOADER + (.getClassLoader (.getClass ^Object loading#))})) + (try + ~@body + (finally + (. clojure.lang.Var (popThreadBindings))))))) + +(defmacro ns + "Sets *ns* to the namespace named by name (unevaluated), creating it + if needed. references can be zero or more of: (:refer-clojure ...) + (:require ...) (:use ...) (:import ...) (:load ...) (:gen-class) + with the syntax of refer-clojure/require/use/import/load/gen-class + respectively, except the arguments are unevaluated and need not be + quoted. (:gen-class ...), when supplied, defaults to :name + corresponding to the ns name, :main true, :impl-ns same as ns, and + :init-impl-ns true. All options of gen-class are + supported. The :gen-class directive is ignored when not + compiling. If :gen-class is not supplied, when compiled only an + nsname__init.class will be generated. If :refer-clojure is not used, a + default (refer 'clojure.core) is used. Use of ns is preferred to + individual calls to in-ns/require/use/import: + + (ns foo.bar + (:refer-clojure :exclude [ancestors printf]) + (:require (clojure.contrib sql combinatorics)) + (:use (my.lib this that)) + (:import (java.util Date Timer Random) + (java.sql Connection Statement)))" + {:arglists '([name docstring? attr-map? references*]) + :added "1.0"} + [name & references] + (let [process-reference + (fn [[kname & args]] + `(~(symbol "clojure.core" (clojure.core/name kname)) + ~@(map #(list 'quote %) args))) + docstring (when (string? (first references)) (first references)) + references (if docstring (next references) references) + name (if docstring + (vary-meta name assoc :doc docstring) + name) + metadata (when (map? (first references)) (first references)) + references (if metadata (next references) references) + name (if metadata + (vary-meta name merge metadata) + name) + gen-class-clause (first (filter #(= :gen-class (first %)) references)) + gen-class-call + (when gen-class-clause + (list* `gen-class :name (.replace (str name) \- \_) :impl-ns name :main true (next gen-class-clause))) + references (remove #(= :gen-class (first %)) references) + ;ns-effect (clojure.core/in-ns name) + name-metadata (meta name)] + `(do + (clojure.core/in-ns '~name) + ~@(when name-metadata + `((.resetMeta (clojure.lang.Namespace/find '~name) ~name-metadata))) + (with-loading-context + ~@(when gen-class-call (list gen-class-call)) + ~@(when (and (not= name 'clojure.core) (not-any? #(= :refer-clojure (first %)) references)) + `((clojure.core/refer '~'clojure.core))) + ~@(map process-reference references)) + (if (.equals '~name 'clojure.core) + nil + (do (dosync (commute @#'*loaded-libs* conj '~name)) nil))))) + +(defmacro refer-clojure + "Same as (refer 'clojure.core )" + {:added "1.0"} + [& filters] + `(clojure.core/refer '~'clojure.core ~@filters)) +--Input + +--Expected +; 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 clojure.core + {:doc "The core Clojure language." + :author "Rich Hickey"}) + +(def unquote) +(def unquote-splicing) + +(def + ^{:arglists '([& items]) + :doc "Creates a new list containing the items." + :added "1.0"} + list (. clojure.lang.PersistentList creator)) + +(def + ^{:arglists '([x seq]) + :doc "Returns a new seq where x is the first element and seq is + the rest." + :added "1.0" + :static true} + + cons (fn* ^:static cons [x seq] (. clojure.lang.RT (cons x seq)))) + +; during bootstrap we don't have destructuring let, loop or fn, will redefine later +(def + ^{:macro true + :added "1.0"} + let (fn* let [&form &env & decl] (cons 'let* decl))) + +;; ... + +(declare gen-class) + +(defmacro with-loading-context [& body] + `((fn loading# [] + (. clojure.lang.Var (pushThreadBindings {clojure.lang.Compiler/LOADER + (.getClassLoader (.getClass ^Object loading#))})) + (try + ~@body + (finally + (. clojure.lang.Var (popThreadBindings))))))) + +(defmacro ns + "Sets *ns* to the namespace named by name (unevaluated), creating it + if needed. references can be zero or more of: (:refer-clojure ...) + (:require ...) (:use ...) (:import ...) (:load ...) (:gen-class) + with the syntax of refer-clojure/require/use/import/load/gen-class + respectively, except the arguments are unevaluated and need not be + quoted. (:gen-class ...), when supplied, defaults to :name + corresponding to the ns name, :main true, :impl-ns same as ns, and + :init-impl-ns true. All options of gen-class are + supported. The :gen-class directive is ignored when not + compiling. If :gen-class is not supplied, when compiled only an + nsname__init.class will be generated. If :refer-clojure is not used, a + default (refer 'clojure.core) is used. Use of ns is preferred to + individual calls to in-ns/require/use/import: + + (ns foo.bar + (:refer-clojure :exclude [ancestors printf]) + (:require (clojure.contrib sql combinatorics)) + (:use (my.lib this that)) + (:import (java.util Date Timer Random) + (java.sql Connection Statement)))" + {:arglists '([name docstring? attr-map? references*]) + :added "1.0"} + [name & references] + (let [process-reference + (fn [[kname & args]] + `(~(symbol "clojure.core" (clojure.core/name kname)) + ~@(map #(list 'quote %) args))) + docstring (when (string? (first references)) (first references)) + references (if docstring (next references) references) + name (if docstring + (vary-meta name assoc :doc docstring) + name) + metadata (when (map? (first references)) (first references)) + references (if metadata (next references) references) + name (if metadata + (vary-meta name merge metadata) + name) + gen-class-clause (first (filter #(= :gen-class (first %)) references)) + gen-class-call + (when gen-class-clause + (list* `gen-class :name (.replace (str name) \- \_) :impl-ns name :main true (next gen-class-clause))) + references (remove #(= :gen-class (first %)) references) + ; ns-effect (clojure.core/in-ns name) + name-metadata (meta name)] + `(do + (clojure.core/in-ns '~name) + ~@(when name-metadata + `((.resetMeta (clojure.lang.Namespace/find '~name) ~name-metadata))) + (with-loading-context + ~@(when gen-class-call (list gen-class-call)) + ~@(when (and (not= name 'clojure.core) (not-any? #(= :refer-clojure (first %)) references)) + `((clojure.core/refer '~'clojure.core))) + ~@(map process-reference references)) + (if (.equals '~name 'clojure.core) + nil + (do (dosync (commute @#'*loaded-libs* conj '~name)) nil))))) + +(defmacro refer-clojure + "Same as (refer 'clojure.core )" + {:added "1.0"} + [& filters] + `(clojure.core/refer '~'clojure.core ~@filters)) +--Expected