<commit_before>;   Copyright (c) <NAME>. 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.

(set! *warn-on-reflection* true)

(ns cljs.compiler
  (:refer-clojure :exclude [munge macroexpand-1])
  (:require [clojure.java.io :as io]
            [clojure.string :as string]
            [clojure.tools.reader :as reader]
            [cljs.env :as env]
            [cljs.tagged-literals :as tags]
            [cljs.analyzer :as ana]
            [cljs.source-map :as sm])
  (:import java.lang.StringBuilder
           java.io.File))

;; next line is auto-generated by the build-script - Do not edit!
(def ^:dynamic *clojurescript-version*)

(defn clojurescript-version 
  "Returns clojurescript version as a printable string."
  []
  (str
    (:major *clojurescript-version*)
    "."
    (:minor *clojurescript-version*)
    (when-let [i (:incremental *clojurescript-version*)]
      (str "." i))
    (when-let [q (:qualifier *clojurescript-version*)]
      (str "-" q))
    (when (:interim *clojurescript-version*)
      "-SNAPSHOT")))

(def js-reserved
  #{"abstract" "boolean" "break" "byte" "case"
    "catch" "char" "class" "const" "continue"
    "debugger" "default" "delete" "do" "double"
    "else" "enum" "export" "extends" "final"
    "finally" "float" "for" "function" "goto" "if"
    "implements" "import" "in" "instanceof" "int"
    "interface" "let" "long" "native" "new"
    "package" "private" "protected" "public"
    "return" "short" "static" "super" "switch"
    "synchronized" "this" "throw" "throws"
    "transient" "try" "typeof" "var" "void"
    "volatile" "while" "with" "yield" "methods"
    "null"})

(def ^:dynamic *source-map-data* nil)
(def ^:dynamic *lexical-renames* {})

(def cljs-reserved-file-names #{"deps.cljs"})

(defmacro ^:private debug-prn
  [& args]
  `(.println System/err (str ~@args)))

(defn ns-first-segments []
  (letfn [(get-first-ns-segment [ns] (first (string/split (str ns) #"\.")))]
    (map get-first-ns-segment (keys (::ana/namespaces @env/*compiler*)))))

; Helper fn
(defn shadow-depth [s]
  (let [{:keys [name info]} s]
    (loop [d 0, {:keys [shadow]} info]
      (cond
       shadow (recur (inc d) shadow)
       (some #{(str name)} (ns-first-segments)) (inc d)
       :else d))))

(defn munge
  ([s] (munge s js-reserved))
  ([s reserved]
    (if (map? s)
      ; Unshadowing
      (let [{:keys [name field] :as info} s
            depth (shadow-depth s)
            renamed (*lexical-renames* (System/identityHashCode s))
            munged-name (munge (cond field (str "self__." name)
                                     renamed renamed
                                     :else name)
                               reserved)]
        (if (or field (zero? depth))
          munged-name
          (symbol (str munged-name "__$" depth))))
      ; String munging
      (let [ss (string/replace (str s) #"\/(.)" ".$1") ; Division is special
            ss (apply str (map #(if (reserved %) (str % "$") %)
                               (string/split ss #"(?<=\.)|(?=\.)")))
            ms (clojure.lang.Compiler/munge ss)]
        (if (symbol? s)
          (symbol ms)
          ms)))))

(defn- comma-sep [xs]
  (interpose "," xs))

(defn- escape-char [^Character c]
  (let [cp (.hashCode c)]
    (case cp
      ; Handle printable escapes before ASCII
      34 "\\\""
      92 "\\\\"
      ; Handle non-printable escapes
      8 "\\b"
      12 "\\f"
      10 "\\n"
      13 "\\r"
      9 "\\t"
      (if (< 31 cp 127)
        c ; Print simple ASCII characters
        (format "\\u%04X" cp))))) ; Any other character is Unicode

(defn- escape-string [^CharSequence s]
  (let [sb (StringBuilder. (count s))]
    (doseq [c s]
      (.append sb (escape-char c)))
    (.toString sb)))

(defn- wrap-in-double-quotes [x]
  (str \" x \"))

(defmulti emit* :op)

(defn emit [ast]
  (env/ensure
    (emit* ast)))

(defn emits [& xs]
  (doseq [x xs]
    (cond
     (nil? x) nil
     (map? x) (emit x)
     (seq? x) (apply emits x)
     (fn? x)  (x)
     :else (let [s (print-str x)]
             (when *source-map-data*
               (swap! *source-map-data*
                 update-in [:gen-col] #(+ % (count s))))
             (print s))))
  nil)

(defn emitln [& xs]
  (apply emits xs)
  (println)
  (when *source-map-data*
    (swap! *source-map-data*
      (fn [{:keys [gen-line] :as m}]
        (assoc m
          :gen-line (inc gen-line)
          :gen-col 0))))
  nil)

(defn ^String emit-str [expr]
  (with-out-str (emit expr)))

(defmulti emit-constant class)
(defmethod emit-constant nil [x] (emits "null"))
(defmethod emit-constant Long [x] (emits x))
(defmethod emit-constant Integer [x] (emits x)) ; reader puts Integers in metadata
(defmethod emit-constant Double [x] (emits x))
(defmethod emit-constant String [x]
  (emits (wrap-in-double-quotes (escape-string x))))
(defmethod emit-constant Boolean [x] (emits (if x "true" "false")))
(defmethod emit-constant Character [x]
  (emits (wrap-in-double-quotes (escape-char x))))

(defmethod emit-constant java.util.regex.Pattern [x]
  (if (= "" (str x))
    (emits "(new RegExp(\"\"))")
    (let [[_ flags pattern] (re-find #"^(?:\(\?([idmsux]*)\))?(.*)" (str x))]
      (emits \/ (.replaceAll (re-matcher #"/" pattern) "\\\\/") \/ flags))))

(def ^:const goog-hash-max 0x100000000)

(defn goog-string-hash [s]
  (reduce
    (fn [r c]
      (mod (+ (* 31 r) (int c)) goog-hash-max))
    0 s))

(defmethod emit-constant clojure.lang.Keyword [x]
  (if (-> @env/*compiler* :opts :emit-constants)
    (let [value (-> @env/*compiler* ::ana/constant-table x)]
      (emits "cljs.core." value))
    (let [ns   (namespace x)
          name (name x)]
      (emits "new cljs.core.Keyword(")
      (emit-constant ns)
      (emits ",")
      (emit-constant name)
      (emits ",")
      (emit-constant (if ns
                       (str ns "/" name)
                       name))
      (emits ",")
      (emit-constant (+ (clojure.lang.Util/hashCombine
                          (unchecked-int (goog-string-hash ns))
                          (unchecked-int (goog-string-hash name)))
                         0x9e3779b9))
      (emits ")"))))

(defmethod emit-constant clojure.lang.Symbol [x]
  (let [ns     (namespace x)
        name   (name x)
        symstr (if-not (nil? ns)
                 (str ns "/" name)
                 name)]
    (emits "new cljs.core.Symbol(")
    (emit-constant ns)
    (emits ",")
    (emit-constant name)
    (emits ",")
    (emit-constant symstr)
    (emits ",")
    (emit-constant (clojure.lang.Util/hashCombine
                     (unchecked-int (goog-string-hash ns))
                     (unchecked-int (goog-string-hash name))))
    (emits ",")
    (emit-constant nil)
    (emits ")")))

(defmacro emit-wrap [env & body]
  `(let [env# ~env]
     (when (= :return (:context env#)) (emits "return "))
     ~@body
     (when-not (= :expr (:context env#)) (emitln ";"))))

(defmethod emit* :no-op [m])

(defmethod emit* :var
  [{:keys [info env] :as arg}]
  (let [var-name (:name info)
        info (if (= (namespace var-name) "js")
               (name var-name)
               info)]
    (when *source-map-data*
      (when (and (:line env) (symbol? var-name))
        (let [{:keys [line column]} env]
          (swap! *source-map-data*
            (fn [m]
              (let [minfo {:gcol  (:gen-col m)
                           :gline (:gen-line m)
                           :name  var-name}]
                ; Dec the line number for 0-indexed line numbers.
                ; tools.reader has 0-indexed line number, chrome
                ; expects 1-indexed source maps.
                (update-in m [:source-map (dec line)]
                  (fnil (fn [line]
                          (update-in line [(or column 0)]
                            (fnil (fn [column] (conj column minfo)) [])))
                    (sorted-map)))))))))
    ; We need a way to write bindings out to source maps and javascript
    ; without getting wrapped in an emit-wrap calls, otherwise we get
    ; e.g. (function greet(return x, return y) {}).
    (if (:binding-form? arg)
      ; Emit the arg map so shadowing is properly handled when munging
      ; (prevents duplicate fn-param-names)
      (emits (munge arg))
      (when-not (= :statement (:context env))
        (emit-wrap env (emits (munge info)))))))

(defmethod emit* :meta
  [{:keys [expr meta env]}]
  (emit-wrap env
    (emits "cljs.core.with_meta(" expr "," meta ")")))

(def ^:private array-map-threshold 8)
(def ^:private obj-map-threshold 8)

(defmethod emit* :map
  [{:keys [env keys vals]}]
  (let [simple-keys? (every? #(or (string? %) (keyword? %)) keys)]
    (emit-wrap env
      (cond
        (zero? (count keys))<commit_msg>emit source map info for every AST node not just vars<commit_after>;   Copyright (c) <NAME>. 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.

(set! *warn-on-reflection* true)

(ns cljs.compiler
  (:refer-clojure :exclude [munge macroexpand-1])
  (:require [clojure.java.io :as io]
            [clojure.string :as string]
            [clojure.tools.reader :as reader]
            [cljs.env :as env]
            [cljs.tagged-literals :as tags]
            [cljs.analyzer :as ana]
            [cljs.source-map :as sm])
  (:import java.lang.StringBuilder
           java.io.File))

;; next line is auto-generated by the build-script - Do not edit!
(def ^:dynamic *clojurescript-version*)

(defn clojurescript-version 
  "Returns clojurescript version as a printable string."
  []
  (str
    (:major *clojurescript-version*)
    "."
    (:minor *clojurescript-version*)
    (when-let [i (:incremental *clojurescript-version*)]
      (str "." i))
    (when-let [q (:qualifier *clojurescript-version*)]
      (str "-" q))
    (when (:interim *clojurescript-version*)
      "-SNAPSHOT")))

(def js-reserved
  #{"abstract" "boolean" "break" "byte" "case"
    "catch" "char" "class" "const" "continue"
    "debugger" "default" "delete" "do" "double"
    "else" "enum" "export" "extends" "final"
    "finally" "float" "for" "function" "goto" "if"
    "implements" "import" "in" "instanceof" "int"
    "interface" "let" "long" "native" "new"
    "package" "private" "protected" "public"
    "return" "short" "static" "super" "switch"
    "synchronized" "this" "throw" "throws"
    "transient" "try" "typeof" "var" "void"
    "volatile" "while" "with" "yield" "methods"
    "null"})

(def ^:dynamic *source-map-data* nil)
(def ^:dynamic *lexical-renames* {})

(def cljs-reserved-file-names #{"deps.cljs"})

(defmacro ^:private debug-prn
  [& args]
  `(.println System/err (str ~@args)))

(defn ns-first-segments []
  (letfn [(get-first-ns-segment [ns] (first (string/split (str ns) #"\.")))]
    (map get-first-ns-segment (keys (::ana/namespaces @env/*compiler*)))))

; Helper fn
(defn shadow-depth [s]
  (let [{:keys [name info]} s]
    (loop [d 0, {:keys [shadow]} info]
      (cond
       shadow (recur (inc d) shadow)
       (some #{(str name)} (ns-first-segments)) (inc d)
       :else d))))

(defn munge
  ([s] (munge s js-reserved))
  ([s reserved]
    (if (map? s)
      ; Unshadowing
      (let [{:keys [name field] :as info} s
            depth (shadow-depth s)
            renamed (*lexical-renames* (System/identityHashCode s))
            munged-name (munge (cond field (str "self__." name)
                                     renamed renamed
                                     :else name)
                               reserved)]
        (if (or field (zero? depth))
          munged-name
          (symbol (str munged-name "__$" depth))))
      ; String munging
      (let [ss (string/replace (str s) #"\/(.)" ".$1") ; Division is special
            ss (apply str (map #(if (reserved %) (str % "$") %)
                               (string/split ss #"(?<=\.)|(?=\.)")))
            ms (clojure.lang.Compiler/munge ss)]
        (if (symbol? s)
          (symbol ms)
          ms)))))

(defn- comma-sep [xs]
  (interpose "," xs))

(defn- escape-char [^Character c]
  (let [cp (.hashCode c)]
    (case cp
      ; Handle printable escapes before ASCII
      34 "\\\""
      92 "\\\\"
      ; Handle non-printable escapes
      8 "\\b"
      12 "\\f"
      10 "\\n"
      13 "\\r"
      9 "\\t"
      (if (< 31 cp 127)
        c ; Print simple ASCII characters
        (format "\\u%04X" cp))))) ; Any other character is Unicode

(defn- escape-string [^CharSequence s]
  (let [sb (StringBuilder. (count s))]
    (doseq [c s]
      (.append sb (escape-char c)))
    (.toString sb)))

(defn- wrap-in-double-quotes [x]
  (str \" x \"))

(defmulti emit* :op)

(defn emit [ast]
  (env/ensure
    (when *source-map-data*
      (let [{:keys [env]} ast]
        (when (:line env)
          (let [{:keys [line column]} env]
            (swap! *source-map-data*
              (fn [m]
                (let [minfo (cond-> {:gcol (:gen-col m)
                                     :gline (:gen-line m)}
                              (= (:op ast) :var)
                              (assoc :name (-> ast :info :name)))]
                  ; Dec the line number for 0-indexed line numbers.
                  ; tools.reader has 0-indexed line number, chrome
                  ; expects 1-indexed source maps.
                  (update-in m [:source-map (dec line)]
                    (fnil (fn [line]
                            (update-in line [(or column 0)]
                              (fnil (fn [column] (conj column minfo)) [])))
                      (sorted-map))))))))))
    (emit* ast)))

(defn emits [& xs]
  (doseq [x xs]
    (cond
     (nil? x) nil
     (map? x) (emit x)
     (seq? x) (apply emits x)
     (fn? x)  (x)
     :else (let [s (print-str x)]
             (when *source-map-data*
               (swap! *source-map-data*
                 update-in [:gen-col] #(+ % (count s))))
             (print s))))
  nil)

(defn emitln [& xs]
  (apply emits xs)
  (println)
  (when *source-map-data*
    (swap! *source-map-data*
      (fn [{:keys [gen-line] :as m}]
        (assoc m
          :gen-line (inc gen-line)
          :gen-col 0))))
  nil)

(defn ^String emit-str [expr]
  (with-out-str (emit expr)))

(defmulti emit-constant class)
(defmethod emit-constant nil [x] (emits "null"))
(defmethod emit-constant Long [x] (emits x))
(defmethod emit-constant Integer [x] (emits x)) ; reader puts Integers in metadata
(defmethod emit-constant Double [x] (emits x))
(defmethod emit-constant String [x]
  (emits (wrap-in-double-quotes (escape-string x))))
(defmethod emit-constant Boolean [x] (emits (if x "true" "false")))
(defmethod emit-constant Character [x]
  (emits (wrap-in-double-quotes (escape-char x))))

(defmethod emit-constant java.util.regex.Pattern [x]
  (if (= "" (str x))
    (emits "(new RegExp(\"\"))")
    (let [[_ flags pattern] (re-find #"^(?:\(\?([idmsux]*)\))?(.*)" (str x))]
      (emits \/ (.replaceAll (re-matcher #"/" pattern) "\\\\/") \/ flags))))

(def ^:const goog-hash-max 0x100000000)

(defn goog-string-hash [s]
  (reduce
    (fn [r c]
      (mod (+ (* 31 r) (int c)) goog-hash-max))
    0 s))

(defmethod emit-constant clojure.lang.Keyword [x]
  (if (-> @env/*compiler* :opts :emit-constants)
    (let [value (-> @env/*compiler* ::ana/constant-table x)]
      (emits "cljs.core." value))
    (let [ns   (namespace x)
          name (name x)]
      (emits "new cljs.core.Keyword(")
      (emit-constant ns)
      (emits ",")
      (emit-constant name)
      (emits ",")
      (emit-constant (if ns
                       (str ns "/" name)
                       name))
      (emits ",")
      (emit-constant (+ (clojure.lang.Util/hashCombine
                          (unchecked-int (goog-string-hash ns))
                          (unchecked-int (goog-string-hash name)))
                         0x9e3779b9))
      (emits ")"))))

(defmethod emit-constant clojure.lang.Symbol [x]
  (let [ns     (namespace x)
        name   (name x)
        symstr (if-not (nil? ns)
                 (str ns "/" name)
                 name)]
    (emits "new cljs.core.Symbol(")
    (emit-constant ns)
    (emits ",")
    (emit-constant name)
    (emits ",")
    (emit-constant symstr)
    (emits ",")
    (emit-constant (clojure.lang.Util/hashCombine
                     (unchecked-int (goog-string-hash ns))
                     (unchecked-int (goog-string-hash name))))
    (emits ",")
    (emit-constant nil)
    (emits ")")))

(defmacro emit-wrap [env & body]
  `(let [env# ~env]
     (when (= :return (:context env#)) (emits "return "))
     ~@body
     (when-not (= :expr (:context env#)) (emitln ";"))))

(defmethod emit* :no-op [m])

(defmethod emit* :var
  [{:keys [info env] :as arg}]
  (let [var-name (:name info)
        info (if (= (namespace var-name) "js")
               (name var-name)
               info)]
    ; We need a way to write bindings out to source maps and javascript
    ; without getting wrapped in an emit-wrap calls, otherwise we get
    ; e.g. (function greet(return x, return y) {}).
    (if (:binding-form? arg)
      ; Emit the arg map so shadowing is properly handled when munging
      ; (prevents duplicate fn-param-names)
      (emits (munge arg))
      (when-not (= :statement (:context env))
        (emit-wrap env (emits (munge info)))))))

(defmethod emit* :meta
  [{:keys [expr meta env]}]
  (emit-wrap env
    (emits "cljs.core.with_meta(" expr "," meta ")")))

(def ^:private array-map-threshold 8)
(def ^:private obj-map-threshold 8)

(defmethod emit* :map
  [{:keys [env keys vals]}]
  (let [simple-keys? (every? #(or (string? %) (keyword? %)) keys)]
    (emit-wrap env
      (cond
        (zero? (count keys))
{'fraction_non_alphanumeric': 0.16909922666376212, 'fraction_numerical': 0.005990632828667901, 'mean_word_length': 2.144349315068493, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 7, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '88282', 'n_tokens_mistral': 6485, 'n_tokens_neox': 6206, 'n_words': 1813}