<commit_before>(ns om-css.core
  (:require [om-css.dom :as dom]
            [cljs.analyzer.api :as ana-api]
            [clojure.java.io :as io]
            [clojure.string :as string]
            [garden.core :as garden]))

(def css (atom {}))

(defn reshape-render
  ([form]
   (reshape-render form nil))
  ([form this-arg]
   (loop [dt (seq form) ret [] this-arg this-arg]
     (if dt
       (let [form (first dt)]
         (if (and (sequential? form) (not (empty? form)))
           (let [first-form (name (or (first form) ""))]
             (if (some #{(symbol first-form)} dom/all-tags)
               (let [[pre post] (split-at 1 form)]
                 (recur (next dt)
                   (conj ret
                     (concat pre (list this-arg) (reshape-render post this-arg)))
                   this-arg))
               (recur (next dt) (into ret [form])
                 (if (vector? form)
                   (first form)
                   this-arg))))
           (recur (next dt) (into ret [form]) this-arg)))
       (seq ret)))))

(defn reshape-defui [forms]
  (letfn [(split-on-object [forms]
            (split-with (complement '#{Object}) forms))
          (split-on-render [forms]
            (split-with
              (complement #('#{render} (first %)))
              forms))]
    (loop [dt (seq forms) dt' []]
      (if dt
        (let [[pre [sym & obj-forms :as post]] (split-on-object dt)
              dt' (into dt' pre)]
          (if (seq post)
            (let [[pre [render & post]] (split-on-render obj-forms)
                  new-render (reshape-render render)]
              (recur nil (-> (conj dt' sym)
                           (into (concat pre [new-render] post)))))
            (recur nil dt')))
        dt'))))

(defn get-style-form [forms]
  (loop [dt forms]
    (when (seq  dt)
      (let [form (first dt)]
        (if (and (not (sequential? form))
              (not (nil? form))
              (= (name form) "Style"))
          (fnext dt)
          (recur (rest dt)))))))

(defn reshape-style-form [form]
  (drop 2 form))

(defn get-component-style [forms]
  (-> forms
    get-style-form
    reshape-style-form
    first))

(defn- munge-ns-name [ns-name]
  (string/replace (munge ns-name) #"\." "_"))

(defn- format-class-name [ns-name component-name class-name]
  "generate namespace qualified classname"
  (let [ns-name ns-name
        class-name (name class-name)]
    (str "." (munge-ns-name ns-name)
      "_" component-name "_" (subs class-name 1))))

;; styles is the last arg because of thread-last in `defui*`
(defn format-style-classes [ns-name component-name styles]
  (->> styles
    (clojure.core/map
      #(cond
         (sequential? %)
         (format-style-classes ns-name component-name %)

         (and (keyword? %)
           (.startsWith (name %) "."))
         (format-class-name ns-name component-name %)

         :else %))
    (into [])))

;; TODO: runtime evaluation to support vars and fns
;; currently `load-string` fails if the style contains a var/function
;; call outside the scope of clojure.core
(defn defui* [name forms env]
  (let [ns-name (-> env :ns :name str)
        component-style (some->> (get-component-style forms)
                          (str "(clojure.core/refer 'clojure.core)")
                          load-string
                          (format-style-classes ns-name (str name)))
        css-str (when component-style
                  (garden/css component-style))
        forms (reshape-defui forms)
        forms (concat forms (list 'static 'field 'ns ns-name))]
    (when css-str
      (swap! css assoc [ns-name name] css-str))
    `(om.next/defui ~name ~@forms)))

(defmacro defui [name & forms]
  (defui* name forms &env))

(defn defcomponent*
  [env component-name [props children :as args] component-style body]
  "Example usage:
  (defcomponent foo
    [props children]
    (dom/div {:class \"foo\"}
             children))
  (foo (dom/a {:href \"http://google.com\"}))
  "
  (let [ns-name (-> env :ns :name str)
        css-str (when component-style
                  (garden/css (format-style-classes ns-name
                                (str component-name)
                                component-style)))
        _ (when css-str
            (swap! css assoc [ns-name component-name] css-str))
        body (reshape-render body {:ns-name ns-name
                                   :component-name (str component-name)})]
    (when-not (and (vector? args) (= (count args) 2))<commit_msg>fix `defcomponent` docstring<commit_after>(ns om-css.core
  (:require [om-css.dom :as dom]
            [cljs.analyzer.api :as ana-api]
            [clojure.java.io :as io]
            [clojure.string :as string]
            [garden.core :as garden]))

(def css (atom {}))

(defn reshape-render
  ([form]
   (reshape-render form nil))
  ([form this-arg]
   (loop [dt (seq form) ret [] this-arg this-arg]
     (if dt
       (let [form (first dt)]
         (if (and (sequential? form) (not (empty? form)))
           (let [first-form (name (or (first form) ""))]
             (if (some #{(symbol first-form)} dom/all-tags)
               (let [[pre post] (split-at 1 form)]
                 (recur (next dt)
                   (conj ret
                     (concat pre (list this-arg) (reshape-render post this-arg)))
                   this-arg))
               (recur (next dt) (into ret [form])
                 (if (vector? form)
                   (first form)
                   this-arg))))
           (recur (next dt) (into ret [form]) this-arg)))
       (seq ret)))))

(defn reshape-defui [forms]
  (letfn [(split-on-object [forms]
            (split-with (complement '#{Object}) forms))
          (split-on-render [forms]
            (split-with
              (complement #('#{render} (first %)))
              forms))]
    (loop [dt (seq forms) dt' []]
      (if dt
        (let [[pre [sym & obj-forms :as post]] (split-on-object dt)
              dt' (into dt' pre)]
          (if (seq post)
            (let [[pre [render & post]] (split-on-render obj-forms)
                  new-render (reshape-render render)]
              (recur nil (-> (conj dt' sym)
                           (into (concat pre [new-render] post)))))
            (recur nil dt')))
        dt'))))

(defn get-style-form [forms]
  (loop [dt forms]
    (when (seq  dt)
      (let [form (first dt)]
        (if (and (not (sequential? form))
              (not (nil? form))
              (= (name form) "Style"))
          (fnext dt)
          (recur (rest dt)))))))

(defn reshape-style-form [form]
  (drop 2 form))

(defn get-component-style [forms]
  (-> forms
    get-style-form
    reshape-style-form
    first))

(defn- munge-ns-name [ns-name]
  (string/replace (munge ns-name) #"\." "_"))

(defn- format-class-name [ns-name component-name class-name]
  "generate namespace qualified classname"
  (let [ns-name ns-name
        class-name (name class-name)]
    (str "." (munge-ns-name ns-name)
      "_" component-name "_" (subs class-name 1))))

;; styles is the last arg because of thread-last in `defui*`
(defn format-style-classes [ns-name component-name styles]
  (->> styles
    (clojure.core/map
      #(cond
         (sequential? %)
         (format-style-classes ns-name component-name %)

         (and (keyword? %)
           (.startsWith (name %) "."))
         (format-class-name ns-name component-name %)

         :else %))
    (into [])))

;; TODO: runtime evaluation to support vars and fns
;; currently `load-string` fails if the style contains a var/function
;; call outside the scope of clojure.core
(defn defui* [name forms env]
  (let [ns-name (-> env :ns :name str)
        component-style (some->> (get-component-style forms)
                          (str "(clojure.core/refer 'clojure.core)")
                          load-string
                          (format-style-classes ns-name (str name)))
        css-str (when component-style
                  (garden/css component-style))
        forms (reshape-defui forms)
        forms (concat forms (list 'static 'field 'ns ns-name))]
    (when css-str
      (swap! css assoc [ns-name name] css-str))
    `(om.next/defui ~name ~@forms)))

(defmacro defui [name & forms]
  (defui* name forms &env))

(defn defcomponent*
  [env component-name [props children :as args] component-style body]
  "Example usage:
   (defcomponent foo
     [props children]
     ;; optional styles vector
     [[:.foo {:color :green}]
     (dom/div {:class :foo}
              children))
   (foo (dom/a {:href \"http://google.com\"}))
   "
  (let [ns-name (-> env :ns :name str)
        css-str (when component-style
                  (garden/css (format-style-classes ns-name
                                (str component-name)
                                component-style)))
        _ (when css-str
            (swap! css assoc [ns-name component-name] css-str))
        body (reshape-render body {:ns-name ns-name
                                   :component-name (str component-name)})]
    (when-not (and (vector? args) (= (count args) 2))
{'fraction_non_alphanumeric': 0.15059909860393536, 'fraction_numerical': 0.0008794107947675058, 'mean_word_length': 1.810627123880136, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '482580', 'n_tokens_mistral': 2923, 'n_tokens_neox': 2845, 'n_words': 819}