Skip to content

Instantly share code, notes, and snippets.

@thheller
Last active December 13, 2015 20:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save thheller/4972200 to your computer and use it in GitHub Desktop.
Save thheller/4972200 to your computer and use it in GitHub Desktop.
A name for every CLJS fn
(ns dummy
(:require [clojure.string :as str]))
(.log js/console (pr-str name))
(defn unmunge [s]
(-> s
(str/replace #"_DOT_" ".")
(str/replace #"_" "-")
))
(defn get-func-signature [func]
(let [name (.-name func)]
(when (seq name)
(let [[_ ns fn-name line :as x] (re-find #"fn_(.+)_SLASH_(.+)_(\d+)" name)]
(if x
(str (unmunge ns) "/" (unmunge fn-name) " line:" line)
name)))
))
(extend-type js/Function
IPrintWithWriter
(-pr-writer [this writer opts]
(if-let [sig (get-func-signature this)]
(-write writer (str "#<function " sig ">"))
(-write writer (str "#<" this ">"))
)))
(.log js/console (pr-str name))
(.log js/console (pr-str js/goog.base))
From bbb8c39223130de03c56825c17a7ae9f3730d0e3 Mon Sep 17 00:00:00 2001
From: Thomas Heller <info@zilence.net>
Date: Sun, 17 Feb 2013 17:36:34 +0100
Subject: [PATCH] generate a javascript function <name>() for every fn
makes debugging a whole lot easier
---
src/clj/cljs/analyzer.clj | 42 ++++++++++++++++++++++++++++++++++++++++--
1 files changed, 40 insertions(+), 2 deletions(-)
diff --git a/src/clj/cljs/analyzer.clj b/src/clj/cljs/analyzer.clj
index f379d8d..59eddcd 100644
--- a/src/clj/cljs/analyzer.clj
+++ b/src/clj/cljs/analyzer.clj
@@ -368,6 +368,42 @@
{:env env :variadic variadic :params params :max-fixed-arity fixed-arity
:type type :form form :recurs @(:flag recur-frame) :expr expr}))
+;; from clojure jvm/clojure/lang/Compiler.java
+;; some of those shouldnt appear ever, better safe than sorry tho
+(def fn-name-replace-chars {\- "_",
+ \. "_DOT_",
+ \: "_COLON_",
+ \+ "_PLUS_",
+ \> "_GT_",
+ \< "_LT_",
+ \= "_EQ_",
+ \~ "_TILDE_",
+ \! "_BANG_",
+ \@ "_CIRCA_",
+ \# "_SHARP_",
+ \', "_SINGLEQUOTE_",
+ \" "_DOUBLEQUOTE_",
+ \% "_PERCENT_",
+ \^ "_CARET_",
+ \& "_AMPERSAND_",
+ \* "_STAR_",
+ \| "_BAR_",
+ \{ "_LBRACE_",
+ \} "_RBRACE_",
+ \[ "_LBRACK_",
+ \] "_RBRACK_",
+ \/ "_SLASH_",
+ \\ "_BSLASH_",
+ \? "_QMARK_"})
+
+(defn make-fn-name [env name]
+ (let [sb (StringBuilder.)]
+ (doseq [c (str "fn-" (get-in env [:ns :name]) "/" (or name (gensym "anon")) "-" (:line env))]
+ (.append sb (fn-name-replace-chars c c)))
+ (symbol (.toString sb))
+ ))
+
+
(defmethod parse 'fn*
[op env [_ & args :as form] name]
(let [[name meths] (if (symbol? (first args))
@@ -376,7 +412,8 @@
;;turn (fn [] ...) into (fn ([]...))
meths (if (vector? (first meths)) (list meths) meths)
locals (:locals env)
- locals (if name (assoc locals name {:name name :shadow (locals name)}) locals)
+ fn-name (make-fn-name env name)
+ locals (if name (assoc locals name {:name fn-name :fn-name fn-name :shadow (locals name)}) locals)
type (-> form meta ::type)
fields (-> form meta ::fields)
protocol-impl (-> form meta :protocol-impl)
@@ -404,13 +441,14 @@
:max-fixed-arity max-fixed-arity
:method-params (map :params methods))
locals)
+
methods (if name
;; a second pass with knowledge of our function-ness/arity
;; lets us optimize self calls
(no-warn (doall (map #(analyze-fn-method menv locals % type) meths)))
methods)]
;;todo - validate unique arities, at most one variadic, variadic takes max required args
- {:env env :op :fn :form form :name name :methods methods :variadic variadic
+ {:env env :op :fn :form form :name fn-name :methods methods :variadic variadic
:recur-frames *recur-frames* :loop-lets *loop-lets*
:jsdoc [(when variadic "@param {...*} var_args")]
:max-fixed-arity max-fixed-arity
--
1.7.6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment