camel-snake-kebab icon indicating copy to clipboard operation
camel-snake-kebab copied to clipboard

Syntax error compiling with figwheel

Open 2food opened this issue 5 years ago • 4 comments

When using camel-snake-kebab in clojurescript, running fighweel and tests at the same time i get this error:

Error refreshing environment: Syntax error compiling at (camel_snake_kebab/core.cljc:16:1).

The line specified is the first line where a conversion is defined with the defconversion macro from camel-snake-kebab.macros:

(defconversion "PascalCase"           clojure.string/capitalize clojure.string/capitalize "")

I don't know the exact reason for why this fails, but it has something to do with the conversion functions being defined with a macro. Redefining the conversion functions with defn and not requiring camel-snake-kebab-core solves the issue for me:

(ns my-conversions
  (:require [camel-snake-kebab.internals.misc :as csk-misc]
            [camel-snake-kebab.extras :as cks-extras]
            [camel-snake-kebab.internals.alter-name :refer [alter-name]]
            [clojure.string :as string]))


(defn convert-case
  [first-fn rest-fn sep s]
  (alter-name s (partial csk-misc/convert-case first-fn rest-fn sep)))

(defn ->PascalCase [x] (convert-case string/capitalize string/capitalize "" x))
(defn ->Camel_Snake_Case [x] (convert-case string/capitalize string/capitalize "_" x))
(defn ->camelCase [x] (convert-case string/lower-case string/capitalize "" x))
(defn ->SCREAMING_SNAKE_CASE [x] (convert-case string/upper-case string/upper-case "_" x))
(defn ->snake_case [x] (convert-case string/lower-case string/lower-case "_" x))
(defn ->kebab-case [x] (convert-case string/lower-case string/lower-case "-" x))
(defn ->HTTP-Header-Case [x] (convert-case csk-misc/capitalize-http-header csk-misc/capitalize-http-header "_" x))

All of these are type preserving, but I don't see the need for defining explicit type converting functions like ->kebab-case-keyword when you can just do (comp keyword ->kebab-case)?

As far as I can tell this works the same as when using defconversion, I might be missing something here though so please correct me if I'm wrong.

2food avatar Mar 15 '19 09:03 2food

+1

Luke1298 avatar Dec 13 '19 05:12 Luke1298

I'm running into the same problem with tools.namespace/refresh. If I remove this lib, refresh works correctly.

Versions:

[org.clojure/clojurescript "1.10.773"]
[camel-snake-kebab "0.4.2"]

Error:

:error-while-loading camel-snake-kebab.core
#error {
 :cause "camel-snake-kebab.internals.alter-name"
 :via
 [{:type clojure.lang.Compiler$CompilerException
   :message "Syntax error compiling at (camel_snake_kebab/core.cljc:49:1)."
   :data #:clojure.error{:phase :compile-syntax-check, :line 49, :column 1, :source "camel_snake_kebab/core.cljc"}
   :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 7115]}
  {:type java.lang.ClassNotFoundException
   :message "camel-snake-kebab.internals.alter-name"
   :at [java.net.URLClassLoader findClass "URLClassLoader.java" 435]}]
 ...

marianboda avatar Jul 07 '21 12:07 marianboda

I am also facing this exact issue. Was there a workaround found?

fr33m0nk avatar May 06 '22 16:05 fr33m0nk

I have found a solution to the problem.

The problem was caused by figwheel-main's need to have the output directory e.g. target/dev on classpath. Figwheel-main after building cljs files also puts camel-case-kebab.core in the output directory. By default, tools.namespace/refresh looks first at var #'clojure.tools.namespace.repl/refresh-dirs which is empty and then tries to reloads the classpath which has Figwheel-main's output directory e.g. target/dev. JVM think camel-snake-kebab.core is incorrectly placed in Figwheel-main's output directory e.g.target/dev which causes below error:

:error-while-loading camel-snake-kebab.core
#error {
 :cause "camel-snake-kebab.internals.alter-name"
 :via
 [{:type clojure.lang.Compiler$CompilerException
   :message "Syntax error compiling at (camel_snake_kebab/core.cljc:49:1)."
   :data #:clojure.error{:phase :compile-syntax-check, :line 49, :column 1, :source "camel_snake_kebab/core.cljc"}
   :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 7115]}
  {:type java.lang.ClassNotFoundException
   :message "camel-snake-kebab.internals.alter-name"
   :at [java.net.URLClassLoader findClass "URLClassLoader.java" 435]}]
 ...

Fix for this is to alter var #'clojure.tools.namespace.repl/refresh-dirs and set its value to a collection that has everything from classpath except Figwheel-main's output directory.

Below is the function I am using now. I have tested this and it works great.

(ns user
    (:require
      [clojure.java.classpath :as cp]
      [clojure.string :as str])
    (:use
      [dev]
      [dev-extras :exclude [go]])
    (:import (java.io File)))

(defn go
  ([] 
   (go "target/dev"))
  ([figwheel-output-directory]
   (let [directories-to-reload (into []
                                     (filter #(not (str/includes? (.getPath ^File %) figwheel-output-directory)))
                                     (cp/classpath))]
     (alter-var-root #'clojure.tools.namespace.repl/refresh-dirs (constantly directories-to-reload))
     (dev-extras/go))))

Now, after calling (go), I can call (reset) without any problem. There's also an open issue somewhat related to this.

fr33m0nk avatar May 06 '22 18:05 fr33m0nk