<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.

(ns cljs.closure
  "Compile ClojureScript to JavaScript with optimizations from Google
   Closure Compiler producing runnable JavaScript.

   The Closure Compiler (compiler.jar) must be on the classpath.

   Use the 'build' function for end-to-end compilation.

   build = compile -> add-dependencies -> optimize -> output

   Two protocols are defined: IJavaScript and Compilable. The
   Compilable protocol is satisfied by something which can return one
   or more IJavaScripts.

   With IJavaScript objects in hand, calling add-dependencies will
   produce a sequence of IJavaScript objects which includes all
   required dependencies from the Closure library and ClojureScript,
   in dependency order. This function replaces the closurebuilder
   tool.

   The optimize function converts one or more IJavaScripts into a
   single string of JavaScript source code using the Closure Compiler
   API.

   The produced output is either a single string of optimized
   JavaScript or a deps file for use during development.
  "
  (:refer-clojure :exclude [compile])
  (:require [cljs.util :as util]
            [cljs.compiler :as comp]
            [cljs.analyzer :as ana]
            [cljs.source-map :as sm]
            [cljs.env :as env]
            [cljs.js-deps :as deps]
            [clojure.java.io :as io]
            [clojure.string :as string]
            [clojure.data.json :as json])
  (:import [java.io File BufferedInputStream StringWriter]
           [java.net URL]
           [java.util.logging Level]
           [java.util List Random]
           [java.util.concurrent TimeUnit]
           [com.google.javascript.jscomp CompilerOptions CompilationLevel
              CompilerOptions$LanguageMode SourceMap$Format
              SourceMap$DetailLevel ClosureCodingConvention SourceFile
              Result JSError CheckLevel DiagnosticGroups
              CommandLineRunner AnonymousFunctionNamingPolicy
              JSModule JSModuleGraph SourceMap ProcessCommonJSModules
              ES6ModuleLoader AbstractCompiler TransformAMDToCJSModule
              ProcessEs6Modules CompilerInput]
           [com.google.javascript.rhino Node]
           [java.security MessageDigest]
           [javax.xml.bind DatatypeConverter]
           [java.nio.file Path Paths Files StandardWatchEventKinds WatchKey
                          WatchEvent FileVisitor FileVisitResult]
           [com.sun.nio.file SensitivityWatchEventModifier]
           [com.google.common.base Throwables]))

(def name-chars (map char (concat (range 48 57) (range 65 90) (range 97 122))))

(defn random-char []
  (nth name-chars (.nextInt (Random.) (count name-chars))))

(defn random-string [length]
  (apply str (take length (repeatedly random-char))))

(util/compile-if
 (.getConstructor ES6ModuleLoader
   (into-array java.lang.Class
               [java.util.List java.lang.Iterable]))
 (do (def is-new-es6-loader? true)
     (def default-module-root ES6ModuleLoader/DEFAULT_FILENAME_PREFIX))
 (def is-new-es6-loader? false))

(util/compile-if
 (.getConstructor ES6ModuleLoader
   (into-array java.lang.Class
               [AbstractCompiler java.lang.String]))
 (def is-old-es6-loader? true)
 (def is-old-es6-loader? false))

(util/compile-if
 (and (.getConstructor ProcessCommonJSModules
        (into-array java.lang.Class
                    [com.google.javascript.jscomp.Compiler ES6ModuleLoader]))
      (or is-new-es6-loader? is-old-es6-loader?))
 (def can-convert-commonjs? true)
 (def can-convert-commonjs? false))

(util/compile-if
 (and can-convert-commonjs?
      (.getConstructor TransformAMDToCJSModule
        (into-array java.lang.Class
                    [AbstractCompiler])))
 (def can-convert-amd? true)
 (def can-convert-amd? false))

(util/compile-if
 (and (.getConstructor ProcessEs6Modules
        (into-array java.lang.Class
                    [com.google.javascript.jscomp.Compiler ES6ModuleLoader Boolean/TYPE]))
      (or is-new-es6-loader? is-old-es6-loader?))
 (def can-convert-es6? true)
 (def can-convert-es6? false))

;; Closure API
;; ===========

(defmulti js-source-file (fn [_ source] (class source)))

(defmethod js-source-file String [^String name ^String source]
  (SourceFile/fromCode name source))

(defmethod js-source-file File [_ ^File source]
  (SourceFile/fromFile source))

(defmethod js-source-file BufferedInputStream [^String name ^BufferedInputStream source]
  (SourceFile/fromInputStream name source))

(def check-level
  {:error CheckLevel/ERROR
   :warning CheckLevel/WARNING
   :off CheckLevel/OFF})

(def warning-types
  {:access-controls DiagnosticGroups/ACCESS_CONTROLS
   :ambiguous-function-decl DiagnosticGroups/AMBIGUOUS_FUNCTION_DECL
   :debugger-statement-present DiagnosticGroups/DEBUGGER_STATEMENT_PRESENT
   :check-regexp DiagnosticGroups/CHECK_REGEXP
   :check-types DiagnosticGroups/CHECK_TYPES
   :check-useless-code DiagnosticGroups/CHECK_USELESS_CODE
   :check-variables DiagnosticGroups/CHECK_VARIABLES
   :const DiagnosticGroups/CONST
   :constant-property DiagnosticGroups/CONSTANT_PROPERTY
   :deprecated DiagnosticGroups/DEPRECATED
   :duplicate-message DiagnosticGroups/DUPLICATE_MESSAGE
   :es5-strict DiagnosticGroups/ES5_STRICT
   :externs-validation DiagnosticGroups/EXTERNS_VALIDATION
   :fileoverview-jsdoc DiagnosticGroups/FILEOVERVIEW_JSDOC
   :global-this DiagnosticGroups/GLOBAL_THIS
   :internet-explorer-checks DiagnosticGroups/INTERNET_EXPLORER_CHECKS
   :invalid-casts DiagnosticGroups/INVALID_CASTS
   :missing-properties DiagnosticGroups/MISSING_PROPERTIES
   :non-standard-jsdoc DiagnosticGroups/NON_STANDARD_JSDOC
   :strict-module-dep-check DiagnosticGroups/STRICT_MODULE_DEP_CHECK
   :tweaks DiagnosticGroups/TWEAKS
   :undefined-names DiagnosticGroups/UNDEFINED_NAMES
   :undefined-variables DiagnosticGroups/UNDEFINED_VARIABLES
   :unknown-defines DiagnosticGroups/UNKNOWN_DEFINES
   :visiblity DiagnosticGroups/VISIBILITY})

(defn set-options
  "TODO: Add any other options that we would like to support."
  [opts ^CompilerOptions compiler-options]
  (when (contains? opts :pretty-print)
    (set! (.prettyPrint compiler-options) (:pretty-print opts)))

  (when (contains? opts :pseudo-names)
    (set! (.generatePseudoNames compiler-options) (:pseudo-names opts)))

  (when (contains? opts :anon-fn-naming-policy)
    (let [policy (:anon-fn-naming-policy opts)]
      (set! (.anonymousFunctionNaming compiler-options)
        (case policy
          :off AnonymousFunctionNamingPolicy/OFF
          :unmapped AnonymousFunctionNamingPolicy/UNMAPPED
          :mapped AnonymousFunctionNamingPolicy/MAPPED
          (throw (IllegalArgumentException. (str "Invalid :anon-fn-naming-policy value " policy " - only :off, :unmapped, :mapped permitted")))))))

  (when (contains? opts :language-in)
    (case (:language-in opts)
      :ecmascript5        (.setLanguageIn compiler-options CompilerOptions$LanguageMode/ECMASCRIPT5)
      :ecmascript5-strict (.setLanguageIn compiler-options CompilerOptions$LanguageMode/ECMASCRIPT5_STRICT)
      :ecmascript3        (.setLanguageIn compiler-options CompilerOptions$LanguageMode/ECMASCRIPT3)))

  (when (contains? opts :language-out)
    (case (:language-out opts)
      :ecmascript5        (.setLanguageOut compiler-options CompilerOptions$LanguageMode/ECMASCRIPT5)
      :ecmascript5-strict (.setLanguageOut compiler-options CompilerOptions$LanguageMode/ECMASCRIPT5_STRICT)
      :ecmascript3        (.setLanguageOut compiler-options CompilerOptions$LanguageMode/ECMASCRIPT3)))

  (when (contains? opts :print-input-delimiter)
    (set! (.printInputDelimiter compiler-options)
      (:print-input-delimiter opts)))

  (when (contains? opts :closure-warnings)
    (doseq [[type level] (:closure-warnings opts)]
      (. compiler-options
        (setWarningLevel (type warning-types) (level check-level)))))

  (when (contains? opts :closure-extra-annotations)
    (. compiler-options
      (setExtraAnnotationNames (map name (:closure-extra-annotations opts)))))

  compiler-options)

(defn ^CompilerOptions make-options
  "Create a CompilerOptions object and set options from opts map."
  [opts]
  (let [level (case (:optimizations opts)
                :advanced CompilationLevel/ADVANCED_OPTIMIZATIONS
                :whitespace CompilationLevel/WHITESPACE_ONLY
                :simple CompilationLevel/SIMPLE_OPTIMIZATIONS)<commit_msg>expose all lang-in/out Closure options<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.

(ns cljs.closure
  "Compile ClojureScript to JavaScript with optimizations from Google
   Closure Compiler producing runnable JavaScript.

   The Closure Compiler (compiler.jar) must be on the classpath.

   Use the 'build' function for end-to-end compilation.

   build = compile -> add-dependencies -> optimize -> output

   Two protocols are defined: IJavaScript and Compilable. The
   Compilable protocol is satisfied by something which can return one
   or more IJavaScripts.

   With IJavaScript objects in hand, calling add-dependencies will
   produce a sequence of IJavaScript objects which includes all
   required dependencies from the Closure library and ClojureScript,
   in dependency order. This function replaces the closurebuilder
   tool.

   The optimize function converts one or more IJavaScripts into a
   single string of JavaScript source code using the Closure Compiler
   API.

   The produced output is either a single string of optimized
   JavaScript or a deps file for use during development.
  "
  (:refer-clojure :exclude [compile])
  (:require [cljs.util :as util]
            [cljs.compiler :as comp]
            [cljs.analyzer :as ana]
            [cljs.source-map :as sm]
            [cljs.env :as env]
            [cljs.js-deps :as deps]
            [clojure.java.io :as io]
            [clojure.string :as string]
            [clojure.data.json :as json])
  (:import [java.io File BufferedInputStream StringWriter]
           [java.net URL]
           [java.util.logging Level]
           [java.util List Random]
           [java.util.concurrent TimeUnit]
           [com.google.javascript.jscomp CompilerOptions CompilationLevel
              CompilerOptions$LanguageMode SourceMap$Format
              SourceMap$DetailLevel ClosureCodingConvention SourceFile
              Result JSError CheckLevel DiagnosticGroups
              CommandLineRunner AnonymousFunctionNamingPolicy
              JSModule JSModuleGraph SourceMap ProcessCommonJSModules
              ES6ModuleLoader AbstractCompiler TransformAMDToCJSModule
              ProcessEs6Modules CompilerInput]
           [com.google.javascript.rhino Node]
           [java.security MessageDigest]
           [javax.xml.bind DatatypeConverter]
           [java.nio.file Path Paths Files StandardWatchEventKinds WatchKey
                          WatchEvent FileVisitor FileVisitResult]
           [com.sun.nio.file SensitivityWatchEventModifier]
           [com.google.common.base Throwables]))

(def name-chars (map char (concat (range 48 57) (range 65 90) (range 97 122))))

(defn random-char []
  (nth name-chars (.nextInt (Random.) (count name-chars))))

(defn random-string [length]
  (apply str (take length (repeatedly random-char))))

(util/compile-if
 (.getConstructor ES6ModuleLoader
   (into-array java.lang.Class
               [java.util.List java.lang.Iterable]))
 (do (def is-new-es6-loader? true)
     (def default-module-root ES6ModuleLoader/DEFAULT_FILENAME_PREFIX))
 (def is-new-es6-loader? false))

(util/compile-if
 (.getConstructor ES6ModuleLoader
   (into-array java.lang.Class
               [AbstractCompiler java.lang.String]))
 (def is-old-es6-loader? true)
 (def is-old-es6-loader? false))

(util/compile-if
 (and (.getConstructor ProcessCommonJSModules
        (into-array java.lang.Class
                    [com.google.javascript.jscomp.Compiler ES6ModuleLoader]))
      (or is-new-es6-loader? is-old-es6-loader?))
 (def can-convert-commonjs? true)
 (def can-convert-commonjs? false))

(util/compile-if
 (and can-convert-commonjs?
      (.getConstructor TransformAMDToCJSModule
        (into-array java.lang.Class
                    [AbstractCompiler])))
 (def can-convert-amd? true)
 (def can-convert-amd? false))

(util/compile-if
 (and (.getConstructor ProcessEs6Modules
        (into-array java.lang.Class
                    [com.google.javascript.jscomp.Compiler ES6ModuleLoader Boolean/TYPE]))
      (or is-new-es6-loader? is-old-es6-loader?))
 (def can-convert-es6? true)
 (def can-convert-es6? false))

;; Closure API
;; ===========

(defmulti js-source-file (fn [_ source] (class source)))

(defmethod js-source-file String [^String name ^String source]
  (SourceFile/fromCode name source))

(defmethod js-source-file File [_ ^File source]
  (SourceFile/fromFile source))

(defmethod js-source-file BufferedInputStream [^String name ^BufferedInputStream source]
  (SourceFile/fromInputStream name source))

(def check-level
  {:error CheckLevel/ERROR
   :warning CheckLevel/WARNING
   :off CheckLevel/OFF})

(def warning-types
  {:access-controls DiagnosticGroups/ACCESS_CONTROLS
   :ambiguous-function-decl DiagnosticGroups/AMBIGUOUS_FUNCTION_DECL
   :debugger-statement-present DiagnosticGroups/DEBUGGER_STATEMENT_PRESENT
   :check-regexp DiagnosticGroups/CHECK_REGEXP
   :check-types DiagnosticGroups/CHECK_TYPES
   :check-useless-code DiagnosticGroups/CHECK_USELESS_CODE
   :check-variables DiagnosticGroups/CHECK_VARIABLES
   :const DiagnosticGroups/CONST
   :constant-property DiagnosticGroups/CONSTANT_PROPERTY
   :deprecated DiagnosticGroups/DEPRECATED
   :duplicate-message DiagnosticGroups/DUPLICATE_MESSAGE
   :es5-strict DiagnosticGroups/ES5_STRICT
   :externs-validation DiagnosticGroups/EXTERNS_VALIDATION
   :fileoverview-jsdoc DiagnosticGroups/FILEOVERVIEW_JSDOC
   :global-this DiagnosticGroups/GLOBAL_THIS
   :internet-explorer-checks DiagnosticGroups/INTERNET_EXPLORER_CHECKS
   :invalid-casts DiagnosticGroups/INVALID_CASTS
   :missing-properties DiagnosticGroups/MISSING_PROPERTIES
   :non-standard-jsdoc DiagnosticGroups/NON_STANDARD_JSDOC
   :strict-module-dep-check DiagnosticGroups/STRICT_MODULE_DEP_CHECK
   :tweaks DiagnosticGroups/TWEAKS
   :undefined-names DiagnosticGroups/UNDEFINED_NAMES
   :undefined-variables DiagnosticGroups/UNDEFINED_VARIABLES
   :unknown-defines DiagnosticGroups/UNKNOWN_DEFINES
   :visiblity DiagnosticGroups/VISIBILITY})

(defn set-options
  "TODO: Add any other options that we would like to support."
  [opts ^CompilerOptions compiler-options]
  (when (contains? opts :pretty-print)
    (set! (.prettyPrint compiler-options) (:pretty-print opts)))

  (when (contains? opts :pseudo-names)
    (set! (.generatePseudoNames compiler-options) (:pseudo-names opts)))

  (when (contains? opts :anon-fn-naming-policy)
    (let [policy (:anon-fn-naming-policy opts)]
      (set! (.anonymousFunctionNaming compiler-options)
        (case policy
          :off AnonymousFunctionNamingPolicy/OFF
          :unmapped AnonymousFunctionNamingPolicy/UNMAPPED
          :mapped AnonymousFunctionNamingPolicy/MAPPED
          (throw (IllegalArgumentException. (str "Invalid :anon-fn-naming-policy value " policy " - only :off, :unmapped, :mapped permitted")))))))

  (when (contains? opts :language-in)
    (case (:language-in opts)
      :no-transpile       (.setLanguageIn compiler-options CompilerOptions$LanguageMode/NO_TRANSPILE)
      :ecmascript6        (.setLanguageIn compiler-options CompilerOptions$LanguageMode/ECMASCRIPT6)
      :ecmascript6-strict (.setLanguageIn compiler-options CompilerOptions$LanguageMode/ECMASCRIPT6_STRICT)
      :ecmascript6-typed  (.setLanguageIn compiler-options CompilerOptions$LanguageMode/ECMASCRIPT6_TYPED)
      :ecmascript5        (.setLanguageIn compiler-options CompilerOptions$LanguageMode/ECMASCRIPT5)
      :ecmascript5-strict (.setLanguageIn compiler-options CompilerOptions$LanguageMode/ECMASCRIPT5_STRICT)
      :ecmascript3        (.setLanguageIn compiler-options CompilerOptions$LanguageMode/ECMASCRIPT3)))

  (when (contains? opts :language-out)
    (case (:language-out opts)
      :no-transpile       (.setLanguageOut compiler-options CompilerOptions$LanguageMode/NO_TRANSPILE)
      :ecmascript6        (.setLanguageOut compiler-options CompilerOptions$LanguageMode/ECMASCRIPT6)
      :ecmascript6-strict (.setLanguageOut compiler-options CompilerOptions$LanguageMode/ECMASCRIPT6_STRICT)
      :ecmascript6-typed  (.setLanguageOut compiler-options CompilerOptions$LanguageMode/ECMASCRIPT6_TYPED)
      :ecmascript5        (.setLanguageOut compiler-options CompilerOptions$LanguageMode/ECMASCRIPT5)
      :ecmascript5-strict (.setLanguageOut compiler-options CompilerOptions$LanguageMode/ECMASCRIPT5_STRICT)
      :ecmascript3        (.setLanguageOut compiler-options CompilerOptions$LanguageMode/ECMASCRIPT3)))

  (when (contains? opts :print-input-delimiter)
    (set! (.printInputDelimiter compiler-options)
      (:print-input-delimiter opts)))

  (when (contains? opts :closure-warnings)
    (doseq [[type level] (:closure-warnings opts)]
      (. compiler-options
        (setWarningLevel (type warning-types) (level check-level)))))

  (when (contains? opts :closure-extra-annotations)
    (. compiler-options
      (setExtraAnnotationNames (map name (:closure-extra-annotations opts)))))

  compiler-options)

(defn ^CompilerOptions make-options
  "Create a CompilerOptions object and set options from opts map."
  [opts]
  (let [level (case (:optimizations opts)
                :advanced CompilationLevel/ADVANCED_OPTIMIZATIONS
                :whitespace CompilationLevel/WHITESPACE_ONLY
                :simple CompilationLevel/SIMPLE_OPTIMIZATIONS)
{'fraction_non_alphanumeric': 0.09024745269286755, 'fraction_numerical': 0.006145883875141517, 'mean_word_length': 3.6155760139338144, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6119682', 'n_tokens_mistral': 5596, 'n_tokens_neox': 5265, 'n_words': 1345}