<< Back to previous view

[CLJS-2720] Cannot import node_modules into ES6 classpath lib Created: 31/Mar/18  Updated: 31/Mar/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Critical
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 2
Labels: None


 Description   

For ClojureScript we have special parsing of :require to determine top-level Node dependencies, however this is not done for classpath lib files.

If both ClojureScript and ES6 classpath libs try to require a node_module we get the following exception:

Exception in thread "main" java.lang.IllegalArgumentException: Duplicate module path after resolving: /Users/davidnolen/development/clojure/hello-es6/node_modules/react/react.js
	at com.google.javascript.jscomp.deps.ModuleLoader.resolvePaths(ModuleLoader.java:294)
	at com.google.javascript.jscomp.deps.ModuleLoader.<init>(ModuleLoader.java:96)
	at com.google.javascript.jscomp.Compiler.parseInputs(Compiler.java:1760)
	at com.google.javascript.jscomp.Compiler.parse(Compiler.java:994)





[CLJS-2719] Should not compile ES6 or CommonJS libs when under :nodejs target Created: 31/Mar/18  Updated: 31/Mar/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Critical
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: None


 Description   

If we compile, we generate files which cannot be loaded. Instead we should avoid compiling as Node.js can load these kinds of source files anyway.






[CLJS-2793] Instrumenting breaks function with varargs Created: 26/Jun/18  Updated: 22/Jul/18

Status: In Progress
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Critical
Reporter: Yuri Govorushchenko Assignee: Unassigned
Resolution: Unresolved Votes: 2
Labels: None
Environment:

CLJS 1.10.238 (also reproducible in Lumo 1.9.0-alpha), 1.10.340


Attachments: Text File experiment.patch    

 Description   

Steps:

(require '[cljs.spec.alpha :as s]
         '[cljs.spec.test.alpha :as stest])
(defn foo [m & args] (prn :m m :args args))
(s/fdef foo)
(stest/instrument)
(foo {:x 1 :y 2})

Actual:

:m [:x 1] :args ([:y 2])

Expected:

:m {:x 1, :y 2} :args nil

Couldn't reproduce in Clojure 1.9.0 and CLJS 1.9.946.



 Comments   
Comment by Mike Fikes [ 14/Jul/18 4:37 PM ]

This one is fairly vexing, involving the same bit of code dealt with in CLJS-2397.

The attached experiment.patch, while somewhat hackish, appears to solve the issue, but only does so in the REPL; it fails in advanced with the added unit tests.





[CLJS-1479] Race condition in browser REPL Created: 03/Nov/15  Updated: 12/Feb/16

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.7.145
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Daniel Skarda Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None

Attachments: File heavy-load.sh     File race-condition.clj     File race-condition.jstack    

 Description   

Evaluation in browser REPL occasionally hangs. It seems that repl environment and browser sometimes miss each other and their "randezvous" fails. Browser is waiting for POST reply and repl is trying to send a command, but they do not meet each other.

I found the issue when we switched our tests from nodejs to browser environment. Luckily I was able to find very small example which hangs during execution. It seems that (simulated) heavy load increases the chance of "hanging".

Minimal setup:

(ns race.condition
  (:require [cljs.repl.browser :as browser]
            [cljs.repl :as repl]
            [cljs.env :as env]
            [cljs.build.api :as api]))


(api/build '[(ns race.repl
               (:require [clojure.browser.repl]))
             (clojure.browser.repl/connect "http://localhost:9000/repl")]
           {:output-to  "target/cljs-race/main.js"
            :output-dir "target/cljs-race"
            :main       'race.repl})

(spit "target/cljs-race/index.html"
      (str "<html>" "<body>"
           "<script type=\"text/javascript\" src=\"main.js\">"
           "</script>" "</body>" "</html>"))

Now start the environment:

(def env (browser/repl-env :static-dir ["target/cljs-race" "."] :port 9000 :src nil))

(env/with-compiler-env (env/default-compiler-env)
  (repl/-setup env {}))

cross your fingers and start this endless loop:

(loop [i 0]
  (println (java.util.Date.) i)
  (dotimes [j 100]
    (let [result (repl/-evaluate env "<exec>" "1"  "true")]
      (when-not (= :success (:status result))
        (println i j result))))
  (recur (inc i)))

To simulate heavy load run heavy-load.sh from attachment.

After some iterations (eg 55 big loop i) execution stops. If you investigate stacks (see race-condition.jstack), you can see in one thread:

at clojure.core$promise$reify__6779.deref(core.clj:6816)
	at clojure.core$deref.invoke(core.clj:2206)
	at cljs.repl.browser$send_for_eval.invoke(browser.clj:65)
	at cljs.repl.browser$browser_eval.invoke(browser.clj:193)
	at cljs.repl.browser.BrowserEnv._evaluate(browser.clj:262)

The code is waiting for a promise with a connection (which already did arive).

My guess is suspicious code in cljs.repl.server functions connection and set-connection. Both functions access an atom in non-standard way. They deref a valua and make a swap! in two steps.

Can somebody with better understanding of REPL internals investigate? Thank you.



 Comments   
Comment by David Nolen [ 12/Feb/16 2:57 PM ]

A patch is welcome for this one.





[CLJS-1691] spec internal compiler APIs Created: 21/Jun/16  Updated: 21/Jun/16

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.9.76
Fix Version/s: None

Type: Task Priority: Major
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None





[CLJS-525] Allow hashtable lookup used for numbers and strings to be extended to other built-in types Created: 17/Jun/13  Updated: 17/Jun/13

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Major
Reporter: Chas Emerick Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

...which would enable safe extension of key cljs protocols to types without modifying their prototypes, e.g. CLJS-523.



 Comments   
Comment by David Nolen [ 17/Jun/13 2:56 PM ]

Date is the only JS native case that I'm aware of that we don't handle. One tricky bit is that goog.typeOf won't give us the information we need, but I think instanceof should cover us here?

Comment by Fogus [ 17/Jun/13 3:05 PM ]

instanceof or the ever-gruesome toString.call(aDate) == '[object Date]' will work.





[CLJS-1833] Consider moving int behavior to unchecked-int + clearer docstrings for limitations of other coercions (long etc) Created: 23/Oct/16  Updated: 23/Oct/16

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Task Priority: Major
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None





[CLJS-1900] Source maps for processed JavaScript modules Created: 24/Jan/17  Updated: 24/Jan/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.9.655
Fix Version/s: None

Type: Defect Priority: Major
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Currently we don't emit source maps for JS modules converted into Google Closure namespaces.






[CLJS-1447] IFn implementors have a broken call implementation, all args after 20th argument should be collected into a seq Created: 11/Sep/15  Updated: 27/Jun/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.7.145
Fix Version/s: 1.9.671

Type: Task Priority: Major
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Regular fns (which are just JavaScript fns) have no such limit. For IFn implementors we should not allow arities above 21 args, and we should transform the 21st arity into a var args signature.



 Comments   
Comment by François De Serres [ 18/Jun/16 9:13 AM ]

we should transform the 21st arity into a var args signature

Unless misunderstanding, can't do that. Var args sigs aren't allowed in protocols.

we should not allow arities above 21 args

Emitting an analyzer warning is what you want?

Comment by Antonin Hildebrand [ 05/Jul/16 6:07 PM ]

I believe I hit this problem in my code using core.async[1].

If it is not possible to implement ATM, I would kindly ask for a compiler warning at least. This thing manifested as a infinite recursive loop ending up in a cryptic stack overflow.

[1] https://github.com/binaryage/dirac/commit/cce56470975a287c0164e6f79cd525d6ed27a543





[CLJS-1446] autodoc + gh-pages for cljs.*.api namespaces Created: 11/Sep/15  Updated: 27/Jun/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.7.145
Fix Version/s: 1.9.671

Type: Task Priority: Major
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: newbie


 Comments   
Comment by W. David Jarvis [ 11/Sep/15 6:07 PM ]

I just tried to get this working - unfortunately, autodoc doesn't currently have support for ClojureScript. An issue is currently open on the GH project here but it doesn't look like it's seen any movement in nearly two years.

Comment by Tom Faulhaber [ 13/Sep/15 2:26 PM ]

I would love to see this work as well and, as the author of autodoc, am happy to help move it forward. I've added some commentary to the issue in autodoc about how to do this. If it's going to happen soon, though, I will need some help from the ClojureScript community as outlined over there.

Comment by David Nolen [ 14/Sep/15 10:42 AM ]

This ticket is about generating docs for Clojure code. Getting autodoc to work for ClojureScript files is worth pursuing but unrelated to this ticket.

Comment by Sebastian Bensusan [ 11/Oct/15 5:54 PM ]

I took at stab at this and only got it running using autodoc-0.9.0-standalone.jar from the command line. My results are not useful at all but those issues should be sorted out in autodoc.

David, do you have a preference in how the docs and artifacts needed should be managed? Should it be a lein plugin or can it be a script that assumes that the correct jars have been installed?

Comment by Tom Faulhaber [ 12/Oct/15 12:37 AM ]

Oh, I did misunderstand this and then didn't see David Nolen's follow-up until now. Let me take a look at whether I can make this happen pretty easily. I wouldn't think it would be too difficult. (Famous last words!)

Comment by Tom Faulhaber [ 02/Jul/16 2:14 AM ]

I have just closed the blocking issue in autodoc Issue 21, andSebastian Bensusan has successfully built a version of doc for the src/main/clojure/... stuff.

The next step is to flesh out what we want to push to http://clojure.github.io/clojurescript. I don't think that this is too hard. Then we can integrate it with the autodoc robot and get automatic updates.





[CLJS-1402] Source Mapping Closure Error Logger Created: 08/Aug/15  Updated: 27/Jun/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.7.145
Fix Version/s: 1.9.671

Type: Enhancement Priority: Major
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: type-check


 Description   

Current error reports generated by Google Closure point back to the generated JavaScript sources. For JavaScript source that originated from ClojureScript we should generated source mapped reports.



 Comments   
Comment by Antonin Hildebrand [ 24/Jan/17 8:06 PM ]

I believe this will be fixed by CLJS-1901 either using `--source_map_input` or inlining source-maps into generated js files (CLJS-1902).





[CLJS-1373] Generalize CLJS-1324, check invokes of all IFn implementors Created: 28/Jul/15  Updated: 27/Jun/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.7.145
Fix Version/s: 1.9.671

Type: Enhancement Priority: Major
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

We currently track all IFn implementors but in order to do arity checking of statically analyzeable invokes of keywords, vector, etc. we need to do a bit more. extend-type should update the type in the compiler state with :method-params :max-fixed-arity and :variadic. Then we can just reuse the existing checks in cljs.analyzer/parse-invoke.






[CLJS-712] resolve-var for symbol with dot still wrong Created: 03/Dec/13  Updated: 27/Jun/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.7.145
Fix Version/s: 1.9.671

Type: Defect Priority: Major
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

We need to recur on the first segment passing an new additional argument to resolve-var indicating that we should not try to resolve in the current namespace and instead warn.






[CLJS-2165] port `clojure.string/sre-quote-replacement` to ClojureScript, prevent use the conditional reader in cljc file Created: 04/Jul/17  Updated: 04/Jul/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Feature Priority: Major
Reporter: Isaac Zeng Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

ClojureScript


Attachments: Text File 0001-port-re-quote-replacement-to-clojure.string.patch    

 Description   

Clojure has `clojure.string/sre-quote-replacement`, but not in ClojureScript.

for this now, we need use the conditional reader in cljc file
```
(defn foo [s]
#?(:clj (str/re-quote-replacement s)
:cljs (gstr/regExpEscape s)))
```






[CLJS-365] apply needs to put all args after the 20th into an array seq Created: 29/Aug/12  Updated: 05/Jul/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

This ticket is related to CLJS-359






[CLJS-2292] Var being replaced warnings with :refer-clojure :rename Created: 01/Aug/17  Updated: 01/Aug/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.9.854
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: None


 Description   

If you rename a core Var, you will get a warning if you redefine it. It is as if the :rename doesn't imply :exclude.

Repro with QuickStart JAR:

$ java -jar cljs.jar -m cljs.repl.node
ClojureScript Node.js REPL server listening on 52319
To quit, type: :cljs/quit
cljs.user=> (ns foo.core (:refer-clojure :rename {map clj-map}))
nil
foo.core=> (map inc [1 2])
(2 3)
foo.core=> (def map {:a :b})
WARNING: map already refers to: cljs.core/map being replaced by: foo.core/map at line 1 <cljs repl>
#'foo.core/map
foo.core=> map
{:a :b}
foo.core=> (clj-map inc [1 2])
(2 3)

Compare to Clojure:

user=> (ns foo.core (:refer-clojure :rename {map clj-map}))
nil
foo.core=> (map inc [1 2])

CompilerException java.lang.RuntimeException: Unable to resolve symbol: map in this context, compiling:(/private/var/folders/gx/nymj3l7x4zq3gxb97v2zwzb40000gn/T/form-init8370940485091648461.clj:1:1)
foo.core=> (def map {:a :b})
#'foo.core/map
foo.core=> map
{:a :b}
foo.core=> (clj-map inc [1 2])
(2 3)

Note that you cannot workaround this by simply adding an explicit :exclude for map above. While this works with the current ClojureScript compiler, it breaks in Clojure, making the alias symbol clj-map unresolvable.






[CLJS-2149] aget produces different results from Clojure for non-integer and out-of-bounds indexes Created: 02/Jul/17  Updated: 18/Nov/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.9.671
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Like CLJS-2113, but for aget:

Clojure:

user=> (aget (to-array [nil 1]) -1)
ArrayIndexOutOfBoundsException -1  clojure.lang.RT.aget (RT.java:2336)
user=> (aget (to-array [nil 1]) 0)
nil
user=> (aget (to-array [nil 1]) 0.5)
nil
user=> (aget (to-array [nil 1]) 1)
1
user=> (aget (to-array [nil 1]) 1.5)
1
user=> (aget (to-array [nil 1]) 2)
ArrayIndexOutOfBoundsException 2  clojure.lang.RT.aget (RT.java:2336)

ClojureScript

cljs.user=> (aget (to-array [nil 1]) -1)
nil
cljs.user=> (aget (to-array [nil 1]) 0)
nil
cljs.user=> (aget (to-array [nil 1]) 0.5)
nil
cljs.user=> (aget (to-array [nil 1]) 1)
1
cljs.user=> (aget (to-array [nil 1]) 1.5)
nil
cljs.user=> (aget (to-array [nil 1]) 2)
nil

Also note that Clojure acts as if rounding indices down to the nearest integer while ClojureScript does not:

(aget (to-array [1 2]) 0.5)

yields 1 in Clojure and nil in ClojureScript.

(Presumably, similar results hold for aset.)



 Comments   
Comment by Mike Fikes [ 18/Nov/17 10:02 AM ]

The fact that Clojure's aget happens to work on non-integer indices may not be intentional. An int cast may be present only to ease interop with the default use of long integral values in Clojure, and while this cast causes the observed behavior (rounding down of passed double s), this may not reflect the intended API.

Here is a commit that speaks to "hints": https://github.com/clojure/clojure/commit/742619e583400400e69cd46ab9e9536c10afb738





[CLJS-1846] Range issues Created: 10/Nov/16  Updated: 19/Nov/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Thomas Mulvaney Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: core

Attachments: Text File CLJS-1846.2.patch     Text File CLJS-1846.patch    
Patch: Code and Test

 Description   

Problem
There are a number of bugs with Range which occur when the step size is 0 or where negative.

Examples

cljs.user=> (count (range 10 0 0))
-Infinity  ;Expect Infinity

cljs.user=> (nth (range 10 0 -1) -1)
11 ; Expected IndexOutOfBounds

cljs.user=> (take 5 (sequence identity (range 0 10 0)))
() ; Expected (0 0 0 0 0)

cljs.user=> (into [] (take 5) (range 0 10 0))
[] ; Expected [0 0 0 0 0]


 Comments   
Comment by David Nolen [ 10/Nov/16 4:37 PM ]

This patch is headed in the right direction but it needs to be more vigilant about performance. I'm more than happy to talk it over via IRC or Slack. Thanks!

Comment by Thomas Mulvaney [ 15/Nov/16 8:24 AM ]

Updated patch with performance tweaks.

  • Added the ^boolean annotation to the `some-range?` helper.
  • Removed calls to methods of Range where possible.
  • Improved 2-arity reduces performance over master significantly by replacing the call to ci-reduce.
Comment by Mike Fikes [ 19/Nov/17 7:39 PM ]

Patch no longer applies; needs re-baseline.





[CLJS-2421] Referred type can be replaced by same-named type in referring namespace Created: 27/Nov/17  Updated: 27/Nov/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Chas Emerick Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Two namespaces:

(ns my.ns)

(defrecord A [foo bar])

(defn make-a [foo bar]
  (A. foo bar))
(ns other.ns
  (:require [my.ns :refer (A)]))

(println (my.ns/A. 1 2) (my.ns/make-a 1 2))

(defrecord A [baz quux])

(println (my.ns/A. 1 2) (my.ns/make-a 1 2))

Loading other.ns yields output:

#my.ns.A{:foo 1, :bar 2} #my.ns.A{:foo 1, :bar 2}
#my.ns.A{:baz 1, :quux 2} #my.ns.A{:baz 1, :quux 2}

The definition of other.ns.A is replacing that of my.ns.A.



 Comments   
Comment by Chas Emerick [ 27/Nov/17 12:39 PM ]

This may be a duplicate of CLJS-1558...?

Comment by Mike Fikes [ 27/Nov/17 12:40 PM ]

This ticket shares similarities with CLJS-1558 in that the compiler is essentially allowing you to re-def a referred Var. Perhaps for both tickets this should cause a compiler error as occurs with Clojure.

Comment by Mike Fikes [ 27/Nov/17 2:42 PM ]

I struggle a little with this one in terms of defining what should be going on, and at the core of my lack of clarity is on whether my.ns/A is a Var or simply a type.

In the compiler state, it does show up under :defs, but it is flagged with :type true. (In other words, perhaps just because it is under :def doesn't imply it is a Var.) In Clojure, even though an underlying constructor exists that can be accessed via interop, no actual Var is created. (Evidence backing this assertion is that (var A) fails in Clojure, and no Var appears if you use dir at the REPL—you only see the associated synthetically-generated positional and map factory Vars.

Another argument that "it is not a Var" is what defrecord returns. defrecord doesn't return a Var (even in Clojure), but instead returns a symbol (which evaluates to itself, much like the symbol java.lang.String).

If you go with the argument that the underlying constructor is not a Var, then perhaps some things could be cleaned up (fixing dir in ClojureScript, and perhaps causing var to balk if applied to types).

Also, if you go with the argument that it is not a Var, then perhaps you'd argue that import is appropriate, while require is not. Inspired by http://puredanger.github.io/tech.puredanger.com/2010/06/30/using-records-from-a-different-namespace-in-clojure/, this variation seems to work fine:

(ns my.ns)

(defrecord A [foo bar])
(ns other.ns
  (:require [my.ns])
  (:import (my.ns.A)))

(println (my.ns.A. 1 2) (my.ns/->A 1 2))

(defrecord A [baz quux])

(println (my.ns.A. 1 2) (my.ns/->A 1 2))

(println (A. 3 4) (->A 3 4))

with this result:

cljs.user=> (require 'other.ns)
#my.ns.A{:foo 1, :bar 2} #my.ns.A{:foo 1, :bar 2}
#my.ns.A{:foo 1, :bar 2} #my.ns.A{:foo 1, :bar 2}
#other.ns.A{:baz 3, :quux 4} #other.ns.A{:baz 3, :quux 4}
nil

One thing I don't like is that you have to write (:import (my.ns.A)) as opposed to {{(:import (my.ns A))}, but perhaps that is a minor quirk that could be cleaned up if the "not a Var" approach were taken.





[CLJS-1141] memoization of js-dependency-index and get-upstream-deps needs knobs Created: 18/Mar/15  Updated: 19/Nov/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.7.145
Fix Version/s: 1.9.671

Type: Enhancement Priority: Major
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: None

Attachments: Text File CLJS_1141.patch     Text File CLJS-1141-with-js-dep-caching-latest.patch    
Patch: Code

 Description   

knobs should be exposed for more dynamic compilation environments like Figwheel which may desire to add dependencies to the classpath on the fly.



 Comments   
Comment by Bruce Hauman [ 21/Mar/15 3:51 PM ]

A patch that caches upstream dependencies in the compiler env.

Comment by Bruce Hauman [ 21/Mar/15 3:59 PM ]

Actually I'm going to submit another patch that includes the memoize calls in js-deps.

Comment by Bruce Hauman [ 28/Mar/15 12:50 PM ]

New patch that moves cljs.js-deps memoization to current env/compiler as well as get-upstream-deps.

Unfortunately there is a circular dep between cljs.env and cljs.js-deps, if we want to cache in env/compiler. I overcame this with a resolve.

Compile performance is either completely unchanged or slightly improved based on several test runs.

Comment by Bruce Hauman [ 28/Mar/15 2:22 PM ]

Hold off on this. Its not behaving as expected. Doesn't seem to be caching in certain situations.

Comment by David Nolen [ 28/Mar/15 2:26 PM ]

Thanks for the update. This will definitely not land until after the pending REPL/piggieback release anyhow.

Comment by Bruce Hauman [ 28/Mar/15 2:44 PM ]

Yeah there is an obvious bug and a subtle one. Hopefully will finish it up soonish.

Comment by Bruce Hauman [ 28/Mar/15 3:43 PM ]

Alright, this latest patch works. There was a subtle memoizing nil value bug.

Comment by Mike Fikes [ 19/Nov/17 8:04 PM ]

Patch no longer applies.





[CLJS-871] .-default property access returns nil Created: 11/Oct/14  Updated: 01/Aug/17

Status: Reopened
Project: ClojureScript
Component/s: None
Affects Version/s: 1.7.145
Fix Version/s: 1.9.671

Type: Defect Priority: Major
Reporter: Joel Holdbrooks Assignee: Unassigned
Resolution: Unresolved Votes: 3
Labels: None

Attachments: Text File 871.patch     Text File 871.patch    
Patch: Code and Test

 Description   

Types defined with deftype/defrecord which have a default field will incorrectly return nil with property access. The following example will return nil.

(deftype Foo [default])

(let [foo (Foo. "bar")]
  (.-default foo))


 Comments   
Comment by Joel Holdbrooks [ 13/Oct/14 4:19 PM ]

Patch attached. I should point out that I had to borrow js-reserved from the compiler namespace and the warning message provided hard codes the munged symbol information instead of reusing the compiler's munge fn.

Comment by Joel Holdbrooks [ 13/Oct/14 9:41 PM ]

For the sake of history, I should provide more context to this patch (I'm unable to edit the issue title for some reason). It isn't just .-default it is any field name that is also a JavaScript identifier (eg. public, private, if).

Comment by David Nolen [ 14/Oct/14 5:26 AM ]

Please lift js-reserved and any helpers like munge into the shared namespace cljs.util so that logic an be shared and hard coding avoided. Thanks.

Comment by Joel Holdbrooks [ 14/Oct/14 5:03 PM ]

Are you sure, David? That might make this patch a bit more noisy. If it's not a problem I'm happy to do it.

Comment by David Nolen [ 14/Oct/14 6:06 PM ]

I'm sure, I'd like to avoid this kind of code duping. Cleaner in the end and better moving forward.

Comment by Joel Holdbrooks [ 18/Mar/15 11:43 AM ]

Updated to use new refactorings

Comment by David Nolen [ 18/Mar/15 11:46 AM ]

The warning is not desirable. Instead we should just munge and ensure property access always works.

Comment by David Nolen [ 01/Aug/17 5:42 PM ]

Now that we have CLJS-1620, a warning seems like a good answer.





[CLJS-1328] Support defrecord reader tags Created: 04/Jul/15  Updated: 04/Dec/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.7.145
Fix Version/s: 1.9.671

Type: Enhancement Priority: Major
Reporter: Herwig Hochleitner Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: reader, readertags


 Description   

Currently, defrecord instances print similar to how they do in clojure

> (pr-str (garden.units/px 5))
#garden.types.CSSUnit{:unit :px, :magnitude 5}

This representation cannot be read by the compiler, nor at runtime by cljs.reader/read-string

> #garden.types.CSSUnit{:unit :px, :magnitude 5}
clojure.lang.ExceptionInfo: garden.types.CSSUnit {:type :reader-exception, :line 1, :column 22, :file "NO_SOURCE_FILE"}
...
> (cljs.reader/read-string "#garden.types.CSSUnit{:unit :px, :magnitude 5}")
#<Error: Could not find tag parser for garden.types.CSSUnit in ("inst" "uuid" "queue" "js")>
...

Analysis

The two requirements - using record literals in cljs source code and supporting runtime reading - can be addressed by using the analyzer to find defrecords and registering them with the two respective reader libraries.

Record literals

Since clojurescript reads and compiles a file at a time, clojure's behavior for literals is hard to exactly mimic. That is, to be able to use the literal in the same file where the record is defined.
A reasonable compromise might be to update the record tag table after each file has been analyzed. Thus the literal form of a record could be used only in requiring files.

EDIT: Record literals can also go into the constant pool

cljs.reader

To play well with minification, the ^:export annotation could be reused on defrecords, to publish the corresponding reader tag to cljs.reader.

Related Tickets



 Comments   
Comment by David Nolen [ 08/Jul/15 12:00 PM ]

It's preferred that we avoid exporting. Instead we can adopt the same approach as the constant literal optimization for keywords under advanced optimizations. We can make a lookup table (which won't pollute the global namespace like exporting does) which maps a string to its type.

I'm all for this enhancement.

Comment by Levi R. I. Tan Ong [ 04/Dec/17 11:23 PM ]

Trying my hand at this, but I'm stuck at an architecture conundrum.

Should the analyzer be able to add a tag reader to the tag table, or should the reader take a look at a the record-table to build tag readers on the fly?

The former seems easier to do with a macro, but it feels wrong to write reader code in the analyzer namespace.
The latter is more tedious because all the reader functions deref the tag reader table, so I'd have to go through all of them, but it feels less like a war crime than the former.

Or is there another option I'm not seeing?





[CLJS-2435] Don't warn if arithmetic operations done on ^int Created: 05/Dec/17  Updated: 05/Dec/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.9.908
Fix Version/s: None

Type: Enhancement Priority: Major
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: errormsgs


 Description   

If CLJC is being used and the ClojureScript compiler sees Clojure type annotations, it should effecively ignore those where there isn't a portability concern.

The specific case for this ticket is ^int and arithmetic, and a motivating example is:

cljs.user=> (let [^int v (alength (into-array []))] (+ v 3))
WARNING: cljs.core/+, all arguments must be numbers, got [int number] instead. at line 1 <cljs repl>
3

On the other hand, ^long should still cause warnings to be emitted given that it is not a "subtype" of ^number (such code might overflow, so warnings are helpful in that case).






[CLJS-2490] Nashorn repl cljs.repl.nashorn/eval-str should set the out and err writers to the currently bound *out* and *in* writers. Created: 31/Jan/18  Updated: 31/Jan/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Bruce Hauman Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Currently the instantiation of the Nashorn REPL captures the out and err writers at the time of creation.

Perhaps it would be better to set the engines writers to the "currently bound" values of out and err before each eval.

This would allow capturing eval output.






[CLJS-2542] s/conform internal JS compile failure Nashorn Java 9 Created: 22/Feb/18  Updated: 22/Feb/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

macOS 10.13.3

java version "9.0.4"
Java(TM) SE Runtime Environment (build 9.0.4+11)
Java HotSpot(TM) 64-Bit Server VM (build 9.0.4+11, mixed mode)



 Description   

(This is reflected in cljs.spec-test/test-roundtrip failing in Nashorn under Java 9.)

Node, when running these tests, in addition to cleaning up .cljs_nashorn_repl/ it is important to clean up nashorn_code_cache/ in order to ensure reproducibility.

Java 8:

$ script/nashornrepljs
To quit, type: :cljs/quit
cljs.user=> (require '[cljs.spec.alpha :as s])

cljs.user=> (s/def ::even? (s/and number? even?))
:cljs.user/even?
cljs.user=> (s/def ::odd? (s/and number? odd?))
:cljs.user/odd?
cljs.user=> (def s2
  (s/cat :forty-two #{42}
    :odds (s/+ ::odd?)
    :m (s/keys :req-un [::a ::b ::c])
    :oes (s/& (s/* (s/cat :o ::odd? :e ::even?)) #(< (count %) 3))
    :ex (s/* (s/alt :odd ::odd? :even ::even?))))
#'cljs.user/s2
cljs.user=> (s/conform s2 [42 11 13 15 {:a 1 :b 2 :c 3} 1 2 3 42 43 44 11])
{:forty-two 42, :odds [11 13 15], :m {:a 1, :b 2, :c 3}, :oes [{:o 1, :e 2} {:o 3, :e 42}], :ex [[:odd 43] [:even 44] [:odd 11]]}

Under Java 9, the first s/conform fails, but the second succeeds.

$ script/nashornrepljs
To quit, type: :cljs/quit
cljs.user=> (require '[cljs.spec.alpha :as s])

cljs.user=> (s/def ::even? (s/and number? even?))
:cljs.user/even?
cljs.user=> (s/def ::odd? (s/and number? odd?))
:cljs.user/odd?
cljs.user=> (def s2
  (s/cat :forty-two #{42}
    :odds (s/+ ::odd?)
    :m (s/keys :req-un [::a ::b ::c])
    :oes (s/& (s/* (s/cat :o ::odd? :e ::even?)) #(< (count %) 3))
    :ex (s/* (s/alt :odd ::odd? :even ::even?))))
#'cljs.user/s2
cljs.user=> (s/conform s2 [42 11 13 15 {:a 1 :b 2 :c 3} 1 2 3 42 43 44 11])
Argument is not an array
	 cljs$spec$alpha$deriv (.cljs_nashorn_repl/cljs/spec/alpha.cljs:0:0)
	 cljs$spec$alpha$re_conform (.cljs_nashorn_repl/cljs/spec/alpha.cljs:1211:5)
	 cljs$spec$alpha$Spec$conform_STAR_$arity$2 (.cljs_nashorn_repl/cljs/spec/alpha.cljs:1252:9)
	 cljs$spec$alpha$conform_STAR_ (.cljs_nashorn_repl/cljs/spec/alpha.cljs:39:1)
	 cljs$spec$alpha$conform (.cljs_nashorn_repl/cljs/spec/alpha.cljs:153:3)
	 (NO_SOURCE_FILE <eval>:1:0)
	 (NO_SOURCE_FILE <eval>:1:0)
	 (NO_SOURCE_FILE <eval>:1:0)
cljs.user=> (s/conform s2 [42 11 13 15 {:a 1 :b 2 :c 3} 1 2 3 42 43 44 11])
{:forty-two 42, :odds [11 13 15], :m {:a 1, :b 2, :c 3}, :oes [{:o 1, :e 2} {:o 3, :e 42}], :ex [[:odd 43] [:even 44] [:odd 11]]}

Printing *e which is actually a Java exception seems to indicate that it is an internal error:

cljs.user=> (.printStackTrace *e)
java.lang.IllegalArgumentException: Argument is not an array
	at java.base/java.lang.reflect.Array.getLength(Native Method)
	at jdk.scripting.nashorn/jdk.nashorn.internal.runtime.RewriteException.toObjectArray(RewriteException.java:247)
	at jdk.scripting.nashorn.scripts/jdk.nashorn.internal.scripts.Script$Recompilation$2983$194058AA$alpha$cu1$restOf.cljs$spec$alpha$deriv(.cljs_nashorn_repl/goog/../cljs/spec/alpha.js:0)
	at jdk.scripting.nashorn.scripts/jdk.nashorn.internal.scripts.Script$Recompilation$2952$217830AA$alpha$cu1$restOf.cljs$spec$alpha$re_conform(.cljs_nashorn_repl/goog/../cljs/spec/alpha.js:4600)
	at jdk.scripting.nashorn.scripts/jdk.nashorn.internal.scripts.Script$Recompilation$2760$223940AA$alpha$cu1$restOf.cljs$spec$alpha$regex_spec_impl#cljs$spec$alpha$Spec$conform_STAR_$arity$2(.cljs_nashorn_repl/goog/../cljs/spec/alpha.js:4729)
	at jdk.scripting.nashorn.scripts/jdk.nashorn.internal.scripts.Script$Recompilation$2756$1102AA$alpha$cu1$restOf.cljs$spec$alpha$conform_STAR_(.cljs_nashorn_repl/goog/../cljs/spec/alpha.js:36)
	at jdk.scripting.nashorn.scripts/jdk.nashorn.internal.scripts.Script$Recompilation$2754$15797AA$alpha$cu1$restOf.cljs$spec$alpha$conform(.cljs_nashorn_repl/goog/../cljs/spec/alpha.js:455)
	at jdk.scripting.nashorn.scripts/jdk.nashorn.internal.scripts.Script$Recompilation$2724$42$\^eval\_$cu1$restOf.L:1#L:1(<eval>:1)
	at jdk.scripting.nashorn.scripts/jdk.nashorn.internal.scripts.Script$Recompilation$2723$1$\^eval\_.L:1(<eval>:1)
	at jdk.scripting.nashorn.scripts/jdk.nashorn.internal.scripts.Script$Recompilation$2722$\^eval\_.:program(<eval>:1)
	at jdk.scripting.nashorn/jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:652)
	at jdk.scripting.nashorn/jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:513)
	at jdk.scripting.nashorn/jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:517)
	at jdk.scripting.nashorn/jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:448)
	at jdk.scripting.nashorn/jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:405)
	at jdk.scripting.nashorn/jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:401)
	at jdk.scripting.nashorn/jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:154)
	at java.scripting/javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264)
	at cljs.repl.nashorn$eval_str.invokeStatic(nashorn.clj:46)
	at cljs.repl.nashorn$eval_str.invoke(nashorn.clj:45)
	at cljs.repl.nashorn.NashornEnv._evaluate(nashorn.clj:134)
	at cljs.repl$evaluate_form.invokeStatic(repl.cljc:538)
	at cljs.repl$evaluate_form.invoke(repl.cljc:472)
	at cljs.repl$eval_cljs.invokeStatic(repl.cljc:645)
	at cljs.repl$eval_cljs.invoke(repl.cljc:638)
	at cljs.repl$repl_STAR_$read_eval_print__8396.invoke(repl.cljc:918)
	at cljs.repl$repl_STAR_$fn__8404$fn__8413.invoke(repl.cljc:965)
	at cljs.repl$repl_STAR_$fn__8404.invoke(repl.cljc:964)
	at cljs.compiler$with_core_cljs.invokeStatic(compiler.cljc:1285)
	at cljs.compiler$with_core_cljs.invoke(compiler.cljc:1274)
	at cljs.repl$repl_STAR_.invokeStatic(repl.cljc:927)
	at cljs.repl$repl_STAR_.invoke(repl.cljc:798)
	at cljs.repl$repl.invokeStatic(repl.cljc:1046)
	at cljs.repl$repl.doInvoke(repl.cljc:976)
	at clojure.lang.RestFn.invoke(RestFn.java:410)
	at user$eval9072.invokeStatic(NO_SOURCE_FILE:3)
	at user$eval9072.invoke(NO_SOURCE_FILE:3)
	at clojure.lang.Compiler.eval(Compiler.java:7062)
	at clojure.lang.Compiler.eval(Compiler.java:7025)
	at clojure.core$eval.invokeStatic(core.clj:3206)
	at clojure.main$eval_opt.invokeStatic(main.clj:291)
	at clojure.main$eval_opt.invoke(main.clj:285)
	at clojure.main$initialize.invokeStatic(main.clj:311)
	at clojure.main$null_opt.invokeStatic(main.clj:345)
	at clojure.main$null_opt.invoke(main.clj:342)
	at clojure.main$main.invokeStatic(main.clj:424)
	at clojure.main$main.doInvoke(main.clj:387)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.lang.Var.applyTo(Var.java:702)
	at clojure.main.main(main.java:37)





[CLJS-2575] :cljs/quit in brepl doesn't work on Windows at times Created: 26/Feb/18  Updated: 26/Feb/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Windows 10



 Description   

Build uberjar, and put it on Windows. Then java -jar cljs.jar and let the browser REPL start up automatically.

I'm running *clojurescript-version* 1.10.62

If you type :cljs/quit it will often hang (especially if this is the first form evaluated, it seems). If you close the browser, it will then exit with an exception:

C:\Users\mfikes\Downloads>java -jar cljs.jar
Compiling client js ...
Serving HTTP on localhost port 9000
Listening for browser REPL connect ...
To quit, type: :cljs/quit
cljs.user=> *clojurescript-version*
"1.10.62"
cljs.user=> :cljs/quit
Exception in thread "Thread-126" java.net.SocketException: Connection reset
        at java.net.SocketInputStream.read(Unknown Source)
        at java.net.SocketInputStream.read(Unknown Source)
        at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
        at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
        at sun.nio.cs.StreamDecoder.read(Unknown Source)
        at java.io.InputStreamReader.read(Unknown Source)
        at java.io.BufferedReader.fill(Unknown Source)
        at java.io.BufferedReader.readLine(Unknown Source)
        at java.io.BufferedReader.readLine(Unknown Source)
        at sun.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at clojure.lang.Reflector.invokeMatchingMethod(Reflector.java:93)
        at clojure.lang.Reflector.invokeNoArgInstanceMember(Reflector.java:313)
        at cljs.repl.server$read_request.invokeStatic(server.clj:120)
        at cljs.repl.server$handle_connection.invokeStatic(server.clj:182)
        at cljs.repl.server$server_loop$fn__7614.invoke(server.clj:194)
        at clojure.core$binding_conveyor_fn$fn__5554.invoke(core.clj:2022)
        at clojure.lang.AFn.run(AFn.java:22)
        at java.lang.Thread.run(Unknown Source)

This doesn't seem to occur with the Node and Nashorn repl environments.






[CLJS-2576] cljs.main: Non terminate with -e on Windows Created: 26/Feb/18  Updated: 26/Feb/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

On Windows, with build uberjar (*clojurescript-version* 1.10.62), -e doesn't terminate for browser environment (unless you close the browser).

The value of -e is printed, but then it hangs. Here is a transcript showing it occurring (after a successful run with the node environment). In that transcript the exception was displayed when closing the browser.

C:\Users\mfikes\Downloads>java -jar cljs.jar -re node -e 3
3

C:\Users\mfikes\Downloads>java -jar cljs.jar -e 3
Compiling client js ...
Serving HTTP on localhost port 9000
Listening for browser REPL connect ...
3
Exception in thread "Thread-123" java.net.SocketException: Connection reset
        at java.net.SocketInputStream.read(Unknown Source)
        at java.net.SocketInputStream.read(Unknown Source)
        at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
        at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
        at sun.nio.cs.StreamDecoder.read(Unknown Source)
        at java.io.InputStreamReader.read(Unknown Source)
        at java.io.BufferedReader.fill(Unknown Source)
        at java.io.BufferedReader.readLine(Unknown Source)
        at java.io.BufferedReader.readLine(Unknown Source)
        at sun.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at clojure.lang.Reflector.invokeMatchingMethod(Reflector.java:93)
        at clojure.lang.Reflector.invokeNoArgInstanceMember(Reflector.java:313)
        at cljs.repl.server$read_request.invokeStatic(server.clj:120)
        at cljs.repl.server$handle_connection.invokeStatic(server.clj:182)
        at cljs.repl.server$server_loop$fn__7614.invoke(server.clj:194)
        at clojure.core$binding_conveyor_fn$fn__5554.invoke(core.clj:2022)
        at clojure.lang.AFn.run(AFn.java:22)
        at java.lang.Thread.run(Unknown Source)

(Perhaps this shares a root cause with CLJS-2575.)






[CLJS-2583] cljs.main: Validate -O and -t Created: 27/Feb/18  Updated: 28/Feb/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Major
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None

Attachments: Text File CLJS-2583.patch    

 Description   

Since -O and -t take on an enumerated set of values, validate them early.

This can potentially avoid some cryptic error reports. For example, supplying adv instead of advanced derails in an odd way:

$ clj -m cljs.main -O adv -c chambered.core
WARNING: :preloads should only be specified with :none optimizations
Exception in thread "main" java.lang.IllegalArgumentException: No implementation of method: :-find-sources of protocol: #'cljs.closure/Compilable found for class: nil
	at clojure.core$_cache_protocol_fn.invokeStatic(core_deftype.clj:583)
	at clojure.core$_cache_protocol_fn.invoke(core_deftype.clj:575)
	at cljs.closure$eval6819$fn__6833$G__6810__6840.invoke(closure.clj:511)
	at cljs.closure$build$fn__7680.invoke(closure.clj:2751)
	at cljs.closure$build.invokeStatic(closure.clj:2750)
	at cljs.closure$build.invoke(closure.clj:2663)
	at cljs.build.api$build.invokeStatic(api.clj:205)
	at cljs.build.api$build.invoke(api.clj:189)
	at cljs.cli$default_compile.invokeStatic(cli.clj:391)
	at cljs.cli$default_compile.invoke(cli.clj:361)
	at cljs.cli$compile_opt.invokeStatic(cli.clj:398)
	at cljs.cli$compile_opt.invoke(cli.clj:396)
	at cljs.cli$main.invokeStatic(cli.clj:527)
	at cljs.cli$main.doInvoke(cli.clj:516)
	at clojure.lang.RestFn.applyTo(RestFn.java:139)
	at clojure.core$apply.invokeStatic(core.clj:659)
	at clojure.core$apply.invoke(core.clj:652)
	at cljs.main$_main.invokeStatic(main.clj:60)
	at cljs.main$_main.doInvoke(main.clj:52)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.lang.Var.applyTo(Var.java:702)
	at clojure.core$apply.invokeStatic(core.clj:657)
	at clojure.main$main_opt.invokeStatic(main.clj:317)
	at clojure.main$main_opt.invoke(main.clj:313)
	at clojure.main$main.invokeStatic(main.clj:424)
	at clojure.main$main.doInvoke(main.clj:387)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.lang.Var.applyTo(Var.java:702)
	at clojure.main.main(main.java:37)


 Comments   
Comment by Mike Fikes [ 27/Feb/18 10:29 PM ]

The attached patch works, but there are some things I like, and some things I don't like.

It is nice that it declaratively adds specs to the commands and enhances the runtime a little to validate these specs.

But, while this feels like "input validation", another argument is that, if the compiler is going to employ specs, some, like optimization levels could be deeper in the system (which would also catch misconfiguration of compiler option edn).

Anyway, even though I'm not completely happy with the patch, attaching it in case it inspires a better approach.

Here is what you see with the patch for the example in the ticket description.

$ clj -m cljs.main -O adv -c chambered.core
Exception in thread "main" clojure.lang.ExceptionInfo: Invalid level: val: "adv" fails spec: :cljs.cli/optmizations predicate: #{"none" "advanced" "whitespace" "simple"}
 {}
	at clojure.core$ex_info.invokeStatic(core.clj:4739)
	at clojure.core$ex_info.invoke(core.clj:4739)
	at cljs.cli$add_commands$maybe_wrap_fn__8772$fn__8774.invoke(cli.clj:424)
	at cljs.cli$initialize$fn__8714.invoke(cli.clj:235)
	at clojure.lang.PersistentVector.reduce(PersistentVector.java:341)
	at clojure.core$reduce.invokeStatic(core.clj:6747)
	at clojure.core$reduce.invoke(core.clj:6730)
	at cljs.cli$initialize.invokeStatic(cli.clj:233)
	at cljs.cli$initialize.invoke(cli.clj:230)
	at cljs.cli$main.invokeStatic(cli.clj:543)
	at cljs.cli$main.doInvoke(cli.clj:531)
	at clojure.lang.RestFn.applyTo(RestFn.java:139)
	at clojure.core$apply.invokeStatic(core.clj:659)
	at clojure.core$apply.invoke(core.clj:652)
	at cljs.main$_main.invokeStatic(main.clj:60)
	at cljs.main$_main.doInvoke(main.clj:52)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.lang.Var.applyTo(Var.java:702)
	at clojure.core$apply.invokeStatic(core.clj:657)
	at clojure.main$main_opt.invokeStatic(main.clj:317)
	at clojure.main$main_opt.invoke(main.clj:313)
	at clojure.main$main.invokeStatic(main.clj:424)
	at clojure.main$main.doInvoke(main.clj:387)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.lang.Var.applyTo(Var.java:702)
	at clojure.main.main(main.java:37)
Comment by David Nolen [ 28/Feb/18 4:28 PM ]

We'd have to bump to 1.9, which we don't really require, I accidentally bumped to 1.9.0 in the pom.template.xml file.





[CLJS-2596] cljs.main: Browser script side effects don't always print Created: 02/Mar/18  Updated: 02/Mar/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

{:deps {org.clojure/clojurescript
{:git/url "https://github.com/clojure/clojurescript"
:sha "8971829275b466280a0b8fc85886e3fa7d353a13"}}}



 Description   
"src/foo/core.cljs"
(println "hello")

Sometimes this works:

$ clj -Srepro -m cljs.main src/foo/core.cljs
Compiling client js ...
Serving HTTP on localhost port 9000
Listening for browser REPL connect ...
hello

and other times it doesn't:

$ clj -Srepro -m cljs.main src/foo/core.cljs
Compiling client js ...
Serving HTTP on localhost port 9000
Listening for browser REPL connect ...

and when it fails the browser will log

[Log] Could not send {:type :print, :content "\"hello\"", :order 8} after 10 attempts. (repl, line 3272)
[Log] Could not send {:type :print, :content "\"\\n\"", :order 9} after 10 attempts. (repl, line 3272)

making it appear that the REPL terminal is shutting down before the browser can flush its prints.

This seems very much related to CLJS-2574.






[CLJS-2617] Add events for significant compiler signals (compile finished, warnings, exceptions) Created: 05/Mar/18  Updated: 05/Mar/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Major
Reporter: Bruce Hauman Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Tools like Figwheel normally have to compose over the compiler
in-order to capture important build signals (ie. compile finished,
exception thrown, syntax warnings, and perhaps compile start). This is
a significant coupling and it prevents them from reusing the built-in
watching and compiling facilities that are already available.

I'd like to propose firing events for these important build signals.
This would enable tooling like Figwheel to decouple itself from
whatever is triggering a compile in the first place.

Providing this signal would also go a long way towards making
cljs.main be the parent tool in the CLJS toolchain.

I also propse that the Object that fires these events to be attached
to the cljs.env/compiler in some fashion. The cljs.env/compiler is
already present everywhere this information is needed, and is also the
datastructure that represents/holds all the information for a
particular "build" in the compiler.

The solution could be as easy as adding data or meta-data to the map held in
cljs.env/compiler such as

:compile-data {:finished-at timestamp
                :warnings [...] 
                :exception (on exception)}

And tools could add watches to the env/compiler and wait for
these keys to be set.

This is certainly a simple solution. The downside of this may be
slowing down the compiler because changes/swaps! to the
env/compiler occur quite often and tools will checking for these
"flags" to be set on every change. Tools would have to ensure that the
processing they perform on the compiler thread is quick and to the
point or they risk slowing down the compiler. This may be a non-issue
but is worth to mentioning.

Another approach is to embed a simple observable into the
env/compiler data and fire events on this observable for the
significant build events.

Or one could simply extend the env/compiler atom with this
Observable.

There are many of solutions; the important thing is to provide the
information so that tools will have it available to them.

The great thing about using the env/compiler as a vehicle, is that
tools can add listeners for the events on the env/compiler before
they call build or they can add listeners to the env/compiler that is bound
and present on the compiler thread from a macro that is executed from
the REPL or even a compiled file. In other words tool writers would be
able to pass listeners to the compile process or add listenerers from
within it.

This would be pretty darn flexible and powerful.



 Comments   
Comment by David Nolen [ 05/Mar/18 8:56 AM ]

I don't like the idea of writing events to the state atom. The warning handler pattern seems fine to me, we should just generalize that.





[CLJS-2625] cljs.main: Sometimes print side effects don't properly occur prior to REPL Created: 07/Mar/18  Updated: 07/Mar/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

{:deps {org.clojure/clojurescript {:mvn/version "1.10.138"}}}
macOS
Safari



 Description   

Using built 1.10.138:

src/hello_world/core.cljs
(ns hello-world.core)

(println "Hello world!")

Note that sometimes Hello world! is printed, and sometimes only a newline.

$ clj -Srepro --main cljs.main --compile hello-world.core --repl
Hello world!
ClojureScript 1.10.138
cljs.user=> :cljs/quit
$ clj -Srepro --main cljs.main --compile hello-world.core --repl

ClojureScript 1.10.138
cljs.user=> :cljs/quit
$ clj -Srepro --main cljs.main --compile hello-world.core --repl
Hello world!
ClojureScript 1.10.138
cljs.user=> :cljs/quit
$ clj -Srepro --main cljs.main --compile hello-world.core --repl
Hello world!
ClojureScript 1.10.138
cljs.user=> :cljs/quit
$ clj -Srepro --main cljs.main --compile hello-world.core --repl
Hello world!
ClojureScript 1.10.138
cljs.user=> :cljs/quit
$ clj -Srepro --main cljs.main --compile hello-world.core --repl

ClojureScript 1.10.138
cljs.user=> :cljs/quit





[CLJS-2644] FileNotFoundException when building js-deps index, when emacs temp-file links are present in filesystem Created: 09/Mar/18  Updated: 09/Mar/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Bruce Hauman Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

When an emacs temp file link is in the filesystem next to its original js file the compiler fails to start with a FileNotFoundException.

This happens when a :libs path is provided and the directory is indexed.

Suggested fix: check for file existence when indexing the files with `js-deps/build-index`

and or don't include hidden files when indexing the directory.






[CLJS-2663] cljs.main: Browser REPL failure processing require of cljs.js in --init file Created: 15/Mar/18  Updated: 15/Mar/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

{:deps {org.clojure/clojurescript
{:git/url "https://github.com/clojure/clojurescript"
:sha "a095d308484fa2ccea11b6d7256fb310d5d57c33"}}}



 Description   

There is a failure to process (require 'cljs.js) when in an --init file for the browser REPL. I haven't found any other namespace that this fails with (for example, clojure.set doesn't exhibit this).

Repro:

foo.cljs
(require 'cljs.js)

(prn cljs.js/empty-state)
$ clj -Srepro -m cljs.main -re browser -i foo.cljs -r
TypeError: undefined is not an object (evaluating 'cljs.js.empty_state')
cljs.user=>

It works fine with Node:

$ clj -Srepro -m cljs.main -re node -i foo.cljs -r
#object[cljs$js$empty_state]
cljs.user=>


 Comments   
Comment by Mike Fikes [ 15/Mar/18 9:19 AM ]

Workaround:

Add an explicit -e with require prior to the -i:

clj -Srepro -m cljs.main -re browser -e "(require 'cljs.js)" -i foo.cljs -r

This is an odd workaround because, if you use it, you still need the require in the foo.cljs file.





[CLJS-2343] Double require guard bypassed if :refer-macros Created: 30/Aug/17  Updated: 30/Aug/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3196, 1.9.908
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: errors

Approval: Vetted

 Description   

If you have this code,

(ns foo.core
  (:require [cljs.test])
  (:require [clojure.string]))

it will trigger the "Only one :require form is allowed per namespace definition" diagnostic.

But this diagnostic is bypassed if you use inline macro spec sugar:

(ns foo.core
  (:require [cljs.test :refer-macros [deftest]])
  (:require [clojure.string]))

This causes the compiler to derail with this:

clojure.lang.ExceptionInfo: Only :as, :refer and :rename options supported in :require / :require-macros; offending spec: [cljs.test :refer-macros [deftest]] at line 1 <cljs repl> {:file "<cljs repl>", :line 1, :column 1, :root-source-info {:source-type :fragment, :source-form (ns foo.core (:require [cljs.test :refer-macros [deftest]]) (:require [clojure.string]))}, :tag :cljs/analysis-error}
	at clojure.core$ex_info.invokeStatic(core.clj:4617)
	at cljs.analyzer$error.invokeStatic(analyzer.cljc:693)
	at cljs.analyzer$error.invoke(analyzer.cljc:693)
	at cljs.analyzer$error.invokeStatic(analyzer.cljc:695)
	at cljs.analyzer$basic_validate_ns_spec.invokeStatic(analyzer.cljc:2256)
	at cljs.analyzer$parse_require_spec.invokeStatic(analyzer.cljc:2344)
	at cljs.analyzer$parse_require_spec.invoke(analyzer.cljc:2343)
	at clojure.lang.AFn.applyToHelper(AFn.java:171)
	at clojure.lang.AFn.applyTo(AFn.java:144)
	at clojure.core$apply.invokeStatic(core.clj:652)
	at clojure.core$partial$fn__4765.doInvoke(core.clj:2534)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at clojure.core$map$fn__4785.invoke(core.clj:2644)
	at clojure.lang.LazySeq.sval(LazySeq.java:40)
	at clojure.lang.LazySeq.seq(LazySeq.java:49)
	at clojure.lang.Cons.next(Cons.java:39)
	at clojure.lang.RT.boundedLength(RT.java:1749)
	at clojure.lang.RestFn.applyTo(RestFn.java:130)
	at clojure.core$apply.invokeStatic(core.clj:650)
	at cljs.analyzer$fn__2052$fn__2062.invoke(analyzer.cljc:2622)
	at clojure.core.protocols$fn__6755.invokeStatic(protocols.clj:167)
	at clojure.core.protocols$fn__6755.invoke(protocols.clj:124)
	at clojure.core.protocols$fn__6710$G__6705__6719.invoke(protocols.clj:19)
	at clojure.core.protocols$seq_reduce.invokeStatic(protocols.clj:31)
	at clojure.core.protocols$fn__6738.invokeStatic(protocols.clj:75)
	at clojure.core.protocols$fn__6738.invoke(protocols.clj:75)
	at clojure.core.protocols$fn__6684$G__6679__6697.invoke(protocols.clj:13)
	at clojure.core$reduce.invokeStatic(core.clj:6545)
	at cljs.analyzer$fn__2052.invokeStatic(analyzer.cljc:2575)
	at cljs.analyzer$fn__2052.invoke(analyzer.cljc:2556)
	at clojure.lang.MultiFn.invoke(MultiFn.java:251)
	at cljs.analyzer$analyze_seq_STAR_.invokeStatic(analyzer.cljc:3333)
	at cljs.analyzer$analyze_seq_STAR__wrap.invokeStatic(analyzer.cljc:3336)
	at cljs.analyzer$analyze_seq.invokeStatic(analyzer.cljc:3361)
	at cljs.analyzer$analyze_form.invokeStatic(analyzer.cljc:3530)
	at cljs.analyzer$analyze_STAR_.invokeStatic(analyzer.cljc:3577)
	at cljs.analyzer$analyze.invokeStatic(analyzer.cljc:3603)
	at cljs.repl$evaluate_form$__GT_ast__6169.invoke(repl.cljc:471)
	at cljs.repl$evaluate_form.invokeStatic(repl.cljc:472)
	at cljs.repl$eval_cljs.invokeStatic(repl.cljc:631)
	at cljs.repl$eval_cljs.invoke(repl.cljc:618)
	at cljs.repl$repl_STAR_$read_eval_print__6300.invoke(repl.cljc:880)
	at cljs.repl$repl_STAR_$fn__6306$fn__6315.invoke(repl.cljc:922)
	at cljs.repl$repl_STAR_$fn__6306.invoke(repl.cljc:921)
	at cljs.compiler$with_core_cljs.invokeStatic(compiler.cljc:1252)
	at cljs.repl$repl_STAR_.invokeStatic(repl.cljc:882)
	at cljs.repl$repl.invokeStatic(repl.cljc:1001)
	at cljs.repl$repl.doInvoke(repl.cljc:933)
	at clojure.lang.RestFn.invoke(RestFn.java:410)
	at cljs.repl.node$_main.invokeStatic(node.clj:234)
	at cljs.repl.node$_main.invoke(node.clj:233)
	at clojure.lang.Var.invoke(Var.java:375)
	at clojure.lang.AFn.applyToHelper(AFn.java:152)
	at clojure.lang.Var.applyTo(Var.java:700)
	at clojure.core$apply.invokeStatic(core.clj:646)
	at clojure.main$main_opt.invokeStatic(main.clj:314)
	at clojure.main$main_opt.invoke(main.clj:310)
	at clojure.main$main.invokeStatic(main.clj:421)
	at clojure.main$main.doInvoke(main.clj:384)
	at clojure.lang.RestFn.invoke(RestFn.java:421)
	at clojure.lang.Var.invoke(Var.java:383)
	at clojure.lang.AFn.applyToHelper(AFn.java:156)
	at clojure.lang.Var.applyTo(Var.java:700)
	at clojure.main.main(main.java:37)





[CLJS-2683] Suppress compiler options in watch log Created: 21/Mar/18  Updated: 21/Mar/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Major
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

{:deps {org.clojure/clojurescript {:mvn/version "1.10.217"}}}



 Description   

If running watch via cljs.main compiler options logged for each watch event.

src/hello_world/core.cljs
(ns hello-world.core)
watch.clj
(require 'cljs.build.api)

(cljs.build.api/watch "src"
  {:main 'hello-world.core
   :output-to "out/main.js"})

If you

clj watch.clj

and tail -f out/watch.log and touch src/hello_world/core.cljs, you will see

Options passed to ClojureScript compiler: 

along with a fairly verbose options EDN dump, for every watch event.

The same happens with

clj -Srepro -m cljs.main -w src -c hello-world.core -r





[CLJS-2684] cljs.main: Watch with Node fails regarding :main Created: 21/Mar/18  Updated: 21/Mar/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

{:deps {org.clojure/clojurescript {:mvn/version "1.10.217"}}}



 Description   
src/hello_world/core.cljs
(ns hello-world.core)

If you

clj -m cljs.main -re node -v -c hello-world.core -r

the verbose logging will show that the compiler options includes

:main hello-world.core

but if you simply add -w src:

clj -m cljs.main -re node -v -w src -c hello-world.core -r

then out/watch.log will show that an assert is triggered:

Building ...
java.lang.AssertionError: Assert failed: :nodejs target with :none optimizations requires a :main entry
(not (and (= target :nodejs) (= optimizations :none) (not (contains? opts :main))))
	at cljs.closure$check_node_target.invokeStatic(closure.clj:2068)
	at cljs.closure$check_node_target.invoke(closure.clj:2065)
	at cljs.closure$build.invokeStatic(closure.clj:2735)
	at cljs.closure$build.invoke(closure.clj:2697)
	at cljs.closure$watch$buildf__5939.invoke(closure.clj:2907)
	at cljs.closure$watch.invokeStatic(closure.clj:2939)
	at cljs.closure$watch.invoke(closure.clj:2883)
	at cljs.repl$repl_STAR_$fn__6536$fn__6541.invoke(repl.cljc:983)
	at clojure.core$binding_conveyor_fn$fn__5476.invoke(core.clj:2022)
	at clojure.lang.AFn.run(AFn.java:22)
	at java.lang.Thread.run(Thread.java:748)

Watching paths: /private/tmp/watch-noisy/src





[CLJS-2695] Windows stack trace not source-mapped Created: 23/Mar/18  Updated: 23/Mar/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Windows 10
Current master uberjar (1.10.225)
Microsoft Edge



 Description   

Running through the new 1.10.x Quick Start on Windows, you can see that the stack trace is not source-mapped (referring to JavaScript line numbers).

cljs.user=> (ffirst [1])
Error: 1 is not ISeqable
Error: 1 is not ISeqable
   at cljs$core$seq (http://localhost:9000/out/cljs/core.js:4457:1)
   at cljs$core$first (http://localhost:9000/out/cljs/core.js:4476:1)
   at cljs$core$ffirst (http://localhost:9000/out/cljs/core.js:5922:1)
   at Anonymous function (eval code:1:55)
   at Anonymous function (eval code:1:18)
   at eval code (eval code:1:2)
   at Anonymous function (http://localhost:9000/out/clojure/browser/repl.js:115:31)
   at clojure$browser$repl$evaluate_javascript (http://localhost:9000/out/clojure/browser/repl.js:115:1)
   at Anonymous function (http://localhost:9000/out/clojure/browser/repl.js:372:5)
   at Anonymous function (http://localhost:9000/out/clojure/browser/repl.js:369:1)

Likewise source mapping not working in Node:

(This is after doing npm install source-map-support.)

cljs.user=> (ffirst [1])
Error: 1 is not ISeqable
   at cljs$core$seq (C:\Users\mfikes\AppData\Local\Temp\out90041183794981196991184876870030\cljs\core.js:4457:1)
   at cljs$core$first (C:\Users\mfikes\AppData\Local\Temp\out90041183794981196991184876870030\cljs\core.js:4476:1)
   at cljs$core$ffirst (C:\Users\mfikes\AppData\Local\Temp\out90041183794981196991184876870030\cljs\core.js:5922:1)
   at Anonymous function (repl:1:55)
   at Anonymous function (repl:1:18)
   at Global code (repl:1:2)
   at exports.runInThisContext (vm.js:54:3)
   at Anonymous function ([stdin]:76:29)
   at Domain.prototype.run (domain.js:222:5)
   at Anonymous function ([stdin]:73:25)





[CLJS-2655] Rhino & Nashorn Socket REPLs don't share evaluation environment Created: 13/Mar/18  Updated: 24/Mar/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Clojure Socket REPLs share an evaluation environment.

For example, start up with

java -Dclojure.server.repl="{:port 5555 :accept clojure.core.server/repl}" -cp cljs.jar clojure.main

Then in one terminal

$ telnet 0 5555
Trying 0.0.0.0...
Connected to localhost.
Escape character is '^]'.
user=> (def x 3)
#'user/x

then if you go into another terminal

$ telnet 0 5555
Trying 0.0.0.0...
Connected to localhost.
Escape character is '^]'.
user=> x
3

and in the original terminal where you started the socket REPL:

user=> x
3

Here is what I get with the Node Socket REPL (not sure if I'm starting it the right way):

java -Dclojure.server.repl="{:port 5555 :accept cljs.server.node/repl}" -cp cljs.jar clojure.main

First terminal:

$ telnet 0 5555
Trying 0.0.0.0...
Connected to localhost.
Escape character is '^]'.
ClojureScript 1.10.160
cljs.user=> (def x 3)
#'cljs.user/x

Second terminal:

$ telnet 0 5555
Trying 0.0.0.0...
Connected to localhost.
Escape character is '^]'.
ClojureScript 1.10.160
cljs.user=> x
WARNING: Use of undeclared Var cljs.user/x at line 1 <cljs repl>
nil


 Comments   
Comment by David Nolen [ 16/Mar/18 9:51 AM ]

To clarify, ClojureScript Socket REPLs must be made to work this way one by one. Only cljs.server.browser currently works this way. The others needs to be adjusted. The main thrust of this work is to make -setup & -teardown idempotent and thread safe. The other bit is to make sure that output gets directed correctly. Browser REPL currently exhibits this bug https://dev.clojure.org/jira/browse/CLJS-2643.





[CLJS-2016] Support inheritance annotations in externs Created: 25/Apr/17  Updated: 29/Mar/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Major
Reporter: Jonathan Henry Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Closure externs may contain @extends annotations to specify base classes. The base classes' attributes should be propagated to subclasses in `:cljs.analyzer/externs`.






[CLJS-2270] Support AOT compilation of macro namespaces (bootstrap) Created: 24/Jul/17  Updated: 29/Mar/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.9.671
Fix Version/s: Next

Type: Enhancement Priority: Major
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: bootstrap

Approval: Vetted

 Comments   
Comment by Andrea Richiardi [ 08/Feb/18 11:18 AM ]

This is great! It is exactly what we were discussing at some point in lumo with Antonio. I am interested in what is the possible approach for solving transitive dependency issues: I really like the npm approach that inlines deps under the parent (each one gets its own).





[CLJS-1678] variadic defn can be called for missing fixed arities, overlapping arity Created: 11/Jun/16  Updated: 29/Mar/18

Status: Reopened
Project: ClojureScript
Component/s: None
Affects Version/s: 1.9.671
Fix Version/s: Next

Type: Defect Priority: Major
Reporter: Francis Avila Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: core


 Description   

For defns with a variadic arity: if invoked with a missing fixed arity, they use the variadic method instead of erroring; if invoked with a fixed arity that is the max fixed arity, variadic mathod instead of fixed form is invoked.

(defn f-hole
  ([a] 1)
  ([a b c d & args] "4 or more"))

(f-hole 1 2) ; =>"4 or more", should be error

(defn f-overlap-mfa
  ([a b] 2)
  ([a b & c] "2+"))

(f-overlap-mfa 1) ;=> "2+", should be error
(f-overlap-mfa 1 2) ;=> "2+", should be 2
(f-overlap-mfa 1 2 3) ;=> "2+", correct

A way to fix the f-hole bug is to emit a "case X:" into the switch statement for all X with no signature or less than max-fixed-arity.

The f-overlap-mfa I'm not sure why is happening and didn't investigate deeply.



 Comments   
Comment by Francis Avila [ 11/Jun/16 8:31 AM ]

Sorry, filed against CLJ instead of CLJS!

Comment by Rohit Aggarwal [ 12/Jun/16 9:41 AM ]

The behaviour I am seeing for f-overlap-mfa is:

(f-overlap-mfa 1) ;=> "2+"
(f-overlap-mfa 1 2) ;=> 2
(f-overlap-mfa 1 2 3) ;=> "2+"

So the two argument result is different for me than you, Francis Avila.

The call with just one argument does give a warning though:

WARNING: Wrong number of args (1) passed to cljs.user/f-overlap-mfa





[CLJS-1147] reconnect logic for browser REPLs Created: 18/Mar/15  Updated: 27/Jun/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.7.145
Fix Version/s: 1.9.671

Type: Enhancement Priority: Major
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Instead of forcing users to refresh browser and lose application state, the browser REPL should poll once a second to connect if connection is unreachable for some reason.



 Comments   
Comment by David Nolen [ 21/Mar/15 8:56 PM ]

This is firmly a major nice-to-have, but not a blocker.





[CLJS-2732] Allow vars to be invoked with infinite arglists Created: 08/Apr/18  Updated: 09/Apr/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Major
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

CLJ-1423 but for ClojureScript.

(apply distinct? (repeat 1)) returns immediately

(apply #'distinct? (repeat 1)) hangs



 Comments   
Comment by A. R [ 09/Apr/18 2:45 AM ]

Isn't this just CLJS-365 ? The Var impl is already good.





[CLJS-2155] building fileUrl on windows in repl.cljc results with java.net.UnknownHostException Created: 03/Jul/17  Updated: 19/Aug/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.9.671
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Vojimir Golem Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: None
Environment:

Windows OS



 Description   

I think that the following line might cause the problem on windows:
https://github.com/clojure/clojurescript/blob/master/src/main/clojure/cljs/repl.cljc#L713

For file param e.g. "src\duct3\client.cljs"

(str "file://" (.getAbsolutePath file))

evaluates on windows as:
"file://C:\Projects\Playground\duct3\src\duct3\client.cljs"

which is not legal file Url (https://en.wikipedia.org/wiki/File_URI_scheme#Windows)

and final result is: java.net.UnknownHostException (java treat that URL as FTP address).



 Comments   
Comment by Vojimir Golem [ 19/Aug/17 10:02 AM ]

Permalink to mentioned line:
https://github.com/clojure/clojurescript/blob/98656d305e6447c62e36849ee615532d53211fdd/src/main/clojure/cljs/repl.cljc#L736





[CLJS-2408] js->clj does not work on objects with null prototype Created: 21/Nov/17  Updated: 25/Apr/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.9.908
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Kurt Harriger Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: None


 Description   

Version: 1.9.946
Follow up from issue CLJS-1998

cljs.user=> (js->clj #js {})
{}

cljs.user=> (js->clj (.create js/Object nil))
#object[Object]

cljs.user=> (keys (js->clj (.create js/Object nil)))
org.mozilla.javascript.EcmaError: TypeError: Cannot find default value for object. (.cljs_rhino_repl/goog/../.cljs_rhino_repl/cljs/core.js#9915)
	 (.cljs_rhino_repl/cljs/core.cljs:2930:10)
	 cljs$core$seq (.cljs_rhino_repl/cljs/core.cljs:1212:13)
	 cljs$core$keys (.cljs_rhino_repl/cljs/core.cljs:8648:3)
	 (NO_SOURCE_FILE <cljs repl>:1:0)
	 (NO_SOURCE_FILE <cljs repl>:1:0)


 Comments   
Comment by Kurt Harriger [ 21/Nov/17 8:44 PM ]

For more context the source of the object with null prototype is generated in a third party library I am using here https://github.com/ProseMirror/prosemirror-model/blob/cdded3d/src/schema.js#L13

Comment by Kurt Harriger [ 21/Mar/18 7:47 PM ]

```
(def a (.create js/Object null)) => #'cljs.user/a
(type a) => nil
```

The implementation of js->clj explicitly checks for type js/Object.

```
(defn js->clj
"Recursively transforms JavaScript arrays into ClojureScript
vectors, and JavaScript objects into ClojureScript maps. With
option ':keywordize-keys true' will convert object fields from
strings to keywords."
([x] (js->clj x :keywordize-keys false))
([x & opts]
(let [{:keys [keywordize-keys]} opts
keyfn (if keywordize-keys keyword str)
f (fn thisfn [x]
(cond
(satisfies? IEncodeClojure x)
(js>clj x (apply array-map opts))

(seq? x)
(doall (map thisfn x))

(coll? x)
(into (empty x) (map thisfn x))

(array? x)
(vec (map thisfn x))

(identical? (type x) js/Object)
(into {} (for [k (js-keys x)]
[(keyfn k) (thisfn (unchecked-get x k))]))

:else x))
```

I think perhaps this last test should be changed to `(or (nil? (type a)) (identical? (type x) js/Object))` because the only way to create an object with a null prototype is explicitly and they do so because they are intended to be used as associative objects. (http://adripofjavascript.com/blog/drips/creating-objects-without-prototypes.html)

Comment by Kurt Harriger [ 22/Mar/18 5:55 PM ]

The above also suggests that maybe one could extend IEncodeClojure on nil?
`a` is not `nil` but its type is... so maybe extending protocol on nil should this work?

But it doesn't... maybe this is a bug in `satisfies?`?

```
cljs.user=> (def a (.create js/Object nil))
#'cljs.user/a
cljs.user=> (aset a "test" 1)
1
cljs.user=> (extend-protocol IEncodeClojure
nil
(js>clj [x opts]
(let [{:keys [keywordize-keys]} opts
keyfn (if keywordize-keys keyword str)]
(into {} (for [k (js-keys x)]
[(keyfn k) (js->clj (unchecked-get x k)) opts])))))
nil
cljs.user=> (js->clj a)
#object[Object]
cljs.user=> (js-keys IEncodeClojure)
#js ["null"]
cljs.user=> (satisfies? IEncodeClojure a)
false
cljs.user=> (type a)
nil

```

Comment by Hendrik Poernama [ 25/Apr/18 4:04 AM ]

What about `(identical? (goog/typeOf x) "object")` instead of `(identical? (type x) js/Object)`?

Closure's typeOf correctly returns 'null' and 'array' and has some browser specific fixes.
Current test looks like a lot less code, so may need to performance test.

Example:
(identical? "object" (goog/typeOf (.create js/Object nil #js {:a #js {:value 1}}))) => true





[CLJS-2626] Assess JavaWebSocket Created: 07/Mar/18  Updated: 25/Apr/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Task Priority: Major
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None

Attachments: Text File CLJS-2626.patch    

 Description   

We would like a more robust standard browser based REPL. A WebSocket implementation would be a significant step in that direction. We should assess https://github.com/TooTallNate/Java-WebSocket, it has few dependencies and appears well maintained.



 Comments   
Comment by John Newman [ 17/Mar/18 9:44 AM ]

Working on a patch for this.

Some work has been completed to help us assess TooTallNate/Java-WebSocket. Here is a simple chat server:

https://gist.github.com/johnmn3/a845f2bf67ad877d957bccd7f9cefe8c

Here is a very simple implementation of Java-WebSocket in Weasel:

https://github.com/johnmn3/weasel/commit/e5eb062dca3dbf623ce1c683443f2a0b3768f749

I will be working with @bhauman on this patch. I'm available on slack for anyone interested in discussing design considerations but feel free to comment here with recommendations or questions.

Comment by John Newman [ 25/Apr/18 10:12 AM ]

WIP snapshot of JavaWebSocket assessment





[CLJS-2677] Better handling of npm-deps via REPL require when output-dir not specified Created: 20/Mar/18  Updated: 25/Apr/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Major
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: npm-deps
Environment:

{:deps {org.clojure/clojurescript {:mvn/version "1.10.217"}}}



 Description   

I'm speculating that the following doesn't work because Closure is not involved when requiring at the REPL.

co.edn
{:output-dir "out"
 :output-to "out/main.js"
 :optimizations :none
 :install-deps true
 :npm-deps {:react "15.6.1"
            :react-dom "15.6.1"}}
src/example/core.cljs
(ns example.core
  (:require [react :refer [createElement]]
            ["react-dom/server" :as ReactDOMServer :refer [renderToString]]))

(js/console.log (renderToString (createElement "div" nil "Hello World!")))

This works fine:

clj -m cljs.main -co co.edn -c example.core -r

logging this in the browser console

[Log] <div data-reactroot="" data-reactid="1" data-react-checksum="1309021079">Hello World!</div> (core.js, line 6)

But if instead you start off fresh (without out, node_modules, package.json and package-lock.json) and do

clj -m cljs.main -co co.edn -r

followed by this in the REPL:

(require 'example.core)

No errors are shown in the REPL console, but the JavaScript console shows lots of errors.

I think to satisfy this ticket this could either be made to "just work" somehow, or perhaps instead the problem could be detected and an ex-info thrown letting the user know that things won't work this way.

Here are the errors logged:

[Error] ReferenceError: Can't find variable: process
	Global Code (warning.js:4)
[Error] ReferenceError: Can't find variable: process
	Global Code (canDefineProperty.js:2:170)
[Error] ReferenceError: Can't find variable: process
	Global Code (emptyObject.js:2:153)
[Error] ReferenceError: Can't find variable: process
	Global Code (invariant.js:4:192)
[Error] ReferenceError: Can't find variable: process
	Global Code (lowPriorityWarning.js:3)
[Error] ReferenceError: Can't find variable: process
	Global Code (ReactBaseClasses.js:16)
[Error] ReferenceError: Can't find variable: process
	Global Code (ReactPropTypeLocationNames.js:2:185)
[Error] ReferenceError: Can't find variable: process
	Global Code (ReactDOMFactories.js:5)
[Error] ReferenceError: Can't find variable: process
	Global Code (checkPropTypes.js:10)
[Error] ReferenceError: Can't find variable: process
	createChainableTypeChecker (factoryWithTypeCheckers.js:12:305)
	createPrimitiveTypeChecker (factoryWithTypeCheckers.js:17:102)
	(anonymous function) (factoryWithTypeCheckers.js:10:535)
	(anonymous function) (factory.js:3:441)
	Global Code (ReactPropTypes.js:5:149)
[Error] ReferenceError: Can't find variable: process
	Global Code (factory.js:34:317)
[Error] ReferenceError: Can't find variable: process
	Global Code (React.js:18)
[Error] ReferenceError: Can't find variable: process
	Global Code (EventPluginRegistry.js:16:218)
[Error] ReferenceError: Can't find variable: process
	Global Code (ReactErrorUtils.js:5)
[Error] ReferenceError: Can't find variable: process
	Global Code (EventPluginUtils.js:12)
[Error] TypeError: undefined is not an object (evaluating 'module$private$tmp$island$node_modules$react_dom$lib$EventPluginRegistry["default"].injectEventPluginOrder')
	Global Code (EventPluginHub.js:16:199)
[Error] TypeError: undefined is not an object (evaluating 'module$private$tmp$island$node_modules$react_dom$lib$EventPluginHub["default"].getListener')
	Global Code (EventPropagators.js:9:167)
[Error] ReferenceError: Can't find variable: process
	Global Code (SyntheticEvent.js:18)
[Error] TypeError: undefined is not a function (near '...module$private$tmp$island$node_modules$react_dom$lib$SyntheticEvent["default"].augmentClass...')
	Global Code (SyntheticCompositionEvent.js:4:393)
[Error] TypeError: undefined is not a function (near '...module$private$tmp$island$node_modules$react_dom$lib$SyntheticEvent["default"].augmentClass...')
	Global Code (SyntheticInputEvent.js:4:203)
[Error] ReferenceError: Can't find variable: process
	Global Code (DOMProperty.js:14:471)
[Error] TypeError: undefined is not an object (evaluating 'module$private$tmp$island$node_modules$react_dom$lib$DOMProperty["default"].ID_ATTRIBUTE_NAME')
	Global Code (ReactDOMComponentTree.js:7:516)
[Error] ReferenceError: Can't find variable: process
	Global Code (ReactInvalidSetStateWarningHook.js:4)
[Error] ReferenceError: Can't find variable: process
	Global Code (ReactInstrumentation.js:4)
[Error] TypeError: undefined is not a function (near '...module$private$tmp$island$node_modules$react_dom$lib$SyntheticEvent["default"].augmentClass...')
	Global Code (SyntheticUIEvent.js:7:93)
[Error] TypeError: undefined is not a function (near '...module$private$tmp$island$node_modules$react_dom$lib$SyntheticUIEvent["default"].augmentClass...')
	Global Code (SyntheticMouseEvent.js:9:95)
[Error] TypeError: undefined is not an object (evaluating 'module$private$tmp$island$node_modules$react_dom$lib$DOMProperty["default"].injection')
	Global Code (HTMLDOMPropertyConfig.js:3:425)
[Error] ReferenceError: Can't find variable: process
	Global Code (DOMChildrenOperations.js:21)
[Error] TypeError: undefined is not an object (evaluating 'module$private$tmp$island$node_modules$react_dom$lib$DOMChildrenOperations["default"].dangerouslyReplaceNodeWithMarkup')
	Global Code (ReactComponentBrowserEnvironment.js:5:349)
[Error] ReferenceError: Can't find variable: process
	Global Code (CSSPropertyOperations.js:17)
[Error] TypeError: undefined is not an object (evaluating 'module$private$tmp$island$node_modules$react_dom$lib$DOMProperty["default"].ATTRIBUTE_NAME_START_CHAR')
	Global Code (DOMPropertyOperations.js:9:200)
[Error] TypeError: undefined is not an object (evaluating 'module$private$tmp$island$node_modules$react$lib$React["default"].isValidElement')
	Global Code (LinkedValueUtils.js:9:533)
[Error] ReferenceError: Can't find variable: process
	Global Code (ReactPropTypeLocationNames.js:2:193)
[Error] ReferenceError: Can't find variable: process
	Global Code (ReactCompositeComponent.js:21:366)
[Error] ReferenceError: Can't find variable: process
	Global Code (ReactMultiChild.js:21)
[Error] ReferenceError: Can't find variable: process
	Global Code (ReactServerRenderingTransaction.js:10:126)
[Error] ReferenceError: Can't find variable: process
	Global Code (validateDOMNesting.js:7)
[Error] TypeError: undefined is not an object (evaluating 'module$private$tmp$island$node_modules$react_dom$lib$EventPluginHub["default"].deleteListener')
	Global Code (ReactDOMComponent.js:42:171)
[Error] TypeError: undefined is not an object (evaluating 'module$private$tmp$island$node_modules$react_dom$lib$DOMProperty["default"].injection')
	Global Code (ReactInjection.js:13:279)
[Error] ReferenceError: Can't find variable: process
	Global Code (ReactReconcileTransaction.js:18)
[Error] TypeError: undefined is not a function (near '...module$private$tmp$island$node_modules$react_dom$lib$SyntheticEvent["default"].augmentClass...')
	Global Code (SyntheticAnimationEvent.js:4:256)
[Error] TypeError: undefined is not a function (near '...module$private$tmp$island$node_modules$react_dom$lib$SyntheticEvent["default"].augmentClass...')
	Global Code (SyntheticClipboardEvent.js:4:303)
[Error] TypeError: undefined is not a function (near '...module$private$tmp$island$node_modules$react_dom$lib$SyntheticUIEvent["default"].augmentClass...')
	Global Code (SyntheticFocusEvent.js:4:214)
[Error] TypeError: undefined is not a function (near '...module$private$tmp$island$node_modules$react_dom$lib$SyntheticUIEvent["default"].augmentClass...')
	Global Code (SyntheticKeyboardEvent.js:10:95)
[Error] TypeError: undefined is not a function (near '...module$private$tmp$island$node_modules$react_dom$lib$SyntheticMouseEvent["default"].augmentClass...')
	Global Code (SyntheticDragEvent.js:4:214)
[Error] TypeError: undefined is not a function (near '...module$private$tmp$island$node_modules$react_dom$lib$SyntheticUIEvent["default"].augmentClass...')
	Global Code (SyntheticTouchEvent.js:6:95)
[Error] TypeError: undefined is not a function (near '...module$private$tmp$island$node_modules$react_dom$lib$SyntheticEvent["default"].augmentClass...')
	Global Code (SyntheticTransitionEvent.js:4:257)
[Error] TypeError: undefined is not a function (near '...module$private$tmp$island$node_modules$react_dom$lib$SyntheticMouseEvent["default"].augmentClass...')
	Global Code (SyntheticWheelEvent.js:5:98)
[Error] TypeError: undefined is not an object (evaluating 'module$private$tmp$island$node_modules$react_dom$lib$ReactInjection["default"].EventEmitter')
	inject (ReactDefaultInjection.js:22:383)
	Global Code (ReactDOMServer.js:6:257)
[Error] TypeError: undefined is not an object (evaluating 'module$private$tmp$island$node_modules$react_dom$server["default"].renderToString')
	Global Code (core.js:6)


 Comments   
Comment by David Nolen [ 20/Mar/18 9:59 AM ]

You must set :output-dir if you intend to use :npm-deps for now. If we somehow figure out a way to make this work, it also needs to work with Node.js if you do not supply :output-dir.





[CLJS-1410] Support source maps in deps.cljs Created: 09/Aug/15  Updated: 12/Feb/16

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Major
Reporter: Martin Klepsch Assignee: Unassigned
Resolution: Unresolved Votes: 4
Labels: None


 Description   

There should be support to package source maps with a foreign-lib using deps.cljs



 Comments   
Comment by David Nolen [ 12/Feb/16 3:00 PM ]

Patch welcome for this one!





[CLJS-2622] Add support for package tarballs in :npm-deps Created: 06/Mar/18  Updated: 30/Apr/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.10.238
Fix Version/s: None

Type: Enhancement Priority: Major
Reporter: Jannis Pohlmann Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: npm-deps

Attachments: Text File CLJS-2622.patch    

 Description   

NPM supports installing packages from tarballs via {npm install /path/to/foo.tgz}. This can be useful for trying a local (modified) version of a package, or generally any unpublished and/or private JS project; all that's needed is a {package.json} and a {.js} file and {npm pack} can generate a tarball.

It would be nice if ClojureScript would support this as well, through {:npm-deps}.

Proposed syntax:

{:npm-deps {"/path/to/tarball.tgz" "0.1.0"
            "/path/to/bar.tgz" ""}}

The version isn't needed with tarballs, so it could be anything.

I have the code for this working but I still want to add a test before I submit a patch.



 Comments   
Comment by Jannis Pohlmann [ 07/Mar/18 7:18 AM ]

This patch implements the feature and adds tests for indexing and building with a tarball dependency.

Comment by Thomas Heller [ 30/Apr/18 2:53 PM ]

What benefit does this provide over just running npm install ./some.tgz?

I don't think this is a good idea.





[CLJS-1690] spec the ClojureScript AST Created: 21/Jun/16  Updated: 21/Jun/16

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.9.76
Fix Version/s: None

Type: Task Priority: Major
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: None





[CLJS-2752] load-file fails if no output dir specified Created: 18/May/18  Updated: 18/May/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.10.238
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

{:deps {org.clojure/clojurescript {:mvn/version "1.10.238"}}}



 Description   
foo.cljs
(def x 3)

Working with -d:

$ clj -m cljs.main -re node -d out -r
ClojureScript 1.10.238
cljs.user=> (load-file "foo.cljs")
nil
cljs.user=> x
3

Failing without:

$ clj -m cljs.main -re node -r
ClojureScript 1.10.238
cljs.user=> (load-file "foo.cljs")
java.lang.IllegalArgumentException: /var/folders/gx/nymj3l7x4zq3gxb97v2zwzb40000gn/T/out7651413336278138652227528048732117/cljs/user/fooAD3E4B4.js is not a relative path
	at clojure.java.io$as_relative_path.invokeStatic(io.clj:414)
	at clojure.java.io$file.invokeStatic(io.clj:426)
	at clojure.java.io$file.invoke(io.clj:418)
	at cljs.closure$compile_file.invokeStatic(closure.clj:572)
	at cljs.closure$compile_file.invoke(closure.clj:564)
	at cljs.closure$fn__5124.invokeStatic(closure.clj:653)
	at cljs.closure$fn__5124.invoke(closure.clj:647)
	at cljs.closure$fn__5052$G__5045__5059.invoke(closure.clj:521)
	at cljs.closure$compile.invokeStatic(closure.clj:557)
	at cljs.closure$compile.invoke(closure.clj:554)
	at cljs.repl$load_file$fn__6378.invoke(repl.cljc:586)
	at cljs.repl$load_file.invokeStatic(repl.cljc:585)
	at cljs.repl$load_file.invoke(repl.cljc:577)
	at cljs.repl$fn__6429$self__6431.invoke(repl.cljc:740)
	at clojure.lang.AFn.applyToHelper(AFn.java:165)
	at clojure.lang.AFn.applyTo(AFn.java:144)
	at clojure.core$apply.invokeStatic(core.clj:657)
	at clojure.core$apply.invoke(core.clj:652)
	at cljs.repl$wrap_self$g__6408.invoke(repl.cljc:724)
	at cljs.repl$repl_STAR_$read_eval_print__6536.invoke(repl.cljc:955)
	at cljs.repl$repl_STAR_$fn__6542$fn__6551.invoke(repl.cljc:998)
	at cljs.repl$repl_STAR_$fn__6542.invoke(repl.cljc:997)
	at cljs.compiler$with_core_cljs.invokeStatic(compiler.cljc:1285)
	at cljs.compiler$with_core_cljs.invoke(compiler.cljc:1274)
	at cljs.repl$repl_STAR_.invokeStatic(repl.cljc:960)
	at cljs.repl$repl_STAR_.invoke(repl.cljc:839)
	at cljs.cli$repl_opt.invokeStatic(cli.clj:290)
	at cljs.cli$repl_opt.invoke(cli.clj:277)
	at cljs.cli$main.invokeStatic(cli.clj:612)
	at cljs.cli$main.doInvoke(cli.clj:601)
	at clojure.lang.RestFn.applyTo(RestFn.java:139)
	at clojure.core$apply.invokeStatic(core.clj:659)
	at clojure.core$apply.invoke(core.clj:652)
	at cljs.main$_main.invokeStatic(main.clj:61)
	at cljs.main$_main.doInvoke(main.clj:52)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.lang.Var.applyTo(Var.java:702)
	at clojure.core$apply.invokeStatic(core.clj:657)
	at clojure.main$main_opt.invokeStatic(main.clj:317)
	at clojure.main$main_opt.invoke(main.clj:313)
	at clojure.main$main.invokeStatic(main.clj:424)
	at clojure.main$main.doInvoke(main.clj:387)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.lang.Var.applyTo(Var.java:702)
	at clojure.main.main(main.java:37)





[CLJS-2728] Ability to disable macro spec checks Created: 08/Apr/18  Updated: 18/May/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Major
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Akin to Clojure's new ability https://github.com/clojure/clojure/commit/3d9b356306db77946bdf4809baeb660f94cec846

Perhaps ClojureScript would employ a new compiler option to control this?



 Comments   
Comment by David Nolen [ 18/May/18 1:03 PM ]

Agreed.





[CLJS-2756] Relative path issue processing node_modules file Created: 21/May/18  Updated: 21/May/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: npm-deps
Environment:

{:deps {org.clojure/clojurescript {:mvn/version "1.10.238"}}}



 Description   

The following

clojure -m cljs.main -co '{:npm-deps {"slate" "0.33.6"} :install-deps true}' -e "(require 'slate)"

generates the following exception

Exception in thread "main" java.lang.IllegalArgumentException: /Users/mfikes/node_modules/immutable/dist/immutable.js is not a relative path
	at clojure.java.io$as_relative_path.invokeStatic(io.clj:414)
	at clojure.java.io$file.invokeStatic(io.clj:426)
	at clojure.java.io$file.invoke(io.clj:418)
	at cljs.closure$write_javascript.invokeStatic(closure.clj:1857)
	at cljs.closure$write_javascript.invoke(closure.clj:1850)
	at cljs.closure$process_js_modules$fn__5815.invoke(closure.clj:2560)
	at clojure.lang.ArrayChunk.reduce(ArrayChunk.java:63)
	at clojure.core.protocols$fn__7847.invokeStatic(protocols.clj:136)
	at clojure.core.protocols$fn__7847.invoke(protocols.clj:124)
	at clojure.core.protocols$fn__7807$G__7802__7816.invoke(protocols.clj:19)
	at clojure.core.protocols$seq_reduce.invokeStatic(protocols.clj:31)
	at clojure.core.protocols$fn__7835.invokeStatic(protocols.clj:75)
	at clojure.core.protocols$fn__7835.invoke(protocols.clj:75)
	at clojure.core.protocols$fn__7781$G__7776__7794.invoke(protocols.clj:13)
	at clojure.core$reduce.invokeStatic(core.clj:6748)
	at clojure.core$reduce.invoke(core.clj:6730)
	at cljs.closure$process_js_modules.invokeStatic(closure.clj:2559)
	at cljs.closure$process_js_modules.invoke(closure.clj:2518)
	at cljs.closure$handle_js_modules.invokeStatic(closure.clj:2672)
	at cljs.closure$handle_js_modules.invoke(closure.clj:2633)
	at cljs.repl$evaluate_form.invokeStatic(repl.cljc:508)
	at cljs.repl$evaluate_form.invoke(repl.cljc:484)
	at cljs.repl$eval_cljs.invokeStatic(repl.cljc:672)
	at cljs.repl$eval_cljs.invoke(repl.cljc:665)
	at cljs.repl$run_inits$fn__6480.invoke(repl.cljc:823)
	at cljs.repl$run_inits.invokeStatic(repl.cljc:821)
	at cljs.repl$run_inits.invoke(repl.cljc:814)
	at cljs.cli$default_main$fn__6799.invoke(cli.clj:340)
	at cljs.compiler$with_core_cljs.invokeStatic(compiler.cljc:1285)
	at cljs.compiler$with_core_cljs.invoke(compiler.cljc:1274)
	at cljs.compiler.api$with_core_cljs.invokeStatic(api.clj:50)
	at cljs.compiler.api$with_core_cljs.invoke(api.clj:34)
	at cljs.compiler.api$with_core_cljs.invokeStatic(api.clj:42)
	at cljs.compiler.api$with_core_cljs.invoke(api.clj:34)
	at cljs.cli$default_main.invokeStatic(cli.clj:326)
	at cljs.cli$default_main.invoke(cli.clj:299)
	at cljs.cli$null_opt.invokeStatic(cli.clj:394)
	at cljs.cli$null_opt.invoke(cli.clj:391)
	at cljs.cli$main.invokeStatic(cli.clj:612)
	at cljs.cli$main.doInvoke(cli.clj:601)
	at clojure.lang.RestFn.applyTo(RestFn.java:139)
	at clojure.core$apply.invokeStatic(core.clj:659)
	at clojure.core$apply.invoke(core.clj:652)
	at cljs.main$_main.invokeStatic(main.clj:61)
	at cljs.main$_main.doInvoke(main.clj:52)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.lang.Var.applyTo(Var.java:702)
	at clojure.core$apply.invokeStatic(core.clj:657)
	at clojure.main$main_opt.invokeStatic(main.clj:317)
	at clojure.main$main_opt.invoke(main.clj:313)
	at clojure.main$main.invokeStatic(main.clj:424)
	at clojure.main$main.doInvoke(main.clj:387)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.lang.Var.applyTo(Var.java:702)
	at clojure.main.main(main.java:37)


 Comments   
Comment by Mike Fikes [ 21/May/18 2:30 PM ]

This failure was evidently related to the fact that I had a node_modules directory sitting in my home directory. Removing it caused the issue above to go away.

Perhaps this is the result of the processing marching outward (I was in a subdirectory of my home directory). If this is a possibility, maybe the ClojureScript compiler can itself handle this corner case? (Or is this just a user error?)





[CLJS-2762] Insufficient hooks to build tooling around test termination Created: 29/May/18  Updated: 29/May/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None

Approval: Vetted

 Description   

Currently ClojureScript tests cannot communication termination (and thus test failure) to the JVM process. The solution should cover asynchronous test use case.






[CLJS-2765] Git caching creates cljs_deps.js file with relative paths to cache directory on the first try Created: 01/Jun/18  Updated: 02/Jun/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: None

Approval: Screened

 Description   

See CLJS-2763 for code to reproduce



 Comments   
Comment by David Nolen [ 01/Jun/18 1:27 PM ]

Quick fix applied to master for now https://github.com/clojure/clojurescript/commit/cae4792015626ca341e03a4fd9154b6705beba1e

Comment by Mike Fikes [ 02/Jun/18 10:21 AM ]

Trying to reproduce this, using the files in the description of CLJS-2763, I'm getting what may be a completely different error (using 1.10.238, or a JAR built prior to the quick fix above, or a JAR built with current master):

$ clj -m cljs.main -co build.edn -c
Options passed to ClojureScript compiler: {:output-dir "out", :closure-variable-map-out #object[java.io.File 0x747d1932 "out/closure_var.map"], :closure-warnings {:check-types :off, :check-variables :off}, :closure-defines {}, :ups-libs nil, :cache-analysis true, :closure-module-roots [], :modules {:a {:output-to "out/a.js", :entries [demo.a]}, :b {:output-to "out/b.js", :entries [demo.foo.b], :depends-on #{:a}}, :cljs-base {:output-to #object[java.io.File 0x3fc05ea2 "out/cljs_base.js"]}}, :optimizations :none, :ups-foreign-libs [], :closure-property-map-in #object[java.io.File 0x7c891ba7 "out/closure_prop.map"], :verbose true, :aot-cache true, :preloads [process.env], :ignore-js-module-exts [".css"], :output-to "out/main.js", :preamble ["cljs/imul.js"], :closure-property-map-out #object[java.io.File 0x6240651f "out/closure_prop.map"], :stable-names true, :ups-externs nil, :opts-cache "cljsc_opts.edn", :source-map true, :cache-analysis-format :transit, :closure-variable-map-in #object[java.io.File 0x3cf7298d "out/closure_var.map"], :emit-constants nil}
Exception in thread "main" java.lang.IllegalArgumentException: No implementation of method: :-find-sources of protocol: #'cljs.closure/Compilable found for class: nil
	at clojure.core$_cache_protocol_fn.invokeStatic(core_deftype.clj:583)
	at clojure.core$_cache_protocol_fn.invoke(core_deftype.clj:575)
	at cljs.closure$fn__4972$G__4954__4979.invoke(closure.clj:543)
	at cljs.closure$fn__5065.invokeStatic(closure.clj:750)
	at cljs.closure$fn__5065.invoke(closure.clj:714)
	at cljs.closure$fn__4972$G__4954__4979.invoke(closure.clj:543)
	at cljs.closure$fn__5075$fn__5076.invoke(closure.clj:761)
	at clojure.core$map$fn__5583$fn__5584.invoke(core.clj:2734)
	at clojure.core.protocols$iter_reduce.invokeStatic(protocols.clj:49)
	at clojure.core.protocols$fn__7839.invokeStatic(protocols.clj:75)
	at clojure.core.protocols$fn__7839.invoke(protocols.clj:75)
	at clojure.core.protocols$fn__7781$G__7776__7794.invoke(protocols.clj:13)
	at clojure.core$transduce.invokeStatic(core.clj:6804)
	at clojure.core$into.invokeStatic(core.clj:6819)
	at clojure.core$into.invoke(core.clj:6807)
	at cljs.closure$fn__5075.invokeStatic(closure.clj:761)
	at cljs.closure$fn__5075.invoke(closure.clj:714)
	at cljs.closure$fn__4972$G__4954__4979.invoke(closure.clj:543)
	at cljs.closure$build$fn__5831.invoke(closure.clj:2902)
	at cljs.closure$build.invokeStatic(closure.clj:2899)
	at cljs.closure$build.invoke(closure.clj:2808)
	at cljs.build.api$build.invokeStatic(api.clj:208)
	at cljs.build.api$build.invoke(api.clj:189)
	at cljs.cli$default_compile.invokeStatic(cli.clj:485)
	at cljs.cli$default_compile.invoke(cli.clj:445)
	at cljs.cli$compile_opt.invokeStatic(cli.clj:493)
	at cljs.cli$compile_opt.invoke(cli.clj:491)
	at cljs.cli$main.invokeStatic(cli.clj:634)
	at cljs.cli$main.doInvoke(cli.clj:623)
	at clojure.lang.RestFn.applyTo(RestFn.java:139)
	at clojure.core$apply.invokeStatic(core.clj:659)
	at clojure.core$apply.invoke(core.clj:652)
	at cljs.main$_main.invokeStatic(main.clj:61)
	at cljs.main$_main.doInvoke(main.clj:52)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.lang.Var.applyTo(Var.java:702)
	at clojure.core$apply.invokeStatic(core.clj:657)
	at clojure.main$main_opt.invokeStatic(main.clj:317)
	at clojure.main$main_opt.invoke(main.clj:313)
	at clojure.main$main.invokeStatic(main.clj:424)
	at clojure.main$main.doInvoke(main.clj:387)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.lang.Var.applyTo(Var.java:702)
	at clojure.main.main(main.java:37)




[CLJS-2774] cljs.main: load file fails if NPM deps involved Created: 13/Jun/18  Updated: 13/Jun/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: None
Environment:

{:deps {org.clojure/clojurescript {:mvn/version "1.10.238"}}}



 Description   
src/foo/core.cljs
(ns foo.core
  (:require left-pad))

(defn pad [n]
  (left-pad n 10 0))

We pass -d here to work around CLJS-2752 and CLJS-2666.

$ clj -m cljs.main -co '{:npm-deps {:left-pad "1.3.0"} :install-deps true}' -d out -r
cljs.user=> (load-file "foo/core.cljs")
nil
cljs.user=> (dir foo.core)
pad
nil
cljs.user=> (foo.core/pad 3)
ReferenceError: Can't find variable: foo
cljs.user=> (require 'foo.core)

cljs.user=> (foo.core/pad 3)
"0000000003"

Note that load-file fails (even though it can succeed; see CLJS-2753), while require succeeds.






[CLJS-2710] High-arity .apply on spec-instrumented function throws "Invalid arity" error Created: 27/Mar/18  Updated: 15/Jun/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Miikka Koskinen Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

ClojureScript 1.10.238



 Description   

With ClojureScript 1.10.238, if you call .apply with over 21 arguments on a function that has been instrumented with cljs.spec.test.alpha/instrument, you will get an error about invalid arity. This problem does not occur with ClojureScript 1.9.954.

(require '[cljs.spec.alpha :as s] '[cljs.spec.test.alpha :as stest])

(defn my-fun [& args] (prn :args args))
(s/fdef my-fun :args (s/cat :args (s/* any?)))

(.apply my-fun nil (into-array (range 22)))
;; :args (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21)

(stest/instrument)
(.apply my-fun nil (into-array (range 22)))
;; Error: Invalid arity: 22
;;     at Function.G__10112 [as call] (.../cljs/core.js:6798:7)
;;     at Function.cljs.core.MetaFn.apply (.../cljs/core.js:6829:24)
;;     at repl:1:96

Regular apply works as expected.



 Comments   
Comment by David Nolen [ 27/Mar/18 4:40 PM ]

See CLJS-364 & CLJS-365

Comment by A. R [ 28/Mar/18 1:22 AM ]

Some of these are (commented out) but added in the patch for the apply test suit: CLJS-2147

Comment by David Nolen [ 28/Mar/18 10:35 AM ]

Ah great, thanks for the tests.

Comment by David Nolen [ 10/Jun/18 12:28 PM ]

Revisiting this now that I'm working on CLJS-2761, why do we need to support `.apply`? I don't think this was ever promised.





[CLJS-2782] lein test fails if directory has hyphens Created: 16/Jun/18  Updated: 16/Jun/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Master as of https://github.com/clojure/clojurescript/commit/7528dc79fea372fafa365ee80e4568a3af5f1526



 Description   

Create a directory with hyphens in its name, and then clone clojurescript into it and run lein test.

lein test :only cljs.module-processing-tests/commonjs-module-processing-preprocess-symbol

FAIL in (commonjs-module-processing-preprocess-symbol) (module_processing_tests.clj:191)
Processed modules are added to :js-module-index
expected: (= {"React" {:name (absolute-module-path "src/test/cljs/reactJS.js"), :module-type :commonjs}, "Circle" {:name (absolute-module-path "src/test/cljs/Circle.js"), :module-type :commonjs}} (:js-module-index (clojure.core/deref cenv)))
  actual: (not (= {"React" {:name "module$Users$mfikes$Desktop$dir_with_hypens$clojurescript$src$test$cljs$reactJS", :module-type :commonjs}, "Circle" {:name "module$Users$mfikes$Desktop$dir_with_hypens$clojurescript$src$test$cljs$Circle", :module-type :commonjs}} {"React" {:name "module$Users$mfikes$Desktop$dir-with-hypens$clojurescript$src$test$cljs$reactJS", :module-type :commonjs}, "Circle" {:name "module$Users$mfikes$Desktop$dir-with-hypens$clojurescript$src$test$cljs$Circle", :module-type :commonjs}}))

lein test :only cljs.module-processing-tests/es6-module-processing

FAIL in (es6-module-processing) (module_processing_tests.clj:97)
Processed modules are added to :js-module-index
expected: (= {"es6-hello" {:name (absolute-module-path "src/test/cljs/es6_hello.js"), :module-type :es6}} (:js-module-index (clojure.core/deref cenv)))
  actual: (not (= {"es6-hello" {:name "module$Users$mfikes$Desktop$dir_with_hypens$clojurescript$src$test$cljs$es6-hello", :module-type :es6}} {"es6-hello" {:name "module$Users$mfikes$Desktop$dir-with-hypens$clojurescript$src$test$cljs$es6-hello", :module-type :es6}}))

lein test :only cljs.module-processing-tests/test-cljs-1822

FAIL in (test-cljs-1822) (module_processing_tests.clj:162)
Processed modules are added to :js-module-index
expected: (= {"React" {:name (absolute-module-path "src/test/cljs/react-min.js"), :module-type :commonjs}, "Circle" {:name (absolute-module-path "src/test/cljs/Circle-min.js"), :module-type :commonjs}} (:js-module-index (clojure.core/deref cenv)))
  actual: (not (= {"React" {:name "module$Users$mfikes$Desktop$dir_with_hypens$clojurescript$src$test$cljs$react-min", :module-type :commonjs}, "Circle" {:name "module$Users$mfikes$Desktop$dir_with_hypens$clojurescript$src$test$cljs$Circle-min", :module-type :commonjs}} {"React" {:name "module$Users$mfikes$Desktop$dir-with-hypens$clojurescript$src$test$cljs$react-min", :module-type :commonjs}, "Circle" {:name "module$Users$mfikes$Desktop$dir-with-hypens$clojurescript$src$test$cljs$Circle-min", :module-type :commonjs}}))

lein test :only cljs.module-processing-tests/commonjs-module-processing

FAIL in (commonjs-module-processing) (module_processing_tests.clj:71)
Processed modules are added to :js-module-index
expected: (= {"React" {:name (absolute-module-path "src/test/cljs/reactJS.js"), :module-type :commonjs}, "Circle" {:name (absolute-module-path "src/test/cljs/Circle.js"), :module-type :commonjs}} (:js-module-index (clojure.core/deref cenv)))
  actual: (not (= {"React" {:name "module$Users$mfikes$Desktop$dir_with_hypens$clojurescript$src$test$cljs$reactJS", :module-type :commonjs}, "Circle" {:name "module$Users$mfikes$Desktop$dir_with_hypens$clojurescript$src$test$cljs$Circle", :module-type :commonjs}} {"React" {:name "module$Users$mfikes$Desktop$dir-with-hypens$clojurescript$src$test$cljs$reactJS", :module-type :commonjs}, "Circle" {:name "module$Users$mfikes$Desktop$dir-with-hypens$clojurescript$src$test$cljs$Circle", :module-type :commonjs}}))

Perhaps related to CLJS-2703.






[CLJS-1753] cljs.pprint does not print default tagged literals/elements Created: 16/Aug/16  Updated: 29/Mar/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.9.671
Fix Version/s: Next

Type: Defect Priority: Major
Reporter: Miroslav Kubicek Assignee: Unassigned
Resolution: Unresolved Votes: 2
Labels: printing
Environment:

Win 7 64bit


Approval: Vetted

 Description   

Hi there!
I am having troubles making the cljs pretty print (cljs.pprint/pprint) behave the same way as the regular cljs or clj print function when it goes down to tagged elements that are by default used to denote custom records.

See example below - pr, pr-str, print and print-str functions all use the default approach toward creating (edn-like) tagged element for MyRecord and all produce the same result:
#cljs.user.MyRecord{:value "a"}

On the other hand pprint just ignores the record's tag and simply just traverses/prints it as a map:
{:value "a"}

Is there some setting and/or parameter in cljs.pprint namespace I am missing? I looked briefly at the code, but it seems it uses print-str by default - so maybe it just traverses the graph depth-first and does not check for every node's type? At this stage this seems like a bug to me as the expected behavior of the pprint function is that it would behave the same way print and other core functions do.

THIS WORKS:

cljs.user=> (defrecord MyRecord [value])
cljs.user/MyRecord
cljs.user=> (pr (MyRecord. "a"))
#cljs.user.MyRecord{:value "a"}
nil
cljs.user=> (pr-str (MyRecord. "a"))
"#cljs.user.MyRecord{:value \"a\"}"
cljs.user=> (print (MyRecord. "a"))
#cljs.user.MyRecord{:value a}
nil
cljs.user=> (print-str (MyRecord. "a"))
"#cljs.user.MyRecord{:value a}"

BUT THIS DOESN'T:

cljs.user=> (cljs.pprint/pprint (MyRecord. "a"))
{:value "a"}
("{:value \"a\"}\n")
cljs.user=> (with-out-str (cljs.pprint/pprint (MyRecord. "a")))
"{:value \"a\"}\n"

According to github the head revision of the cljs.pprint namespace has not changed since 1.7.28 so I'd assume all versions up to the current one are affected.

Thanks for help!



 Comments   
Comment by David Nolen [ 08/Jul/17 10:10 AM ]

Patch must supply a test case.

Comment by António Nuno Monteiro [ 08/Jul/17 3:13 PM ]

Not sure if this is a bug. Running this at a Clojure REPL produces the same results:

user=> (defrecord MyRecord [value])
user.MyRecord
user=> (require '[clojure.pprint :as pprint])
nil
user=> (pprint/pprint (MyRecord. "a"))
{:value "a"}
nil
Comment by Miroslav Kubicek [ 09/Jul/17 12:23 AM ]

Good catch, that is indeed interesting... but I'd still argue that this is definitely a bug (which just seems to be present in clj as well) - pretty print should work in the same way as print does, only prettier (aka more readable). It should not have its own idiosyncrasies. Every other print function (even including spit) works this way, so I can not imagine what would be the reason (or a use case) for pprint not to honor tagged literals specification of clojure and print things its own way.

Comment by Steve Miner [ 05/Nov/17 8:14 AM ]

There's a new patch for CLJ-1890. If it's accepted for Clojure, it can be ported to CLJS.





[CLJS-2758] Improving tracability of cljs.spec.test instrumented function call conform errors Created: 24/May/18  Updated: 19/Jun/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.10.238
Fix Version/s: None

Type: Enhancement Priority: Major
Reporter: Christian Johansen Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: bug, enhancement, spec

Attachments: Text File 0001-Change-target-to-default-which-indicates-a-browser.patch     Text File 0002-Use-location.hostname-for-port-less-hostname.patch     Text File 0003-Infer-UA-product-for-error-parsing-from-error-stack-.patch     Text File 0004-Correct-namespace-for-locating-caller-in-spec.test.patch    
Patch: Code

 Description   

Context: Use `cljs.spec.test.alpha/instrument` to instrument `fdef`-ed functions. Call one of said functions with data that fails the argument spec. The thrown exception currently does not provide a lot of context:

1. The exception message contains "missing filename" and "missing line number" - ideally those should contain the file and line number of the offending call
2. The exception data is coded to include information about the caller, but the current implementation always yields `nil` here.

The result is that failure to conform to an fdef argument spec leaves no trace back to the call - it only tells you which function's spec was not satiesfied.

I've started to investigate, and found a few glitches, but I do not have a complete suggestion. I'm offering my patches so far, hoping to get some input on whether or not it would be desirable for me to continue investigating.

Here's what I found so far:

1. `target` was assumed to be `"browser"`, while it is documented to be `"default"` in browsers. Fixed in first patch
2. When attempting to parse the stack trace to find the caller, `host` included the port number. Adressed in the second patch
3. When attempting to parse the stack trace, `goog.userAgent.product` is used to determine the browser, but it is not reliable - for example, `product/IPHONE` is true when Chrome is in responsive design mode. This is both incorrect, and helpeless in the case of `cljs.spec.test.alpha`, which does not recognize iphones at all. Because the user agent is only used to parse stack traces, I fixed this by inferring the user agent from the stack trace instead.
4. The `find-caller` function used the wrong package name to find the `spec_checking_fn`. Additionally, it hard-coded the dots in the package name, while some browsers use `$`. I fixed this in the forth patch. I also moved creating the error outside of the `conform!` anonymous function, as placing it here removes `spec-checking-fn` from the stack trace.

With these patches, the caller is set reliably, although it doesn't seem to reflect the originating call-site. Also, the thrown exception still lacks file name and line number. I'd be happy to continue investigating, and add some tests if you are interested in eventually accepting these patches.

As a side-note: It seems to me that the function that infers user agent from stack trace more appropriately belongs in stacktrace.cljs, and I feel strongly that this should be the default behavior when no `user-agent-product` is provided (instead of the current: returning the stack trace string unmodified). I'll be happy to fix this as well, and add some tests, if the interest is there. Note that the current approach allows Safari to go down the Firefox route, which works like a charm.

Lastly: sorry if I put too many things in one place, I'll be happy to split up as instructed.



 Comments   
Comment by David Nolen [ 15/Jun/18 3:52 PM ]

Thanks! Have you submitted a CA?

Comment by Christian Johansen [ 19/Jun/18 4:21 AM ]

I sure have





[CLJS-2785] npm-deps throws errors when using a dependency with es6 modules Created: 19/Jun/18  Updated: 19/Jun/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Moritz Ulrich Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Using npm-deps to specify a dependency on a library with es6 modules causes errors in Google Closure, making the dependency unusable.

Background

rc-time-picker comes as a set of es6 modules in the es/ subfolder as well as "traditional" module.exports in the lib/ subdirectory. The package.json specifies both as module and main respectively (see https://github.com/react-component/time-picker/blob/master/package.json).

Using this in a clojurescript build with npm-deps like the following makes google closure pick the es6 part and later complain about the file mixing goog.provide and es6 modules:

(require '[cljs.build.api :as b])

(b/build ["src/"]
         {:main 'my.app
          :output-to "js/app.js"
          :optimizations :simple
          :npm-deps {"react"          "16.2.0",
                     "react-dom"      "16.2.0",
                     "rc-time-picker" "^3.3.1",}
          :install-deps true})

A simple app.cljs requiring "rc-time-picker" :as ... causes the following errors during compilation:

WARNING: WARNING - File cannot be a combination of goog.provide, goog.module, and/or ES6 module: .../out/node_modules/rc-time-picker/es/Combobox.js
...
ERROR: JSC_LANGUAGE_FEATURE. This language feature is only supported for ECMASCRIPT6 mode or better: modules. at ...out/node_modules/rc-time-picker/es/TimePicker.js line 12 :66
...

Specifying :language-in and :language-out doesn't help.

The error messages are caused by the Clojurescript code which copies the code from node_modules/rc-time-picker/es/ to out/node_modules/rc-time-picker and where it adds various goog.provide statements to the top of the file, while the end of the file is a export default ... statement.






[CLJS-2794] with-meta should return identity when new meta is identical to prior Created: 27/Jun/18  Updated: 27/Jun/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.10.238
Fix Version/s: None

Type: Enhancement Priority: Major
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

For persistent objects, if meta is identical, with-meta should return the identical object rather than replacing meta and returning a new object.

Like CLJ-2362 but for ClojureScript.

For example,

(let [coll ^:foo [1]] 
  (identical? coll (with-meta coll (meta coll))))

now evaluates to true in Clojure 1.10.0-alpha5.

I suspect this can be achieved by updating all of pertinent IWithMeta implementations in cljs.core to be like the following revision for PersistentVector

IWithMeta
  (-with-meta [coll new-meta]
    (if (identical? meta new-meta)
      coll
      (PersistentVector. new-meta cnt shift root tail __hash)))

while also dealing with the trick that vec and set employ when using with-meta to force a new object to be created (see CLJS-2442).






[CLJS-2795] Sorted colls with default comparator don't check that first element is Comparable Created: 27/Jun/18  Updated: 27/Jun/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

{:deps {org.clojure/clojurescript {:mvn/version "1.10.339"}}}



 Description   

Like CLJ-2089 but for ClojureScript.

Repro, with ClojureScript:

$ clj -m cljs.main
ClojureScript 1.10.339
cljs.user=> (def s (sorted-set #{1}))
#'cljs.user/s
cljs.user=> (conj s #{2})
Error: Cannot compare #{2} to #{1}
	 cljs$core$compare (cljs/core.cljs:2380:13)
	 cljs.core/tree-map-add (cljs/core.cljs:28176:3)
	 cljs$core$IAssociative$_assoc$arity$3 (cljs/core.cljs:8734:18)
	 cljs.core/-assoc (cljs/core.cljs:630:17)
	 cljs$core$IFn$_invoke$arity$3 (cljs/core.cljs:1968:8)
	 cljs$core$ICollection$_conj$arity$2 (cljs/core.cljs:9231:31)
	 cljs.core/-conj (cljs/core.cljs:583:16)
	 cljs$core$IFn$_invoke$arity$2 (cljs/core.cljs:1781:8)
	 cljs$core$conj (cljs/core.cljs:1773:1)

If feasible, this ticket asks that ClojureScript be made to align with the solution in CLJ-2089 (in particular, with making code like (sorted-set #{1}) fail fast.)






[CLJS-2792] CraftyJS NPM dependency cannot be imported Created: 25/Jun/18  Updated: 01/Jul/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.10.238
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Marty Glaubitz Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: clojurescript, npm-deps
Environment:

Operation System: Windows 10
Leiningen Version: Leiningen 2.8.1
Java Version: Java 1.8.0_60 Java HotSpot(TM) 64-Bit Server VM
ClojureScript Version: 1.10.238



 Description   

I'm using ClojureScript with Figwheel and trying to use CraftyJs in ClojureScript.
This is my project.clj

(defproject my_project "0.1.0-SNAPSHOT"
:description "FIXME: write this!"
:url "http://example.com/FIXME"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}

:min-lein-version "2.7.1"

:dependencies [[org.clojure/clojure "1.9.0"]
[org.clojure/clojurescript "1.10.238"]
[org.clojure/core.async "0.4.474"]]

:plugins [[lein-figwheel "0.5.16"]
[lein-cljsbuild "1.1.7" :exclusions [[org.clojure/clojure]]]]

:source-paths ["src"]

:cljsbuild {:builds
[{:id "dev"
:source-paths ["src"]

;; The presence of a :figwheel configuration here
;; will cause figwheel to inject the figwheel client
;; into your build
:figwheel {:on-jsload "my_project.core/on-js-reload"
;; :open-urls will pop open your application
;; in the default browser once Figwheel has
;; started and compiled your application.
;; Comment this out once it no longer serves you.
:open-urls ["http://localhost:3449/index.html"]}

:compiler {:main my_project.core
:asset-path "js/compiled/out"
:install-deps true
:npm-deps {:craftyjs "0.8.0"}
:output-to "resources/public/js/compiled/my_project.js"
:output-dir "resources/public/js/compiled/out"
:source-map-timestamp true
;; To console.log CLJS data-structures make sure you enable devtools in Chrome
;; https://github.com/binaryage/cljs-devtools
:preloads [devtools.preload]}}
;; This next build is a compressed minified build for
;; production. You can build this with:
;; lein cljsbuild once min
{:id "min"
:source-paths ["src"]
:compiler {:output-to "resources/public/js/compiled/my_project.js"
:main my_project.core
:optimizations :advanced
:pretty-print false}}]}

:figwheel {;; :http-server-root "public" ;; default and assumes "resources" ;; :server-port 3449 ;; default ;; :server-ip "127.0.0.1" :css-dirs ["resources/public/css"] ;; watch and update CSS ;; Start an nREPL server into the running figwheel process ;; :nrepl-port 7888 ;; Server Ring Handler (optional) ;; if you want to embed a ring handler into the figwheel http-kit ;; server, this is for simple ring servers, if this ;; doesn't work for you just run your own server :) (see lein-ring) ;; :ring-handler hello_world.server/handler ;; To be able to open files in your editor from the heads up display ;; you will need to put a script on your path. ;; that script will have to take a file path and a line number ;; ie. in ~/bin/myfile-opener ;; #! /bin/sh ;; emacsclient -n +$2 $1 ;; ;; :open-file-command "myfile-opener" ;; if you are using emacsclient you can just use ;; :open-file-command "emacsclient" ;; if you want to disable the REPL ;; :repl false ;; to configure a different figwheel logfile path ;; :server-logfile "tmp/logs/figwheel-logfile.log" ;; to pipe all the output to the repl ;; :server-logfile false }

;; Setting up nREPL for Figwheel and ClojureScript dev
;; Please see:
;; https://github.com/bhauman/lein-figwheel/wiki/Using-the-Figwheel-REPL-within-NRepl
:profiles {:dev {:dependencies [[binaryage/devtools "0.9.9"]
[figwheel-sidecar "0.5.16"]
[cider/piggieback "0.3.1"]]
;; need to add dev source path here to get user.clj loaded
:source-paths ["src" "dev"]
;; for CIDER
;; :plugins [[cider/cider-nrepl "0.12.0"]]
:repl-options {:nrepl-middleware [cider.piggieback/wrap-cljs-repl]}
;; need to add the compliled assets to the :clean-targets
:clean-targets ^{:protect false} ["resources/public/js/compiled"
:target-path]}})

However when running lein figwheel i see following in the console:

Compiling build :dev to "resources/public/js/compiled/my_project.js" from ["src"]...
[eval]:85
!id.startsWith(goog;
^^^^

SyntaxError: missing ) after argument list
at createScript (vm.js:74:10)
at Object.runInThisContext (vm.js:116:10)
at Object.<anonymous> ([eval]-wrapper:6:22)
at Module._compile (module.js:624:30)
at evalScript (bootstrap_node.js:480:27)
at startup (bootstrap_node.js:177:9)
at bootstrap_node.js:626:3

Successfully compiled build :dev to "resources/public/js/compiled/my_project.js" in 19.529 seconds.
and i can't import the library from my ClojureScript, i also see this:

Uncaught Error: Undefined nameToPath for craftyjs
at visitNode (base.js:1357)
at Object.goog.writeScripts_ (base.js:1369)
at Object.goog.require [as require_figwheel_backup_] (base.js:706)
at index.html:14
I already tried to manually delete the compiled JS output folder



 Comments   
Comment by Mike Fikes [ 30/Jun/18 7:05 PM ]

Hey Marty,

I think you can't directly use CraftyJS as an NPM dependency with ClojureScript. If you look on the CraftyJS website it shows additionally using Browserify.

Here is what happens if you try to use it as an NPM dep using minimal tooling:

deps.edn
{:deps {org.clojure/clojurescript {:mvn/version "1.10.339"}}}
compiler-opts.edn
{:npm-deps {:craftyjs "0.8.0"}
 :install-deps true}
$ clj -m cljs.main -co compiler-opts.edn -r
ClojureScript 1.10.339
cljs.user=> (require 'craftyjs)
events.js:183
      throw er; // Unhandled 'error' event
      ^

Error: Can't resolve 'fs' in '/Users/mfikes/Desktop/CLJS-2792-npm-deps/node_modules/craftyjs/src/graphics'
    at onError (/Users/mfikes/Desktop/CLJS-2792-npm-deps/node_modules/enhanced-resolve/lib/Resolver.js:61:15)
    at loggingCallbackWrapper (/Users/mfikes/Desktop/CLJS-2792-npm-deps/node_modules/enhanced-resolve/lib/createInnerCallback.js:31:19)
    at runAfter (/Users/mfikes/Desktop/CLJS-2792-npm-deps/node_modules/enhanced-resolve/lib/Resolver.js:158:4)
    at innerCallback (/Users/mfikes/Desktop/CLJS-2792-npm-deps/node_modules/enhanced-resolve/lib/Resolver.js:146:3)
    at loggingCallbackWrapper (/Users/mfikes/Desktop/CLJS-2792-npm-deps/node_modules/enhanced-resolve/lib/createInnerCallback.js:31:19)
    at next (/Users/mfikes/Desktop/CLJS-2792-npm-deps/node_modules/tapable/lib/Tapable.js:252:11)
    at innerCallback (/Users/mfikes/Desktop/CLJS-2792-npm-deps/node_modules/enhanced-resolve/lib/Resolver.js:144:11)
    at loggingCallbackWrapper (/Users/mfikes/Desktop/CLJS-2792-npm-deps/node_modules/enhanced-resolve/lib/createInnerCallback.js:31:19)
    at next (/Users/mfikes/Desktop/CLJS-2792-npm-deps/node_modules/tapable/lib/Tapable.js:249:35)
    at resolver.doResolve.createInnerCallback (/Users/mfikes/Desktop/CLJS-2792-npm-deps/node_modules/enhanced-resolve/lib/DescriptionFilePlugin.js:44:6)

Error: goog.require could not find: craftyjs
	 (goog/base.js:711:20)
	 require (clojure/browser/repl.cljs:226:33)
cljs.user=>

If you look at the CraftyJS code, it has a require('fs') call (which Browserify evidently helps sidestep.)

But, you can easy use CraftyJS as a foreign lib. To do so, set your compiler options instead to be:

compiler-opts.edn
{:foreign-libs [{:file "https://github.com/craftyjs/Crafty/releases/download/0.8.0/crafty.js"
                 :provides ["craftyjs"]}]}

Then, you can drive CraftyJS right from the REPL:

$ clj -m cljs.main -co compiler-opts.edn -r
ClojureScript 1.10.339
cljs.user=> (set! (.-innerHTML (.getElementById js/document "app")) "")
""
cljs.user=> (require 'craftyjs)

cljs.user=> (.init js/Crafty)
#object[Crafty]
cljs.user=> (def player (-> js/Crafty
(.e "2D, Canvas, Color, Fourway")
(.attr #js {:x 100 :y 100 :w 50 :h 50})
(.color "blue")
(.fourway 3)))
#'cljs.user/player
cljs.user=>

After the above, you can control the box using your arrow keys.

Comment by Marty Glaubitz [ 01/Jul/18 9:58 AM ]

Thanks for the tip! But are you sure that

:file "https://github.com/craftyjs/Crafty/releases/download/0.8.0/crafty.js"

is supposed to work? On my windows machine i can only pass a local file path there...

Comment by Mike Fikes [ 01/Jul/18 1:55 PM ]

Hi Marty. Yes :file can be a URL. See https://clojurescript.org/reference/compiler-options#foreign-libs





[CLJS-2809] Using `:foreign-libs` along with `:npm-deps` fails depending on order of requires Created: 06/Jul/18  Updated: 06/Jul/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.10.238
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Garrett Hopper Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: clojurescript
Environment:

Clojure 1.9.0.381
Java 1.8



 Description   
Starting a REPL with both `:npm-deps` and `:foreign-libs`
clj -Sdeps "{:deps {org.clojure/clojurescript {:mvn/version \"1.10.339\"}}}" -m cljs.main -co "{:npm-deps {left-pad \"1.3.0\"} :install-deps true :foreign-libs [{:file \"https://apis.google.com/js/platform.js\" :provides [\"google.api\"] :global-exports {google.api gapi}}]}" -r
Requiring the `:foreign-libs` library after the `:npm-deps` dependency fails
cljs.user=> (require '[left-pad])
cljs.user=> (require '[google.api])
java.io.FileNotFoundException: /home/garrett/https:/apis.google.com/js/platform.js (No such file or directory)
        at java.io.FileInputStream.open0(Native Method)
        at java.io.FileInputStream.open(FileInputStream.java:195)
        at java.io.FileInputStream.<init>(FileInputStream.java:138)
        at java.io.FileInputStream.<init>(FileInputStream.java:93)
        at sun.net.www.protocol.file.FileURLConnection.connect(FileURLConnection.java:90)
        at sun.net.www.protocol.file.FileURLConnection.getInputStream(FileURLConnection.java:188)
        at cljs.util$last_modified.invokeStatic(util.cljc:224)
        at cljs.util$last_modified.invoke(util.cljc:216)
        at cljs.util$changed_QMARK_.invokeStatic(util.cljc:232)
        at cljs.util$changed_QMARK_.invoke(util.cljc:231)
        at cljs.closure$handle_js_modules$fn__5877.invoke(closure.clj:2670)
        at clojure.core$some.invokeStatic(core.clj:2693)
        at clojure.core$some.invoke(core.clj:2684)
        at cljs.closure$handle_js_modules.invokeStatic(closure.clj:2667)
        at cljs.closure$handle_js_modules.invoke(closure.clj:2633)
        at cljs.repl$evaluate_form.invokeStatic(repl.cljc:508)
        at cljs.repl$evaluate_form.invoke(repl.cljc:484)
        at cljs.repl$eval_cljs.invokeStatic(repl.cljc:672)
        at cljs.repl$eval_cljs.invoke(repl.cljc:665)
        at cljs.repl$repl_STAR_$read_eval_print__6536.invoke(repl.cljc:957)
        at cljs.repl$repl_STAR_$fn__6542$fn__6551.invoke(repl.cljc:998)
        at cljs.repl$repl_STAR_$fn__6542.invoke(repl.cljc:997)
        at cljs.compiler$with_core_cljs.invokeStatic(compiler.cljc:1285)
        at cljs.compiler$with_core_cljs.invoke(compiler.cljc:1274)
        at cljs.repl$repl_STAR_.invokeStatic(repl.cljc:960)
        at cljs.repl$repl_STAR_.invoke(repl.cljc:839)
        at cljs.cli$repl_opt.invokeStatic(cli.clj:290)
        at cljs.cli$repl_opt.invoke(cli.clj:277)
        at cljs.cli$main.invokeStatic(cli.clj:612)
        at cljs.cli$main.doInvoke(cli.clj:601)
        at clojure.lang.RestFn.applyTo(RestFn.java:139)
        at clojure.core$apply.invokeStatic(core.clj:659)
        at clojure.core$apply.invoke(core.clj:652)
        at cljs.main$_main.invokeStatic(main.clj:61)
        at cljs.main$_main.doInvoke(main.clj:52)
        at clojure.lang.RestFn.applyTo(RestFn.java:137)
        at clojure.lang.Var.applyTo(Var.java:702)
        at clojure.core$apply.invokeStatic(core.clj:657)
        at clojure.main$main_opt.invokeStatic(main.clj:317)
        at clojure.main$main_opt.invoke(main.clj:313)
        at clojure.main$main.invokeStatic(main.clj:424)
        at clojure.main$main.doInvoke(main.clj:387)
        at clojure.lang.RestFn.applyTo(RestFn.java:137)
        at clojure.lang.Var.applyTo(Var.java:702)
        at clojure.main.main(main.java:37)
Requiring the `:foreign-libs` library before the `:npm-deps` dependency works
cljs.user=> (require '[google.api])
cljs.user=> (require '[left-pad])


 Comments   
Comment by David Nolen [ 06/Jul/18 1:18 PM ]

It seems the issue here might not be one of order but of mishandling `:file` entries that use URLs.





[CLJS-364] compiler needs to put all args of an invocation after 20 into an array-seq Created: 29/Aug/12  Updated: 09/Jul/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

This ticket is related to CLJS-359






[CLJS-2823] Private var use not detected in multi-arity defn Created: 15/Jul/18  Updated: 15/Jul/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

{:deps {org.clojure/clojurescript {:git/url "https://github.com/clojure/clojurescript" :sha "17b71461ee6304e3696e397add1f4780525553fc"}}}



 Description   

Note that the last form in the repro below does not emit a diagnostic, while the previous does:

$ clj -Srepro -m cljs.main
cljs.user=> (defn- foo [])
#'cljs.user/foo
cljs.user=> (ns bar.core)

bar.core=> (defn baz ([] (cljs.user/foo)))
WARNING: var: cljs.user/foo is not public at line 1 <cljs repl>
#'bar.core/baz
bar.core=> (defn quux ([] (cljs.user/foo)) ([x] (cljs.user/foo)))
#'bar.core/quux
bar.core=>





[CLJS-2826] Add arglist annotations in cljs.core Created: 15/Jul/18  Updated: 15/Jul/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Major
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: None


 Description   

With CLJS-1871 we have the ability to annotate declared fns with arglists, with proper static dispatch resulting.

The declares in cljs.core are currently not annotated (and for now are not strictly needed because of double analysis that occurs of cljs.core, but it would be nice to add those annotations because double-analysis may not always be the way things are done.






[CLJS-2399] :foreign-libs with module conversion does not works properly (possible regression) Created: 16/Nov/17  Updated: 24/Jul/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.9.854, 1.9.908
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Andrey Antukh Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: None
Environment:

OpenJDK 8, Linux, node-v8.7.0



 Description   

This is the same issue as https://dev.clojure.org/jira/browse/CLJS-1682, so all the instructions for reproduce the error can be found in the referenced issue.

Here some specific details of the different errors on different cljs versions:

With `cljs==1.9.845` the compilation terminates successfully in both cases (`:foreign-libs` in `build.clj` and in `deps.cljs`) but on executing the generated javascript, an exception is raised:

$ node out/main.js                            
out/src/vendor/greeter.js:3
exports.sayHello = function(name) {
                 ^

TypeError: Cannot set property 'sayHello' of undefined
    at out/src/vendor/greeter.js:3:18
    at ContextifyScript.Script.runInThisContext (vm.js:50:33)
    at Object.runInThisContext (vm.js:139:38)
    at Object.nodeGlobalRequire (/home/niwi/tmp/greeter/out/goog/bootstrap/nodejs.js:85:8)
    at Object.cljs$core$load_file [as load_file] (/home/niwi/tmp/greeter/out/cljs/core.js:341:13)
    at Object.<anonymous> (/home/niwi/tmp/greeter/out/testapp/core.js:5:11)
    at Module._compile (module.js:624:30)
    at Object.Module._extensions..js (module.js:635:10)
    at Module.load (module.js:545:32)
    at tryModuleLoad (module.js:508:12)

With `cljs==1.9.908` the compilation terminates successfully in both cases but on executing the generated javascript and other exception is raised:

$ node out/main.js                            
/home/niwi/tmp/greeter/out/testapp/core.js:28
return cljs.core.println.call(null,module$src$vendor$greeter.sayHello("Ciri"));
                                                             ^

TypeError: module$src$vendor$greeter.sayHello is not a function
    at Function.testapp.core._main.cljs$core$IFn$_invoke$arity$variadic (/home/niwi/tmp/greeter/out/testapp/core.js:28:62)
    at testapp$core$_main (/home/niwi/tmp/greeter/out/testapp/core.js:24:27)
    at Object.cljs$core$apply_to [as apply_to] (/home/niwi/tmp/greeter/out/cljs/core.js:12793:81)
    at Function.cljs.core.apply.cljs$core$IFn$_invoke$arity$2 (/home/niwi/tmp/greeter/out/cljs/core.js:13237:18)
    at cljs$core$apply (/home/niwi/tmp/greeter/out/cljs/core.js:13195:24)
    at Object.<anonymous> (/home/niwi/tmp/greeter/out/DF0FC10.js:9:17)
    at Module._compile (module.js:624:30)
    at Object.Module._extensions..js (module.js:635:10)
    at Module.load (module.js:545:32)
    at tryModuleLoad (module.js:508:12)

And with `cljs==1.9.946`, using the `:foreign-libs` in the `build.clj` file, the following error is raised:

$ java -cp cljs.jar:src clojure.main build.clj 
module.js:529
    throw err;
    ^

Error: Cannot find module '@cljs-oss/module-deps'
    at Function.Module._resolveFilename (module.js:527:15)
    at Function.Module._load (module.js:476:23)
    at Module.require (module.js:568:17)
    at require (internal/module.js:11:18)
    at [eval]:3:13
    at ContextifyScript.Script.runInThisContext (vm.js:50:33)
    at Object.runInThisContext (vm.js:139:38)
    at Object.<anonymous> ([eval]-wrapper:6:22)
    at Module._compile (module.js:624:30)
    at evalScript (bootstrap_node.js:462:27)

Copying file:/home/niwi/tmp/greeter/src/vendor/greeter.js to out/src/vendor/greeter.js
Copying jar:file:/home/niwi/tmp/greeter/cljs.jar!/cljs/core.cljs to out/cljs/core.cljs
Reading analysis cache for jar:file:/home/niwi/tmp/greeter/cljs.jar!/cljs/core.cljs
Compiling out/cljs/core.cljs
[...]

Independently of the error, the compilation continues and terminates, and the generated javascript raises the following error (very similat to the error with cljs==1.9.908):

$ node out/main.js                                                                 
/home/niwi/tmp/greeter/out/testapp/core.js:28
return cljs.core.println.call(null,module$home$niwi$tmp$greeter$src$vendor$greeter.sayHello("Ciri"));
                                                                                   ^

TypeError: module$home$niwi$tmp$greeter$src$vendor$greeter.sayHello is not a function
    at Function.testapp.core._main.cljs$core$IFn$_invoke$arity$variadic (/home/niwi/tmp/greeter/out/testapp/core.js:28:84)
    at testapp$core$_main (/home/niwi/tmp/greeter/out/testapp/core.js:24:27)
    at Object.cljs$core$apply_to [as apply_to] (/home/niwi/tmp/greeter/out/cljs/core.js:12785:81)
    at Function.cljs.core.apply.cljs$core$IFn$_invoke$arity$2 (/home/niwi/tmp/greeter/out/cljs/core.js:13229:18)
    at cljs$core$apply (/home/niwi/tmp/greeter/out/cljs/core.js:13187:24)
    at Object.<anonymous> (/home/niwi/tmp/greeter/out/AEF573C.js:10:17)
    at Module._compile (module.js:624:30)
    at Object.Module._extensions..js (module.js:635:10)
    at Module.load (module.js:545:32)
    at tryModuleLoad (module.js:508:12)

In case of setting the `:foreign-lib` in the `deps.cljs` file, the compilation terminates without error but the generated javascript raises the same error as with `cljs==1.9.845`.



 Comments   
Comment by Bobby Calderwood [ 24/Jul/18 2:45 PM ]

I can confirm this issue persists in version 1.10.339. I had to `npm install --save @cljs-oss/module-deps` in order to use `:foreign-libs` with `:module-type :es6`. I had no `:npm-deps`, so this seemed an unintuitive extra step.





[CLJS-2331] Extend :global-exports to auto-alias and rewrite occurrences of declared globals Created: 18/Aug/17  Updated: 06/Jun/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.9.908
Fix Version/s: Next

Type: Enhancement Priority: Major
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: foreign-libs, global-exports

Approval: Accepted

 Description   

In order to lower the barrier to adopting `:npm-deps` we could push `:global-exports` a bit further. Instead of just using it to support foreign-libs, we can also use it to automatically make libraries node_modules compatible. This can be done by auto generating a namespace alias if not provided and rewriting global access for matching symbols. Some libs may refer to globals without explicit requires and we should warn in that case.






[CLJS-2818] Support `export ... from ...` syntax Created: 12/Jul/18  Updated: 18/Jul/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.10.238
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Corin Lawson Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Affects: 1.9.1033+

I have a minimal repro repo here: https://github.com/au-phiware/cljs-2818

Description of problem

Prior to the update to Closure compiler in CLJS-2389, ES6 modules that used the {{export { x as y } from './x'}} or {{export { default as y } from './x'}} syntax compiled correctly. Other forms of this syntax, such as {{export { default } from './x'}}, did not.

Since 1.9.1033, the compiler no longer emits the goog.require statements nor does it emit a complete set of goog.addDependency statements in cljs_deps.js.

Steps to reproduce the problem

Consider the following source files:

src/foo/core.cljs
(ns foo.core (:require [hello :refer [helloGreet]]))                                 

(def ^:export sayHello
    (helloGreet "World"))

(sayHello)
es6/hello.js
export {
    default as helloGreet
} from "./greet";
es6/greet.js
export default function greet(m) {
    document.write("\nHello, " + m);
};
build.clj
(require 'cljs.build.api)

(cljs.build.api/build
  "src"
  {:main 'foo.core
   :output-to "target/main.js"
   :output-dir "target/main.out"
   :asset-path "main.out"
   :foreign-libs [{:file "es6/hello.js"
                   :provides ['hello]
                   :module-type :es6}]
   :verbose true
   :npm-deps {"@cljs-oss/module-deps" "*"}
   :install-deps true})

Execute cljs:

java -cp cljs.jar:src clojure.main build.clj

Expected outcome

cljs should exit cleanly and write the following files (approximately).

target/main.out/cljs_deps.js
goog.addDependency("base.js", ['goog'], []);
goog.addDependency("../cljs/core.js", ['cljs.core'], ['goog.string', 'goog.Uri', 'goog.object', 'goog.math.Integer', 'goog.string.StringBuffer', 'goog.array', 'goog.math.Long']);
goog.addDependency("../process/env.js", ['process.env'], ['cljs.core']);
goog.addDependency("../es6/greet.js", ['module$usr$src$es6$greet'], []);
goog.addDependency("../es6/hello.js", ['module$usr$src$es6$hello'], ['module$usr$src$es6$greet']);
goog.addDependency("../foo/core.js", ['foo.core'], ['cljs.core', 'module$usr$src$es6$hello']);
target/main.out/es6/hello.js
goog.provide("module$usr$src$es6$hello");
goog.require("module$usr$src$es6$greet");
module$usr$src$es6$hello.helloGreet=module$usr$src$es6$greet["default"]

Actual outcome

The cljs_deps.js is missing the es6/greet.js dependency:

target/main.out/cljs_deps.js
goog.addDependency("base.js", ['goog'], []);
goog.addDependency("../cljs/core.js", ['cljs.core'], ['goog.string', 'goog.Uri', 'goog.object', 'goog.math.Integer', 'goog.string.StringBuffer', 'goog.array', 'goog.math.Long']);
goog.addDependency("../process/env.js", ['process.env'], ['cljs.core']);
goog.addDependency("../es6/hello.js", ['module$usr$src$es6$hello'], []);
goog.addDependency("../foo/core.js", ['foo.core'], ['cljs.core', 'module$usr$src$es6$hello']);

And the es6/hello.js file is missing the goog.requires statement:

target/main.out/es6/hello.js
goog.provide("module$usr$src$es6$hello");
var module$usr$src$es6$hello={get helloGreet(){return module$usr$src$es6$greet["default"]}}

Furthermore, the browser console shows:

>>> module$usr$src$es6$hello.helloGreet
hello.js:2 Uncaught ReferenceError: module$usr$src$es6$greet is not defined
    at Object.get helloGreet [as helloGreet] (hello.js:2)
    at <anonymous>:1:65

Attempted workaround

Explicitly adding the :requires option to es6/hello.js :foreign-libs entry did not remedy the problem (nor did using an entry for the whole es6 directory or using an npm module, e.g. d3-scale). Neither did adding [greet] to foo.core's requires.



 Comments   
Comment by Corin Lawson [ 18/Jul/18 4:59 AM ]

This appears to be an issue upstream in the Google Closure Compiler...

Comment by Corin Lawson [ 18/Jul/18 6:09 AM ]

The sample same es6 code compiles just fine with gcc, using java -jar $JAR -O WHITESPACE_ONLY --js_output_file=/dev/stdout -W VERBOSE --module_resolution NODE greet.js hello.js. But when cljs calls upon gcc to convert the es6 code the resulting source is missing the goog.require statement... could it be the module_resolution?

Comment by Corin Lawson [ 18/Jul/18 6:52 AM ]

I've noticed that gcc with -O BUNDLE --dependency_mode STRICT fails to emit the greet dep... getting a little confused at this point...

Comment by Corin Lawson [ 18/Jul/18 7:32 PM ]

If I apply this patch to gcc, then it will detect the correct requires of hello.js

diff --git a/src/com/google/javascript/jscomp/CompilerInput.java b/src/com/google/javascript/jscomp/CompilerInput.java
index 62609562b..4e4d3e3dc 100644
--- a/src/com/google/javascript/jscomp/CompilerInput.java
+++ b/src/com/google/javascript/jscomp/CompilerInput.java
@@ -285,7 +285,7 @@ public class CompilerInput extends DependencyInfo.Base implements SourceAst {
 
     // If the code is a JsAst, then it was originally JS code, and is compatible with the
     // regex-based parsing of JsFileParser.
-    if (ast instanceof JsAst && JsFileParser.isSupported()) {
+    if (false && ast instanceof JsAst && JsFileParser.isSupported()) {
       // Look at the source code.
       // Note: it's OK to use getName() instead of
       // getPathRelativeToClosureBase() here because we're not using

But now cljs thinks that greet should be named "module$usr$src$greet" instead of "module$usr$src$es6$greet", but this also seems to be a gcc bug.

Comment by Corin Lawson [ 18/Jul/18 9:29 PM ]

See https://github.com/google/closure-compiler/pull/3026





[CLJS-2850] Support webpack node lib replacements Created: 29/Jul/18  Updated: 29/Jul/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Major
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: None
Environment:

{:deps {org.clojure/clojurescript {:mvn/version "1.10.339"}}}



 Description   
$ clj -m cljs.main -co '{:npm-deps {"readable-stream" "2.3.6"} :install-deps true}' -r
ClojureScript 1.10.339
cljs.user=> (require 'readable-stream)
events.js:183
      throw er; // Unhandled 'error' event
      ^

Error: module not found: "util" from file /private/tmp/node_modules/readable-stream/lib/_stream_readable.js
    at onresolve (/private/tmp/node_modules/@cljs-oss/module-deps/index.js:181:30)
    at onResolve (/private/tmp/node_modules/enhanced-resolve/lib/Resolver.js:70:11)
    at innerCallback (/private/tmp/node_modules/enhanced-resolve/lib/Resolver.js:143:22)
    at callbackWrapper (/private/tmp/node_modules/enhanced-resolve/lib/createInnerCallback.js:10:21)
    at next (/private/tmp/node_modules/tapable/lib/Tapable.js:249:35)
    at innerCallback (/private/tmp/node_modules/enhanced-resolve/lib/Resolver.js:143:22)
    at callbackWrapper (/private/tmp/node_modules/enhanced-resolve/lib/createInnerCallback.js:10:21)
    at next (/private/tmp/node_modules/tapable/lib/Tapable.js:249:35)
    at resolver.doResolve.createInnerCallback (/private/tmp/node_modules/enhanced-resolve/lib/DescriptionFilePlugin.js:41:24)
    at callbackWrapper (/private/tmp/node_modules/enhanced-resolve/lib/createInnerCallback.js:10:21)

Error: goog.require could not find: readable_stream
	 (goog/base.js:711:20)
	 require (clojure/browser/repl.cljs:226:33)
cljs.user=>

Evidently related to https://github.com/webpack/node-libs-browser



 Comments   
Comment by Mike Fikes [ 29/Jul/18 3:33 PM ]

I wonder if this is a matter of getting Closure's support for Webpack to work for this case. (https://github.com/google/closure-compiler/commit/d0867871bbcbba44eedcb94ed2fbdab661067f42)





[CLJS-2810] Support `:foreign-libs` without `:file` to allow use of `:global-exports` already provided by the webpage Created: 06/Jul/18  Updated: 06/Jul/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Major
Reporter: Garrett Hopper Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: clojurescript


 Description   

It would be useful to be able to use `:foreign-libs` even when a library is already globally available on a page.

<script src="https://apis.google.com/js/platform.js"></script>
{:foreign-libs
 [{:provides ["google.api"]
   :global-exports {google.api gapi}}]}





[CLJS-2856] Transitive foreign libs not loaded in non-browser REPLs Created: 05/Aug/18  Updated: 05/Aug/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

{:deps {org.clojure/clojurescript {:mvn/version "1.10.339"}}}



 Description   
mylib.js
mylib = { abc: 3 }
other.js
other = { def: 17 }
co.edn
{:foreign-libs [{:file "mylib.js"
                 :provides ["my-lib"]
                 :requires ["other-lib"]}
                {:file "other.js"
                 :provides ["other-lib"]}]}

Working, with browser REPL:

$ clj -m cljs.main -co co.edn -r
ClojureScript 1.10.339
cljs.user=> (require 'my-lib)

cljs.user=> js/other
#js {:def 17}

Faling with Node:

$ clj -m cljs.main -co co.edn -re node -r
ClojureScript 1.10.339
cljs.user=> (require 'my-lib)
nil
cljs.user=> js/other
repl:13
throw e__6464__auto__;
^

ReferenceError: other is not defined
...





[CLJS-2860] Suppress warnings for qualified references to transitively loaded Closure libs Created: 11/Aug/18  Updated: 11/Aug/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Major
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

{:deps {org.clojure/clojurescript {:mvn/version "1.10.339"}}}



 Description   

This ticket asks that analyzer warnings be suppressed when using transitively loaded Closure libs via qualified references.

co.edn
{:libs ["libs/mylib.js"]}
libs/mylib.js
goog.provide('my_lib.core')

my_lib.core = {
  add: function(x, y) { return x + y; }
}
src/foo/core.cljs
(ns foo.core
 (:require my-lib.core
           clojure.set))

Here is an example illustrating the concept:

$ clj -m cljs.main -co co.edn -re node -r
ClojureScript 1.10.339
cljs.user=> (clojure.set/intersection #{1 2 3} #{2 4 5})
WARNING: Use of undeclared Var clojure.set/intersection at line 1 <cljs repl>
...
cljs.user=> (require 'foo.core)
nil
cljs.user=> (clojure.set/intersection #{1 2 3} #{2 4 5})
#{2}
cljs.user=> (clojure.set/intersection)
WARNING: Wrong number of args (0) passed to clojure.set/intersection at line 1 <cljs repl>
cljs.user=> (my-lib.core/add 2 3)
WARNING: No such namespace: my-lib.core, could not locate my_lib/core.cljs, my_lib/core.cljc, or JavaScript source providing "my-lib.core" (Please check that namespaces with dashes use underscores in the ClojureScript file name) at line 1 <cljs repl>
WARNING: Use of undeclared Var my-lib.core/add at line 1 <cljs repl>
5
cljs.user=> (in-ns 'foo.core)
nil
foo.core=> (my-lib.core/add 2 3)
5

In the above, you can see that when a transitively loaded ClojureScript namespace (in this example clojure.set) is used via qualified symbols, the analyzer works properly.

This characteristic evidently doesn't currently apply to Closure libs, so (correctly functioning) source code would need to be revised in this example simply in order to avoid analyzer warnings (and the source code would need to be aware that a namespace is implemented by a Closure lib instead of a ClojureScript namespace).

The argument for this enhancement is that it leads to consistency and make it possible to cleanly use Closure libs in valid scenarios where transitive dependencies are used. (Normally it is a bad idea to not directly indicate your dependencies in a given namespace, but an arguably copacetic use is when you are using a namespace that exposes macros that expand to use code that the namespace transitively loads. This could occur, for example with macros that want to use libs defined via :libs or even libs in Closure Library.)






[CLJS-2863] Need to reject incorrect fn with fixed arity of more params than variadic Created: 18/Aug/18  Updated: 18/Aug/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   
ClojureScript 1.10.339
cljs.user=> (defn foo ([x] [:single x]) ([& xs] [:variadic xs]))
#'cljs.user/foo
cljs.user=> (foo 1)
[:single 1]
cljs.user=> (foo 1 2)
[:variadic 1]

Note that the variadic call provides the wrong answer.

It appears that the right thing to do is not "make it work" but to reject the code as incorrect. See Clojure:

user=> (defn foo ([x] [:single x]) ([& xs] [:variadic xs]))
CompilerException java.lang.RuntimeException: Can't have fixed arity function with more params than variadic function, compiling:(NO_SOURCE_PATH:1:1)





[CLJS-2870] Wrong provides/requires for ES6 modules with index.js Created: 21/Aug/18  Updated: 21/Aug/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Gary Verhaegen Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

macOS 10.13.6, java 1.8.0_161



 Description   

This is related to CLJS-2205 and CLJS-2836, though I believe it is slightly different and I have additional (hopefully useful) information to provide.

The "semantic-ui-react" node module, when used as an npm-deps, produces code that fails to load. Minimal reproducing case I could come up with:

build_opts.edn
{:npm-deps {:react "16.2.0"
            :react-dom "16.2.0"
            :semantic-ui-react "0.82.2"}
 :install-deps true}
deps.edn
{:deps {org.clojure/clojurescript {:mvn/version "1.10.339"}}}

Note: I see exactly the same issue with current master, which at the time of writing is commit 81a1ea12 installing locally as 1.10.394.

src/hello_world/core.cljs
(ns hello-world.core
  (:require semantic-ui-react))
 
(println "Hello world!")

Files organized as:

$ tree
.
├── build_opts.edn
├── deps.edn
└── src
    └── hello_world
        └── core.cljs

Running:

clj -m cljs.main -co build_opts.edn -c hello-world.core

produces code that fails to load in the following way. First, modules that have an index.js file seem to be missing a provide statement; for example:

out/node_modules/semantic-ui-react/dist/es/addons/Confirm/index.js
goog.provide("module$Users$gary$sparrho$cljs_bug_report$node_modules$semantic_ui_react$dist$es$addons$Confirm$index");
goog.provide("module$semantic_ui_react$dist$es$addons$Confirm$index");
goog.provide("module$semantic_ui_react$dist$es$addons$Confirm");
goog.require("module$Users$gary$sparrho$cljs_bug_report$node_modules$semantic_ui_react$dist$es$addons$Confirm$Confirm");
var module$Users$gary$sparrho$cljs_bug_report$node_modules$semantic_ui_react$dist$es$addons$Confirm$index={get default(){return module$Users$gary$sparrho$cljs_bug_report$node_modules$semantic_ui_react$dist$es$addons$Confirm$Confirm["default"]}}

gets required elsewhere as the "full path" without the final "index":

out/node_modules/semantic-ui-react/dist/es/index.js (elided)
...
goog.require("module$Users$gary$sparrho$cljs_bug_report$node_modules$semantic_ui_react$dist$es$addons$Confirm");
...

which produces an error saying that nameToPath cannot find the module "module$Users$gary$sparrho$cljs_bug_report$node_modules$semantic_ui_react$dist$es$addons$Confirm". I managed to fix that by patching the ClojureScript compiler (adding the additional goog.provides to cljs.closure/add-converted-source if the current source ends in index, mirroring the patch in CLJS-2205), only to find out that there is a second problem (which makes me doubt my approach is the proper way to fix this) in that the code produced actually then goes and tries to use the module with its full name, including the index part:

out/node_modules/semantic-ui-react/dist/es/index.js (elided)
...
goog.require("module$Users$gary$sparrho$cljs_bug_report$node_modules$semantic_ui_react$dist$es$addons$Confirm");
...
var module$Users$gary$sparrho$cljs_bug_report$node_modules$semantic_ui_react$dist$es$index={get Confirm(){return module$Users$gary$sparrho$cljs_bug_report$node_modules$semantic_ui_react$dist$es$addons$Confirm$index["default"]},
...

which throws an error saying that the variable module$Users$gary$sparrho$cljs_bug_report$node_modules$semantic_ui_react$dist$es$addons$Confirm$index is not defined.

I am completely unfamiliar with all of the ClojureScript compiler, the Google Closure compiler or the ES6 module system, which makes it very hard for me to investigate further. I have verified that at the point of generating the requires and provides calls (cljs.closure/add-converted-source) the Closure object representing the dependencies does not contain the index part at the end, which is consistent with the goog.requires calls that are generated. The goog.provides calls seem to be generated independently of the Closure compiler, based on analysis of the js files done in src/main/cljs/cljs/module_deps.js. What I cannot figure out (and therefore where I am blocked) is what piece of code generates the JS code that tries to access the "wrong" variable name. Maybe this is a bug in ClojureScript not generating the right goog.requires calls, or maybe this is a bug in Closure not using the same name for the JS variables as the symbols it generates on its Require objects.






[CLJS-2899] The :testing-contexts value does not survive async macro Created: 09/Sep/18  Updated: 09/Sep/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Andrea Richiardi Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

It seems like the :testing-contexts is not preserved in the test environment after (or within better) a `cljs.test/async` test.

Repro:

cljs.user=> (require '[cljs.test :as test :refer-macros [deftest is testing async]])
cljs.user=> (deftest test-testing-contexts
       #_=>   (testing "not there"
       #_=>     (async done
       #_=>            (js/setTimeout #(do (is (= 0 1))
       #_=>                                (done))))))

cljs.user=> (test/test-var #'cljs.user/test-testing-contexts)
#object[Object]
cljs.user=> 
FAIL in (test-testing-contexts) (at applyHandler (<eval>:NaN:28)
expected: (= 0 1)
  actual: (not (= 0 1))

I have also inspected, using test/testing-contexts-str, the env before and after async and:

cljs.user=> (deftest test-testing-contexts
       #_=>   (testing "not there"
       #_=>     (println "outside ->" (test/testing-contexts-str))
       #_=>     (async done
       #_=>            (println "inside -> " (test/testing-contexts-str))
       #_=>            (js/setTimeout #(do (is (= 0 1))
       #_=>                                (done))))))

cljs.user=> (test/test-var #'cljs.user/test-testing-contexts)
outside -> not there
inside ->  
#object[Object]
cljs.user=> 
FAIL in (test-testing-contexts) (at applyHandler (<eval>:NaN:28)
expected: (= 0 1)
  actual: (not (= 0 1))





[CLJS-2738] Can't use aws-amplify or aws-sdk with npm-deps Created: 15/Apr/18  Updated: 09/Aug/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Quang Van Assignee: Unassigned
Resolution: Unresolved Votes: 5
Labels: npm-deps


 Description   

If I put aws-amplify in :npm-deps it seems to require aws-sdk, but when I put aws-sdk in there, it outputs this error:

Compiling build :dev to "resources/public/js/main.js" from ["src"]...
events.js:182
      throw er; // Unhandled 'error' event
      ^

Error: module not found: "fs" from file /home/quang/dev/org-re-frame/node_modules/aws-amplify/node_modules/aws-sdk/lib/util.js
    at onresolve (/home/quang/dev/org-re-frame/node_modules/@cljs-oss/module-deps/index.js:181:30)
    at onResolve (/home/quang/dev/org-re-frame/node_modules/enhanced-resolve/lib/Resolver.js:70:11)
    at innerCallback (/home/quang/dev/org-re-frame/node_modules/enhanced-resolve/lib/Resolver.js:143:22)
    at callbackWrapper (/home/quang/dev/org-re-frame/node_modules/enhanced-resolve/lib/createInnerCallback.js:10:21)
    at next (/home/quang/dev/org-re-frame/node_modules/tapable/lib/Tapable.js:249:35)
    at innerCallback (/home/quang/dev/org-re-frame/node_modules/enhanced-resolve/lib/Resolver.js:143:22)
    at callbackWrapper (/home/quang/dev/org-re-frame/node_modules/enhanced-resolve/lib/createInnerCallback.js:10:21)
    at next (/home/quang/dev/org-re-frame/node_modules/tapable/lib/Tapable.js:249:35)
    at resolver.doResolve.createInnerCallback (/home/quang/dev/org-re-frame/node_modules/enhanced-resolve/lib/DescriptionFilePlugin.js:41:24)
    at callbackWrapper (/home/quang/dev/org-re-frame/node_modules/enhanced-resolve/lib/createInnerCallback.js:10:21)


 Comments   
Comment by Jeffrey Stanton [ 26/Apr/18 2:51 PM ]

I've also run into the same issue. Here's a simple repro:

deps.edn
{:deps {org.clojure/clojurescript {:mvn/version "1.10.238"}}}
src/foo.cljs
(ns foo (:require ["aws-sdk" :as sdk]))
(defn -main [] (println "hello world"))

then run:

$ clj -m cljs.main -co '{:install-deps true, :npm-deps {:aws-sdk "2.229.1"}}' -m foo
...
Error: module not found: "fs" from file /Users/jeff/repro/node_modules/aws-sdk/lib/util.js
    at onresolve (/Users/jeff/repro/node_modules/@cljs-oss/module-deps/index.js:181:30)
    at onResolve (/Users/jeff/repro/node_modules/enhanced-resolve/lib/Resolver.js:70:11)
    at innerCallback (/Users/jeff/repro/node_modules/enhanced-resolve/lib/Resolver.js:143:22)
    at callbackWrapper (/Users/jeff/repro/node_modules/enhanced-resolve/lib/createInnerCallback.js:10:21)
    ...
Comment by Mike Fikes [ 05/May/18 7:35 PM ]

The big picture is not completely clear to me for this one, but it appears that the NPM version of the library is not intended to be used directly from the browser runtime, and instead you need to build it so that it is packaged for the browser.

The root problem is that the code is attempting to use Node's fs code, but from the browser.

You can see that the code can be compiled and executed if you target Node: If you modify Jeffrey's minimal repro to add

(set! *main-cli-fn* -main)

to the bottom of src/foo.cljs then things will compile and execute in Node:

$ clj -m cljs.main -co '{:install-deps true, :npm-deps {:aws-sdk "2.229.1"}}' -O simple -o main.js -t node -c foo
WARNING: foo is a single segment namespace at line 1 /private/tmp/aws/src/foo.cljs
$ node main.js
hello world

For the browser case, if you look at the code in node_modules/aws-sdk/lib/util.js you can see that it has conditional branches for browser use, but I suspect that this is intended to be used as described here https://github.com/aws/aws-sdk-js#in-the-browser but if you really want to use the code directly from its NPM dependency, you have to use that NPM dependency to build the JavaScript intended to be used in the browser as detailed here: https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/building-sdk-for-browsers.html

If this can be confirmed, then this issue can be resolved as a non-issue, and it is just a matter of correct use of the library.

Comment by David Whittington [ 05/May/18 8:23 PM ]

I can confirm that it works in the browser with the AWS recommended browser build process. I was hoping it would also work as a node dep, but I think you're probably right that it's just not intended to be used that way.

Comment by Christian Paul Dehli [ 09/Aug/18 9:55 PM ]

So adding `aws-sdk` the recommended way does work, however there are many AWS packages that pull in `aws-sdk` as a dependency. One example is https://github.com/awslabs/aws-mobile-appsync-sdk-js/tree/master/packages/aws-appsync. This means that these packages won't run in ClojureScript because they throw the same error as above. I have confirmed that in a regular JavaScript project, `aws-sdk` is added correctly (an example is here: https://github.com/aws-samples/aws-mobile-appsync-events-starter-react/).

Like Mike said, it looks to be coming from this line in the code: https://github.com/aws/aws-sdk-js/blob/ebe83921863f1eb020b6a07ef471f2017cd58550/lib/util.js#L39. process.browser is what's indicating to aws-sdk whether or not it's a browser environment.

My guess would be if we set `process.browser` to true for when building to non-node environments it would solve this problem (https://nolanlawson.com/2017/01/09/how-to-write-a-javascript-package-for-both-node-and-the-browser/)





[CLJS-2902] Warn on type hint mismatch with inferred Created: 13/Sep/18  Updated: 13/Sep/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Major
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

If you have code like

(let [^string x 3] )

we would generally prefer the type hint over the inferred type. But in cases where we have inferred a type and the type is inconsistent with the type hint, it may be useful to emit a diagnostic in that case.

If the inferred type is a superset of the hint, then we shouldn't warn. For example, if we infer any then no warning should be emitted. Also, if, for example we infer #{clj-nil string} and we have a hint of string we can take the stance that the developer is essentially saying that clj-nil can't happen.

But, on the other hand, if we infer number and there is a hint of string then clearly something is amiss.






[CLJS-2907] Hello world! not printed for QuickStart Created: 14/Sep/18  Updated: 14/Sep/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

1.10.339
Mac OS
Safari



 Description   

When following Quick Start, just seeing a blank line at times:

Bad:

$ clj --main cljs.main --compile hello-world.core --repl

ClojureScript 1.10.339
cljs.user=>

Good:

$ clj --main cljs.main --compile hello-world.core --repl
Hello world!
ClojureScript 1.10.339
cljs.user=>





[CLJS-2914] Tests fail if hypen in directory name Created: 16/Sep/18  Updated: 16/Sep/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Check out compiler into a foo-bar directory and run lein test :only cljs.module-processing-tests.

Seems very similar to CLJS-2703.

$ lein test :only cljs.module-processing-tests

lein test cljs.module-processing-tests

lein test :only cljs.module-processing-tests/commonjs-module-processing-preprocess-symbol

FAIL in (commonjs-module-processing-preprocess-symbol) (module_processing_tests.clj:191)
Processed modules are added to :js-module-index
expected: (= {"React" {:name (absolute-module-path "src/test/cljs/reactJS.js"), :module-type :commonjs}, "Circle" {:name (absolute-module-path "src/test/cljs/Circle.js"), :module-type :commonjs}} (:js-module-index (clojure.core/deref cenv)))
  actual: (not (= {"React" {:name "module$Users$mfikes$foo_bar$clojurescript$src$test$cljs$reactJS", :module-type :commonjs}, "Circle" {:name "module$Users$mfikes$foo_bar$clojurescript$src$test$cljs$Circle", :module-type :commonjs}} {"React" {:name "module$Users$mfikes$foo-bar$clojurescript$src$test$cljs$reactJS", :module-type :commonjs}, "Circle" {:name "module$Users$mfikes$foo-bar$clojurescript$src$test$cljs$Circle", :module-type :commonjs}}))

lein test :only cljs.module-processing-tests/es6-module-processing

FAIL in (es6-module-processing) (module_processing_tests.clj:97)
Processed modules are added to :js-module-index
expected: (= {"es6-hello" {:name (absolute-module-path "src/test/cljs/es6_hello.js"), :module-type :es6}} (:js-module-index (clojure.core/deref cenv)))
  actual: (not (= {"es6-hello" {:name "module$Users$mfikes$foo_bar$clojurescript$src$test$cljs$es6-hello", :module-type :es6}} {"es6-hello" {:name "module$Users$mfikes$foo-bar$clojurescript$src$test$cljs$es6-hello", :module-type :es6}}))

lein test :only cljs.module-processing-tests/test-cljs-1822

FAIL in (test-cljs-1822) (module_processing_tests.clj:162)
Processed modules are added to :js-module-index
expected: (= {"React" {:name (absolute-module-path "src/test/cljs/react-min.js"), :module-type :commonjs}, "Circle" {:name (absolute-module-path "src/test/cljs/Circle-min.js"), :module-type :commonjs}} (:js-module-index (clojure.core/deref cenv)))
  actual: (not (= {"React" {:name "module$Users$mfikes$foo_bar$clojurescript$src$test$cljs$react-min", :module-type :commonjs}, "Circle" {:name "module$Users$mfikes$foo_bar$clojurescript$src$test$cljs$Circle-min", :module-type :commonjs}} {"React" {:name "module$Users$mfikes$foo-bar$clojurescript$src$test$cljs$react-min", :module-type :commonjs}, "Circle" {:name "module$Users$mfikes$foo-bar$clojurescript$src$test$cljs$Circle-min", :module-type :commonjs}}))

lein test :only cljs.module-processing-tests/commonjs-module-processing

FAIL in (commonjs-module-processing) (module_processing_tests.clj:71)
Processed modules are added to :js-module-index
expected: (= {"React" {:name (absolute-module-path "src/test/cljs/reactJS.js"), :module-type :commonjs}, "Circle" {:name (absolute-module-path "src/test/cljs/Circle.js"), :module-type :commonjs}} (:js-module-index (clojure.core/deref cenv)))
  actual: (not (= {"React" {:name "module$Users$mfikes$foo_bar$clojurescript$src$test$cljs$reactJS", :module-type :commonjs}, "Circle" {:name "module$Users$mfikes$foo_bar$clojurescript$src$test$cljs$Circle", :module-type :commonjs}} {"React" {:name "module$Users$mfikes$foo-bar$clojurescript$src$test$cljs$reactJS", :module-type :commonjs}, "Circle" {:name "module$Users$mfikes$foo-bar$clojurescript$src$test$cljs$Circle", :module-type :commonjs}}))

Ran 5 tests containing 14 assertions.
4 failures, 0 errors.
Tests failed.


 Comments   
Comment by Mike Fikes [ 16/Sep/18 7:10 AM ]

As far as I can tell, this is not a new regression and existed at the time CLJS-2703 was fixed.





[CLJS-2915] Tests fail if directory has a period (.) in the path Created: 16/Sep/18  Updated: 16/Sep/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.10.238
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Ray McDermott Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Check out compiler into a cljs.dev directory and run lein test :only cljs.module-processing-tests.

Seems very similar to CLJS-2914.

$ lein test :only cljs.module-processing-tests

lein test cljs.module-processing-tests

lein test :only cljs.module-processing-tests/test-module-name-substitution

FAIL in (test-module-name-substitution) (module_processing_tests.clj:124)
expected: (= (str "goog.provide('my_calculator.core');" crlf "goog.require('cljs.core');" crlf "goog.require('" (absolute-module-path "src/test/cljs/calculator.js" true) "');" crlf) (compile (quote (ns my-calculator.core (:require [calculator :as calc :refer [subtract add] :rename {subtract sub}])))))
  actual: (not (= "goog.provide('my_calculator.core');\ngoog.require('cljs.core');\ngoog.require('module$Users$ray$dev$cljs.dev$clojurescript$src$test$cljs$calculator');\n" "goog.provide('my_calculator.core');\ngoog.require('cljs.core');\ngoog.require('module$Users$ray$dev$cljs_dev$clojurescript$src$test$cljs$calculator');\n"))

lein test :only cljs.module-processing-tests/test-module-name-substitution

FAIL in (test-module-name-substitution) (module_processing_tests.clj:129)
expected: (= output (compile (quote (calc/add 3 4))))
  actual: (not (= "module$Users$ray$dev$cljs.dev$clojurescript$src$test$cljs$calculator[\"default\"].add((3),(4));\n" "module$Users$ray$dev$cljs_dev$clojurescript$src$test$cljs$calculator[\"default\"].add((3),(4));\n"))

lein test :only cljs.module-processing-tests/test-module-name-substitution

FAIL in (test-module-name-substitution) (module_processing_tests.clj:130)
expected: (= output (compile (quote (calculator/add 3 4))))
  actual: (not (= "module$Users$ray$dev$cljs.dev$clojurescript$src$test$cljs$calculator[\"default\"].add((3),(4));\n" "module$Users$ray$dev$cljs_dev$clojurescript$src$test$cljs$calculator[\"default\"].add((3),(4));\n"))

lein test :only cljs.module-processing-tests/test-module-name-substitution

FAIL in (test-module-name-substitution) (module_processing_tests.clj:131)
expected: (= output (compile (quote (add 3 4))))
  actual: (not (= "module$Users$ray$dev$cljs.dev$clojurescript$src$test$cljs$calculator[\"default\"].add((3),(4));\n" "module$Users$ray$dev$cljs_dev$clojurescript$src$test$cljs$calculator[\"default\"].add((3),(4));\n"))

lein test :only cljs.module-processing-tests/test-module-name-substitution

FAIL in (test-module-name-substitution) (module_processing_tests.clj:132)
expected: (= (str (absolute-module-path "src/test/cljs/calculator.js" true) "[\"default\"].subtract((5),(4));" crlf) (compile (quote (sub 5 4))))
  actual: (not (= "module$Users$ray$dev$cljs.dev$clojurescript$src$test$cljs$calculator[\"default\"].subtract((5),(4));\n" "module$Users$ray$dev$cljs_dev$clojurescript$src$test$cljs$calculator[\"default\"].subtract((5),(4));\n"))

lein test :only cljs.module-processing-tests/commonjs-module-processing-preprocess-symbol

FAIL in (commonjs-module-processing-preprocess-symbol) (module_processing_tests.clj:191)
Processed modules are added to :js-module-index
expected: (= {"React" {:name (absolute-module-path "src/test/cljs/reactJS.js"), :module-type :commonjs}, "Circle" {:name (absolute-module-path "src/test/cljs/Circle.js"), :module-type :commonjs}} (:js-module-index (clojure.core/deref cenv)))
  actual: (not (= {"React" {:name "module$Users$ray$dev$cljs.dev$clojurescript$src$test$cljs$reactJS", :module-type :commonjs}, "Circle" {:name "module$Users$ray$dev$cljs.dev$clojurescript$src$test$cljs$Circle", :module-type :commonjs}} {"React" {:name "module$Users$ray$dev$cljs-dev$clojurescript$src$test$cljs$reactJS", :module-type :commonjs}, "Circle" {:name "module$Users$ray$dev$cljs-dev$clojurescript$src$test$cljs$Circle", :module-type :commonjs}}))

lein test :only cljs.module-processing-tests/es6-module-processing

FAIL in (es6-module-processing) (module_processing_tests.clj:97)
Processed modules are added to :js-module-index
expected: (= {"es6-hello" {:name (absolute-module-path "src/test/cljs/es6_hello.js"), :module-type :es6}} (:js-module-index (clojure.core/deref cenv)))
  actual: (not (= {"es6-hello" {:name "module$Users$ray$dev$cljs.dev$clojurescript$src$test$cljs$es6-hello", :module-type :es6}} {"es6-hello" {:name "module$Users$ray$dev$cljs-dev$clojurescript$src$test$cljs$es6-hello", :module-type :es6}}))

lein test :only cljs.module-processing-tests/test-cljs-1822

FAIL in (test-cljs-1822) (module_processing_tests.clj:162)
Processed modules are added to :js-module-index
expected: (= {"React" {:name (absolute-module-path "src/test/cljs/react-min.js"), :module-type :commonjs}, "Circle" {:name (absolute-module-path "src/test/cljs/Circle-min.js"), :module-type :commonjs}} (:js-module-index (clojure.core/deref cenv)))
  actual: (not (= {"React" {:name "module$Users$ray$dev$cljs.dev$clojurescript$src$test$cljs$react-min", :module-type :commonjs}, "Circle" {:name "module$Users$ray$dev$cljs.dev$clojurescript$src$test$cljs$Circle-min", :module-type :commonjs}} {"React" {:name "module$Users$ray$dev$cljs-dev$clojurescript$src$test$cljs$react-min", :module-type :commonjs}, "Circle" {:name "module$Users$ray$dev$cljs-dev$clojurescript$src$test$cljs$Circle-min", :module-type :commonjs}}))

lein test :only cljs.module-processing-tests/commonjs-module-processing

FAIL in (commonjs-module-processing) (module_processing_tests.clj:71)
Processed modules are added to :js-module-index
expected: (= {"React" {:name (absolute-module-path "src/test/cljs/reactJS.js"), :module-type :commonjs}, "Circle" {:name (absolute-module-path "src/test/cljs/Circle.js"), :module-type :commonjs}} (:js-module-index (clojure.core/deref cenv)))
  actual: (not (= {"React" {:name "module$Users$ray$dev$cljs.dev$clojurescript$src$test$cljs$reactJS", :module-type :commonjs}, "Circle" {:name "module$Users$ray$dev$cljs.dev$clojurescript$src$test$cljs$Circle", :module-type :commonjs}} {"React" {:name "module$Users$ray$dev$cljs-dev$clojurescript$src$test$cljs$reactJS", :module-type :commonjs}, "Circle" {:name "module$Users$ray$dev$cljs-dev$clojurescript$src$test$cljs$Circle", :module-type :commonjs}}))

Ran 5 tests containing 14 assertions.
9 failures, 0 errors.
Tests failed.


 Comments   
Comment by Ray McDermott [ 16/Sep/18 8:13 AM ]

It's looking for cljs_dev





[CLJS-1297] defrecord does not emit IKVReduce protocol Created: 03/Jun/15  Updated: 19/Nov/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.7.145
Fix Version/s: 1.9.671

Type: Defect Priority: Major
Reporter: Daniel Skarda Assignee: Unassigned
Resolution: Unresolved Votes: 2
Labels: newbie

Attachments: Text File CLJS-1297-19-July-2015.patch    
Patch: Code and Test

 Description   

Records are maps and in Clojure they support reduce-kv (IKVReduce protocol).
This is not true in ClojureScript:

(defrecord Foobar [x y])
 (reduce-kv assoc {} (Foobar. 1 2))

Fails wit Error: No protocol method IKVReduce.-kv-reduce defined for type : [object Object]



 Comments   
Comment by David Nolen [ 03/Jun/15 7:25 PM ]

Just seems like an oversight. Patch welcome, this one is a relatively easy one.

Comment by Daniel Skarda [ 04/Jun/15 2:53 AM ]

OK

I checked Clojure implementation. Records do not implement any reduce protocol on their own. For IKVReduce records use default implementation using reduce and destructuring. Is this approach OK?

Recently Alex Miller implemented many optimizations of reduce protocols in Clojure. Eg range returns an object which implements IReduce protocol so reduce (and transducers in general) can take advantage of it. Any plans for such optimizations in ClojureScript?

;;clojure/src/clj/clojure/core.clj:6523
;;slow path default
clojure.lang.IPersistentMap
(kv-reduce 
  [amap f init]
  (reduce (fn [ret [k v]] (f ret k v)) init amap))
Comment by David Nolen [ 04/Jun/15 9:05 AM ]

Going with the Clojure implementation is fine. Yes all of the optimizations in 1.7.0 are on the table for ClojureScript but these are separate issues from this one.

Comment by Samuel Miller [ 16/Jul/15 10:39 PM ]

Mind if I take this as my first cljs bug? Poking around quickly I think I know what needs to happen.

Comment by David Nolen [ 17/Jul/15 5:21 AM ]

Sure! Have you submitted your CA yet?

Comment by Samuel Miller [ 17/Jul/15 7:13 PM ]

Yes, I did yesterday.

Comment by Samuel Miller [ 20/Jul/15 9:52 PM ]

Here is a potential patch. I implemented a basic IKVreduce based on Daniel Skarda's comment. Note: I am a little fuzzy on macros still so please look over what I have. There is probably a better way. Also added a test for reduce-kv on records.

I ran the test on Linux on V8 and SpiderMonkey. I plan to get JSC and Nashorn working and tested this week but if someone wants to test them out before that would be great.

Comment by Sebastian Bensusan [ 23/Jul/15 6:45 PM ]

Experience report:

I just tested the patch in the Node Repl and it seems to work:

cljs.user=> (defrecord A [a b])
cljs.user/A
cljs.user=> (reduce-kv (fn [m k v] (assoc m k (inc v))) {} (A. 1 2))
{:a 2, :b 3}

and the provided tests passed in Spidermonkey, V8, and Nashorn (I don't have JSC installed).

For completeness: before applying the patch the same code fails with:

Error: No protocol method IKVReduce.-kv-reduce defined for type : [object Object]
Comment by David Nolen [ 10/Aug/15 10:22 PM ]

Is this the same approach taken by Clojure?

Comment by Samuel Miller [ 10/Aug/15 10:36 PM ]

You can see the relevant current Clojure code here...
https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L6526
I think it is the same. I literally just tried to translate it over into CLJS. I might of understood something wrong though.

Comment by David Nolen [ 11/Aug/15 6:10 AM ]

Yes that's the slow path. Please use the implementation used by defrecord instead. If defrecord doesn't have one then this patch is OK.

Comment by Samuel Miller [ 11/Aug/15 8:48 PM ]

As far as I can tell there is no implementation on defrecord itself however there are separate implementations on the the java classes PersistentVector, PersistentArrayMap, PersistentTreeMap, and PersistenHashMap in pure java. I am not sure if you would want to do something similar for Clojurescript.

I can also spend some time trying to make a more performant version.

Comment by António Nuno Monteiro [ 27/Jul/16 7:38 AM ]

Confirmed that Clojure uses the slow path via the IPersistentMap implementation in defrecord
https://github.com/clojure/clojure/blob/d920ad/src/clj/clojure/core.clj#L6712

Patch still applies and can also confirm it works for me.

Comment by Mike Fikes [ 19/Nov/17 8:03 PM ]

CLJS-1297-19-July-2015.patch no longer applies.





[CLJS-2917] cljs.main: Failure to load user.cljs if temp out dir Created: 20/Sep/18  Updated: 20/Sep/18

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

{:deps {org.clojure/clojurescript {:mvn/version "1.10.339"}}}



 Description   
src/user.cljs
(def a 3)
$ clj -Srepro -m cljs.main
java.lang.IllegalArgumentException: /var/folders/gx/nymj3l7x4zq3gxb97v2zwzb40000gn/T/out6255758032123683761473031144485066/cljs/user/userAE725FA.js is not a relative path
	at clojure.java.io$as_relative_path.invokeStatic(io.clj:414)
	at clojure.java.io$file.invokeStatic(io.clj:426)
	at clojure.java.io$file.invoke(io.clj:418)
	at cljs.closure$compile_file.invokeStatic(closure.clj:633)
	at cljs.closure$compile_file.invoke(closure.clj:625)
	at cljs.closure$fn__5175.invokeStatic(closure.clj:721)
	at cljs.closure$fn__5175.invoke(closure.clj:715)
	at cljs.closure$fn__5088$G__5081__5095.invoke(closure.clj:543)
	at cljs.closure$compile.invokeStatic(closure.clj:595)
	at cljs.closure$compile.invoke(closure.clj:592)
	at cljs.repl$load_file$fn__6454.invoke(repl.cljc:601)
	at cljs.repl$load_file.invokeStatic(repl.cljc:600)
	at cljs.repl$load_file.invoke(repl.cljc:592)
	at cljs.repl$repl_STAR_$maybe_load_user_file__6612.invoke(repl.cljc:958)
	at cljs.repl$repl_STAR_$fn__6621$fn__6622.invoke(repl.cljc:989)
	at cljs.repl$repl_STAR_$fn__6621.invoke(repl.cljc:982)
	at cljs.compiler$with_core_cljs.invokeStatic(compiler.cljc:1289)
	at cljs.compiler$with_core_cljs.invoke(compiler.cljc:1278)
	at cljs.repl$repl_STAR_.invokeStatic(repl.cljc:979)
	at cljs.repl$repl_STAR_.invoke(repl.cljc:855)
	at cljs.cli$repl_opt.invokeStatic(cli.clj:305)
	at cljs.cli$repl_opt.invoke(cli.clj:292)
	at cljs.cli$main.invokeStatic(cli.clj:638)
	at cljs.cli$main.doInvoke(cli.clj:625)
	at clojure.lang.RestFn.invoke(RestFn.java:410)
	at clojure.lang.AFn.applyToHelper(AFn.java:154)
	at clojure.lang.RestFn.applyTo(RestFn.java:132)
	at clojure.core$apply.invokeStatic(core.clj:659)
	at clojure.core$apply.invoke(core.clj:652)
	at cljs.main$_main.invokeStatic(main.clj:61)
	at cljs.main$_main.doInvoke(main.clj:52)
	at clojure.lang.RestFn.invoke(RestFn.java:397)
	at clojure.lang.AFn.applyToHelper(AFn.java:152)
	at clojure.lang.RestFn.applyTo(RestFn.java:132)
	at clojure.lang.Var.applyTo(Var.java:702)
	at clojure.core$apply.invokeStatic(core.clj:657)
	at clojure.main$main_opt.invokeStatic(main.clj:317)
	at clojure.main$main_opt.invoke(main.clj:313)
	at clojure.main$main.invokeStatic(main.clj:424)
	at clojure.main$main.doInvoke(main.clj:387)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.lang.Var.applyTo(Var.java:702)
	at clojure.main.main(main.java:37)
ClojureScript 1.10.339
cljs.user=>

If, on the other hand you specify an output directory (via -d) things work.






[CLJS-720] #queue literal behavior is incorrect Created: 07/Dec/13  Updated: 07/Dec/13

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

In order for queue to work we need to adopt an approach similar to the one for #js data literals - i.e. needs special casing in the analyzer since queues are not "atomic" values.






[CLJS-736] Functions folder and reducer broken for types nil and array + fix for typo Created: 29/Dec/13  Updated: 02/Dec/14

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Jonas De Vuyst Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None

Attachments: Text File CLJS-736-alt.patch     Text File CLJS-736.patch     Text File CLJS-736-patch-1-redux.patch     Text File CLJS-alt-satisfies.patch    
Patch: Code and Test

 Description   

1. This currently doesn't work:

(->> nil
(r/map identity)
(r/reduce + 0))
; org.mozilla.javascript.JavaScriptException: Error: No protocol method IReduce.-reduce defined for type null

The reason for this is that reducers created by r/reducer or r/folder, invoke -reduce (of IReduce) directly. They thereby bypass the special case for nil in the function r/reduce.

2. An entirely analogous problem exists for collections of type array.

3. The patch CLJS-700 mistakenly defined coll-fold for the type cljs.core/IPersistentVector. This should have been cljs.core/PersistentVector. (There exists no protocol IPersistentVector in ClojureScript.)

I will shortly attach a patch that addresses all of the above problems by implementing IReduce for nil and array. The patch also includes unit tests.



 Comments   
Comment by Jonas De Vuyst [ 29/Dec/13 2:22 PM ]

Alternative patch in which r/reduce and r/fold treat arrays and nil as special cases – as opposed to having arrays and nil implement IReduce and CollFold.

The functions r/reducer, r/folder, and the protocol methods of r/Cat now call r/reduce and r/fold instead of calling -reduce and coll-fold directly.

This patch also fixes a bug in the coll-fold implementation for Cat, which previously used (reducef) as the initial value rather than (combinef). The new code is copied and pasted from the Clojure implementation and uses the fork-join stubs.

Comment by David Nolen [ 30/Dec/13 8:23 AM ]

The implements? should probably be a satisfies? in the second patch. Have you run any benchmarks of before/after the patch?

Comment by Jonas De Vuyst [ 30/Dec/13 11:24 AM ]

If I understand correctly then (satisfies? x y) is roughly equivalent to (or (implements? x y) (natively-satisfies? x y)).

If native types (nil, array, object currently) are treated as special cases then implements? seems more appropriate.

satisfies? works also, however, so I have attached a new 'alt' patch.

Comment by Jonas De Vuyst [ 30/Dec/13 11:26 AM ]

The first patch is in fact faster when running the following code:

(time (->> (repeat 1000 (vec (range 1000)))
vec
(r/mapcat identity)
(r/map inc)
(r/filter even?)
(r/fold +)))

This takes about 700 msecs. Using the first patch this terminates 100-300 msecs faster. This is after repeated (but informal) testing.

I guess the worry is that the first patch would slow down other random code since it involves extending the types nil, array, and object. I'm not sure what exactly I should test for though.

(Note that the 2nd and 3rd patch also contain a fix for Cat and include more unit tests. The first patch should preferably not be applied as-is.)

Comment by David Nolen [ 30/Dec/13 11:35 AM ]

Yeah you're timing too many things, including vec, range, lazy sequences. Also testing a small N. Take a look at the reducers example on the Mori README - https://github.com/swannodette/mori. Thanks.

Comment by Jonas De Vuyst [ 30/Dec/13 12:52 PM ]

I tried running the following code:

(let [coll (vec (repeat 1000 (vec (range 10))))]
  (time (doseq [n (range 1000)]
               (->> coll
                    (r/mapcat identity)
                    (r/map inc)
                    (r/filter even?)
                    (r/fold +)))))

Some of the last results I got were:

1st patch: 75680 msecs
2nd patch: 76585 msecs

Truth be told, although the first patch seemed to win most of the times, sometimes the second patch was faster.

One other thing I tried was removing the implements?/satisfies? check from the second patch and overriding the protocol method coll-fold for the type object instead (as in the first patch). This 'hybrid' approach generally (but not always) seemed to result in a slowdown.

I'm not sure how I should proceed. Should I perhaps just run both patches simultaneously for several minutes?

Comment by David Nolen [ 30/Dec/13 1:21 PM ]

This is still a bad way to do timing, you're recording the cost of range and seq'ing. Use dotimes.

Comment by Jonas De Vuyst [ 30/Dec/13 4:33 PM ]

Hm. I guess the lazy sequence does lead to a lot of allocations.

Alright, I rewrote my test and ran it a few more times. I now also tested on both vectors and arrays.

Patch 1 needed a slight tweak. When coll-fold is invoked, patch 1 only specifies a fallback for type object (i.e. r/reduce is called). I had to add the same fallback for type array. (This is weird!)

So here are the results.

For vectors:

(let [coll (vec (repeat 100 (vec (range 100))))]
  (time (dotimes [n 3000]
          (->> coll
              (r/mapcat identity)
              (r/map inc)
              (r/filter even?)
              (r/fold +)))))

Patch 1: 205872 msecs
Patch 2: 210756 msecs

For arrays:

(let [coll (into-array (repeat 100 (into-array (range 100))))]
  (time (dotimes [n 3000]
          (->> coll
              (r/mapcat identity)
              (r/map inc)
              (r/filter even?)
              (r/fold +)))))

Patch 1: 123567 msecs
Patch 2: 119704 msecs

I ran my tests a few times and the results were pretty consistent. Patch 1 is faster for vectors and patch 2 is faster for arrays.

This makes sense.

In patch 1 reducer will call -reduce directly. In patch 2, reducer first calls r/reduce, which calls -reduce if the collection is a vector and array-reduce if it's an array. Hence patch 2 contains an extra function call in the case of vectors, but avoids invoking a protocol method on a native type in the case of arrays.

Using macros (or copy and paste) the extra function call can be avoided. Would that be worth trying or is it more important to keep the code clean?

I just realized that patch 2 is semantically slightly different from what Clojure does, although perhaps this is a bug in Clojure: <https://groups.google.com/forum/#!searchin/clojure-dev/kv-reduce/clojure-dev/bEqECvbExGo/iW4B2vEUh8sJ>. My suggestion to use a macro (or copy and paste) to avoid the extra function call in patch 2, could also fix this discrepancy.

Comment by David Nolen [ 30/Dec/13 4:42 PM ]

How are you benchmarking this? With V8? JavaScriptCore? SpiderMonkey? In the browser? What optimization settings, etc.

Comment by Jonas De Vuyst [ 30/Dec/13 4:48 PM ]

I used repljs (Rhino?). I'll test again in a more realistic setting tomorrow.

Comment by David Nolen [ 30/Dec/13 4:54 PM ]

Yeah, benchmarking with Rhino isn't informative.

Comment by Jonas De Vuyst [ 31/Dec/13 1:40 AM ]

I compiled the same code (with n=3000) using cljs with "{:optimizations :advanced}".

I then tested it in the latest stable releases of Firefox, Chrome, and Safari. I closed all my browsers. For each browser I then followed the following procedure:

  • Open the browser
  • Open the developer console
  • Run the benchmark for patch 1
  • Run the benchmark for patch 2
  • Run the benchmark for patch 1 and write down the result
  • Run the benchmark for patch 2 and write down the result
  • Close the browser

Firefox:

  • Patch 1. Vectors: 26057 msecs
  • Patch 1. Arrays: 25026 msecs
  • Patch 2. Vectors: 26258 msecs
  • Patch 2. Arrays: 36653 msecs
  • Summary: Patch 1 is faster for vectors and arrays

Chrome:

  • Patch 1. Vectors: 7804 msecs
  • Patch 1. Arrays: 7092 msecs
  • Patch 2. Vectors: 7754 msecs
  • Patch 2. Arrays: 6768 msecs
  • Summary: Patch 2 is faster for vectors and arrays

Safari:

  • Patch 1. Vectors: 167230 msecs
  • Patch 1. Arrays: 108780 msecs
  • Patch 2. Vectors: 173940 msecs
  • Patch 2. Arrays: 110012 msecs
  • Summary: Patch 1 is faster for vectors and arrays

I'm not sure what to make of this.

Comment by Jonas De Vuyst [ 31/Dec/13 2:47 AM ]

I have attached a new version of the first patch.

This patch fixes an issue with r/Cat. (This issue was also addressed in the second and third patch. A unit test is included.).

This patch also fixes r/fold for arrays.

To summarize, a choice needs to be made between the following patches.

  • CLJS-736-patch-1-redux.patch
  • CLJS-736-alt.patch (uses implements?) / CLJS-alt-satisfies.patch (uses satisfies?)

The implementation details are patch-1-redux is more similar in spirit to the Clojure source code. The alt patches are more similar in spirit to the ClojureScript source code.

As explained above, the alt patches are semantically a bit different from the original Clojure source—but it's not clear which behavior is 'right'.

Comment by David Nolen [ 16/Jan/14 5:27 PM ]

The benchmarks would be more informative if they explained the performance before and after that patch.

Comment by Jonas De Vuyst [ 18/Jan/14 11:55 AM ]

r/reduce previously didn't work for nil or JavaScript arrays.

One reason why I have trouble recommending a patch is that I don't know what use case you would like to optimize for.

Comment by David Nolen [ 18/Jan/14 12:30 PM ]

Yes but now that we have new logic we can at least test the lack of regression on the other types.

Comment by David Nolen [ 18/Jan/14 12:40 PM ]

Ok I tried to apply this patch and run ./script/benchmarks in the repo but the patch will no longer apply. Can we rebase the patch on master. Thanks. If you also want to give the benchmarks a shot follow these instructions to install the JS engines - http://github.com/clojure/clojurescript/wiki/Running-the-tests. Then you can also run the benchmarks at the command line. I see there aren't any reducers benchmarks, I will add some.





[CLJS-900] Parameterize caching strategy Created: 03/Dec/14  Updated: 03/Dec/14

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Task Priority: Minor
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Currently the caching strategy is hard coded to a disk based one. It would be desirable in many situations for the caching to be in memory. We should decouple the caching strategy and support disk / memory out of the box.






[CLJS-1123] this-as unexpectedly binds js/window when used within function with post-condition Created: 15/Mar/15  Updated: 16/Mar/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: J. S. Choi Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Adding a post-condition to any function that uses cljs.core/this-as will unexpectedly cause this-as's "this" symbol to be bound to the root object (e.g., js/window) instead.

(defn f-no-post-condition [argument]
  (this-as this
    (js/console.log argument this)))

(defn f-with-post-condition [argument]
  {:post [true]}
  (this-as this
    (js/console.log argument this)))

(def test-object
  #js {:methodNoPostcondition f-no-post-condition
       :methodWithPostcondition f-with-post-condition})

(f-with-post-condition "A") ; Correctly prints js/window
(.methodNoPostcondition test-object "B") ; Correctly prints test-object
(.methodWithPostcondition test-object "C") ; Incorrectly prints js/window


 Comments   
Comment by David Nolen [ 16/Mar/15 6:17 AM ]

This is almost certainly a different manifestation of CLJS-719.

Comment by Thomas Heller [ 16/Mar/15 6:21 AM ]

Just looked at the generated javascript. As David mentioned the problem is the extra function generated to get the result for the :post condition.

dummy.f_no_post_condition = (function f_no_post_condition(argument){
var this$ = this;
var G__82157 = argument;
var G__82158 = this$;
return console.log(G__82157,G__82158);
});
dummy.f_with_post_condition = (function f_with_post_condition(argument){
var _PERCENT_ = (function (){var this$ = this;
var G__82161 = argument;
var G__82162 = this$;
return console.log(G__82161,G__82162);
})();


return _PERCENT_;
});
dummy.test_object = {"methodWithPostcondition": dummy.f_with_post_condition, "methodNoPostcondition": dummy.f_no_post_condition};
dummy.f_with_post_condition("A");
dummy.test_object.methodNoPostcondition("B");
dummy.test_object.methodWithPostcondition("C");




[CLJS-1091] Compose JavaScript dependency indexes Created: 07/Mar/15  Updated: 29/Apr/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Currently hard coded to Google Closure deps.js and the one produced for a build. Users should be able to supply JS dependency indexes that can get merged in.






[CLJS-1259] Incorrect warnings on type hinted maths Created: 09/May/15  Updated: 14/Jul/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3255
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Erik Ouchterlony Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: bug, math, typehints


 Description   

Variables type hinted as int or double are not recognized as numbers, e.g.

(def ^int i 1)
(+ i i)
WARNING: cljs.core/+, all arguments must be numbers, got [int int] instead. at line 1 <cljs repl>
2


 Comments   
Comment by David Nolen [ 14/Jul/15 6:07 AM ]

The real issue is that there is no support for numeric type hints.





[CLJS-1255] cljs.test file-and-line detection is not useful in browser testing Created: 07/May/15  Updated: 14/Jul/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3211
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Stephen Nelson Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Chrome



 Description   

cljs.test reports using do-report, which adds file and line information computed from javascript stack traces. In chrome at least, these stack traces are not useful:

"Error
    at http://localhost:3449/js/cljs/test.js:261:69
    at cljs$test$do_report (http://localhost:3449/js/cljs/test.js:268:3)
    at http://localhost:3449/js/test/test_tests.js:491:21
    at test.test_tests.test_has_fails.cljs$lang$test (http://localhost:3449/js/test/test_tests.js:502:4)
    at http://localhost:3449/js/cljs/test.js:384:42
    at http://localhost:3449/js/cljs/test.js:387:4
    at cljs$test$run_block (http://localhost:3449/js/cljs/test.js:320:13)
    ..."

The `file-and-line` stack trace parser doesn't parse this correctly, resulting in a message like this:

FAIL in (test-function) (at http:384:42)

Note the lack of a useful file/namespace reference, and that the line number refers to the compiled javascript rather than the source clojurescript.



 Comments   
Comment by Stephen Nelson [ 07/May/15 9:15 PM ]

Prior to the release of cljs.test my company maintained an internal port of clojure.test that did better reporting than cljs.test's by adding source metadata from &form to the do-report calls generated by assert-expr. This approach was great for internal use but might not be suitable for cljs.test as it could reduce portability of assert-expr between clojure and clojurescript. Another approach could be dynamically bind source metadata in the body generated by try-expr. I'd be willing to implement and contribute code if you can provide some indication of your preferred approach.

Our version of assert-expr also injected a 'reporter function', {{(function(a,b,c){a.apply(b.c)})}}, which we would invoke from report, e.g. (reporter (.-debug js/console) js/console args). This causes the clickable link on the right hand side of chrome's console output to link to the source map location of the test expression, rather than the report function.

Comment by David Nolen [ 14/Jul/15 6:09 AM ]

The correct thing to do here is to move the browser REPL stacktrace parsing into a shared library i.e. .cljc that can be loaded into either environment to handle browser difference.





[CLJS-1390] clojure.walk treats vectors diffently from Clojure version Created: 03/Aug/15  Updated: 03/Aug/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.7.28
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Leon Grapenthin Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

The latest patch to clojure.walk (https://github.com/clojure/clojurescript/commit/f706fabfd5f952c4dfb4dc2caeea92f9e00d8287) ports the line of the Clojure version

(instance? clojure.lang.IMapEntry form) (outer (vec (map inner form)))

with the line

(satisfies? IMapEntry form) (outer (vec (map inner form)))

ClojureScript implements IMapEntry on any vector which I assume is intended.

In Clojure, for vectors this case falls:

(coll? form) (outer (into (empty form) (map inner form)))

This makes a difference because empty preserves metadata.
I. e.

(meta (prewalk (fn [form]
                  (vary-meta form assoc :foo true))
               []))

gives {:foo true} on earlier ClojureScript versions and Clojure, but nil on the latest version.

I have relied on this which has likely not been a very good idea, but others might have too - Hence I created this ticket for consideration.






[CLJS-1407] Exposing output file dependency graph in API Created: 09/Aug/15  Updated: 08/Nov/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Juho Teperi Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Use case for boot-cljs and boot-reload:

After compilation boot-reload reloads the changed JS files. So that the files can be reloaded in correct order, boot-cljs uses dependency graph to sort the files. Currently boot-cljs accesses compiler state directly and uses data from :js-dependency-index to build the graph: https://github.com/adzerk-oss/boot-cljs/blob/0.0-3308/src/adzerk/boot_cljs/impl.clj#L17-L36

Simple solution:

If dependencies (requires) of namespace are exposed through API it is easy to build graph of cljs namespace dependencies: https://github.com/adzerk-oss/boot-cljs/blob/d479f10935be321232e2363e2ae3e9cc515a81af/src/adzerk/boot_cljs/impl.clj#L12-L32

Problem with this solution is that all-ns, ns-dependencies or target-file-for-cljs-ns do not work with foreign-deps. While foreign-dep files don't usually change and thus aren't reloaded, it's possible that user has local JS files in the project using foreign-deps and those can change.

Questions, notes and issues

  • Should cljs-dependency-graph be exposed in the API or is it enough to provide ns-dependencies and such which user can use to create dependency graph?
  • cljs.build.api/parse-js-ns can also be used to read provides and requires from compiled JS files, but this doesn't work with foreign-deps either
  • Perhaps there is some way in Closure library to reload files in correct order?
  • Supporting foreign-deps is not perhaps necessary, but if there is good way it would be nice to have.


 Comments   
Comment by Juho Teperi [ 11/Aug/15 3:18 AM ]

I would add the call to cljs.compiler.api and it could be called output-dependency-graph.

Creating the graph requires list of all the nodes and dependencies for each node. For Cljs namespaces
these are accessible through all-ns and ns analysis map :requires. Data about foreign-deps
and closure libs is available in the compiler state under :js-dependency-index key. To create the
graph we need to:

1. Get list of all nodes
2. Get dependencies for given node
3. Get output file for given node

Because steps 2 and 3 depend on the type of node, it would probably be easiest to collect those
values in step 1. So step 1 would do something like this:

{{(get-nodes ...) => {:provides "goog.net" :file "out/goog/net.js" :dependencies #{"goog.foo"}} {:provides "frontend.core" :file "out/frontend/core.js" :dependencies #{"cljs.core"}}}}

That could be implemented by concatenating data from cljs namespaces retrieved from all-ns etc. with
data from :js-dependency-index. The next and last step would be to construct the graph using reduce.

Using this implementation there would be just one new API call: output-dependency-graph.

I was thinking alternative approach with all-ns, find-ns etc. versions which would work also with foreign-deps and closure libs, but I don't think it's very easy (or efficient) e.g. to retrieve data for foreign-dep with just a name as they are indexed by file paths.

Comment by David Nolen [ 03/Nov/15 6:34 PM ]

Now that CLJS-1437 is merged what is needed to wrap this one up?

Comment by Juho Teperi [ 08/Nov/15 9:11 AM ]

My current plan with boot-cljs/boot-reload is to use Figwheel client code which uses Google Closure dependency graph for loading the files in correct order. Thus I don't need this anymore. Perhaps it's best to close this if no-one needs this currently?

Comment by David Nolen [ 08/Nov/15 9:28 AM ]

It may still be useful at some point. Will just lower the priority.





[CLJS-1075] Generic inline source map support Created: 02/Mar/15  Updated: 22/Dec/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Currently hard coded to REPLs. Would simplify jsbin and similar integration.






[CLJS-1059] Simple interface wanted to convert cljs forms to js Created: 22/Feb/15  Updated: 31/Jan/16

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3211
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Stuart Mitchell Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: analyzer, compiler


 Description   

In our project (a clojurescript debugger) we want to convert cljs forms or a sequence of forms into javascript so that they can be executed in the javascript console.

We would like something similar to closure/compile-form-seq (https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/closure.clj#L308)

However, we need to supply, the namespace requires and locals in an env like this

{:ns {:name "test.core" :requires {(quote gstring) (quote goog.string)}} :locals {}}

This code seems to do what we want.

(defn compile-form-seq
    \"Compile a sequence of forms to a JavaScript source string.\"
    [forms env]
    (env/ensure
    (compiler/with-core-cljs nil
      (fn []
        (with-out-str
            (doseq [form forms]
              (compiler/emit (analyzer/analyze env form))))))))

I am not sure why I need env/ensure.

Would you be able to patch compile-form-seq to provide the needed interface, or suggest what we should be doing.

Thanks
Stu



 Comments   
Comment by Mike Thompson [ 22/Feb/15 10:09 PM ]

Just to be clear:
1. when our debugger is at a breakpoint,
2. the user can type in an expression at the repl
3. in response, our debugger has to compile the user-typed-in expression to javascript (and then execute it, showing a result)
4. taking into account any local bindings. <---- this is the key bit.

To satisfy point 4, our tool extracts all the 'locals' from the current call-frame, and then supplies all these local bindings in env/locals, so the compiler doesn't stick a namespace on the front of them.

For example, if there was a local binding for 'x' in the callstack, and the user's repl-entered-expression involves 'x', then we want the compiler to leave the symbol 'x' alone and to not put some namespace on the front of it. In the final javascript, it must still be 'x', not 'some.namespace.x'

Our method to achieve this is to put 'x' into env/locals when compiling – and it all works. Except, with the recent changes this has become more of a challenge. Hence this ticket asking for a way to pass in env.

Comment by Thomas Heller [ 23/Feb/15 3:19 AM ]

You could wrap the user expression in an fn, that would allow you to skip messing with the locals. The REPL basically does the same trick for *1,*2,...

(fn [x]
  ~user-expression-here)
Comment by David Nolen [ 29/Apr/15 7:21 AM ]

Seems like something useful to add to a cljs.compiler.api namespace.





[CLJS-1575] Combination of - and _ params causes JSC_DUPLICATE_PARAM Created: 17/Feb/16  Updated: 18/Mar/16

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Peter Jaros Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

The following function definitions each cause ERROR: JSC_DUPLICATE_PARAM. Parse error. Duplicate parameter name "_" at compile time with :advanced compilation:

Unable to find source-code formatter for language: clojure. Available languages are: javascript, sql, xhtml, actionscript, none, html, xml, java
(defn causes-duplicate-param [{_ :foo}]
  (reify
    Object
    (a-function [-]
      (fn [] "arbitrary function inside a-function body"))))

(defn causes-duplicate-param [{- :foo}]
  (reify
    Object
    (a-function [_]
      (fn [] "arbitrary function inside a-function body"))))

They generate, respectively:

duplicate_param_name_demo.core.t_duplicate_param_name_demo$core1601.prototype.a_function = ((function (map__1599,map__1599__$1,_){
return (function (){
var self__ = this;
var _ = this;
return ((function (_,map__1599,map__1599__$1,_){
return (function (){
return "arbitrary function inside a-function body";
});
;})(_,map__1599,map__1599__$1,_))
});})(map__1599,map__1599__$1,_))
;

duplicate_param_name_demo.core.t_duplicate_param_name_demo$core1612.prototype.a_function = ((function (map__1610,map__1610__$1,_){
return (function (){
var self__ = this;
var _ = this;
return ((function (_,map__1610,map__1610__$1,_){
return (function (){
return "arbitrary function inside a-function body";
});
;})(_,map__1610,map__1610__$1,_))
});})(map__1610,map__1610__$1,_))
;

(Notice the duplicate _ param on the 5th line of each.)

The following do not:

Unable to find source-code formatter for language: clojure. Available languages are: javascript, sql, xhtml, actionscript, none, html, xml, java
(defn causes-duplicate-param [{- :foo}]
  (reify
    Object
    (a-function [-]
      (fn [] "arbitrary function inside a-function body"))))

(defn causes-duplicate-param [{_ :foo}]
  (reify
    Object
    (a-function [_]
      (fn [] "arbitrary function inside a-function body"))))

They generate:

duplicate_param_name_demo.core.t_duplicate_param_name_demo$core1601.prototype.a_function = ((function (map__1599,map__1599__$1,_){
return (function (){
var self__ = this;
var ___$1 = this;
return ((function (___$1,map__1599,map__1599__$1,_){
return (function (){
return "arbitrary function inside a-function body";
});
;})(___$1,map__1599,map__1599__$1,_))
});})(map__1599,map__1599__$1,_))
;

duplicate_param_name_demo.core.t_duplicate_param_name_demo$core1612.prototype.a_function = ((function (map__1610,map__1610__$1,_){
return (function (){
var self__ = this;
var ___$1 = this;
return ((function (___$1,map__1610,map__1610__$1,_){
return (function (){
return "arbitrary function inside a-function body";
});
;})(___$1,map__1610,map__1610__$1,_))
});})(map__1610,map__1610__$1,_))
;

(Notice that one of the {} params has become __$1.)

My guess, though I haven't looked into the compiler code, is that the compiler escapes {} to _$1 when it would conflict with another {}, and also it translates - to {}, but it doesn't notice the conflict when the _ClojureScript symbols are different.



 Comments   
Comment by Peter Jaros [ 17/Feb/16 11:44 AM ]

Forgive the weird formatting errors. I couldn't find a preview function and there doesn't appear to be a way to edit the issue now that it's posted.

Comment by David Nolen [ 18/Mar/16 1:46 PM ]

This is because of munging they will become the same thing. Patch welcome.





[CLJS-1610] Refs api Created: 26/Mar/16  Updated: 28/Mar/16

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: James Laver Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

It would be nice to support the refs API in clojurescript to ease porting of libraries which require it. Obviously usage of it would not bring concurrency benefits, but it would at least allow some existing clojure code to run.

I've satisfied myself it can be done reasonably easily (see https://github.com/jjl/clojurescript/tree/ref-support ), and I can't really see any downsides.

For the minute, this has been put into the cljs.stm namespace. I don't know whether it should be a feature you are automatically opted into, so I didn't put it into core. Thoughts?



 Comments   
Comment by David Nolen [ 28/Mar/16 6:44 AM ]

It's definitely worth considering. If you've done the work, attach an actual patch for review. In general we try to avoid links outside.





[CLJS-1109] Record type name and advanced optimization Created: 12/Mar/15  Updated: 12/Mar/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3058
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Daniel Skarda Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

It is not possible to query type name in advanced compilation.
Code below prints correct record name in other compilation modes, but under advanced compilation it prints constructor source code.

(defrecord FooBar [a])

(def fb (FooBar. 1))

(prn (-> fb))
(prn (-> fb type))
(prn (-> fb type pr-str))





[CLJS-1766] Set literals in REPL end up reified as ArrayMap backed PersistentHashSets. Created: 28/Aug/16  Updated: 28/Aug/16

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Thomas Mulvaney Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: repl


 Description   

Entering a set literal in the REPL with more than 8 elements should create a PHM backed set but instead it is array backed.

Example (in REPL):
cljs.user=> (type (.-hash-map #{1 2 3 4 5 6 7 8 9}))
cljs.core/PersistentArrayMap

This means operations such as `get` and `contains?` end up doing long scans and are slower than a user would expect.






[CLJS-1048] support function values in static vars compile time metadata Created: 20/Feb/15  Updated: 20/Feb/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Ivan Mikushin Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Function values are currently only supported for :test metadata key as a special case.






[CLJS-1562] WARN on hinted fn call type mismatch Created: 06/Feb/16  Updated: 18/Mar/16

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.7.228
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

If a call is made to a function that has hinted arguments (especially {^boolean} and {^number}), with an expression that is known to not be of that type, emit a diagnostic type mismatch warning.

An example that should emit a warning is:

(defn f [^boolean b])
(f 0)





[CLJS-1806] build api fails to generate inline code for :target :nodejs Created: 01/Oct/16  Updated: 09/Dec/16

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.9.76
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Bruce Hauman Assignee: Unassigned
Resolution: Unresolved Votes: 2
Labels: None


 Description   

when inline code is provided as vector to the composition of `cljs.build.api/build` and `cljs.build.api/inputs` methods under `:target :nodejs` the provided inline code is not output.

;; this outputs code
(cljs.build.api/build (cljs.build.api/inputs '[(ns hello.core) (+ 1 2)]) {}) 

;; this does not output inline code
(cljs.build.api/build (cljs.build.api/inputs '[(ns hello.core) (+ 1 2)]) {:target :nodejs}) 


;; When you don't use cljs.build.api/inputs everything works correctly
(cljs.build.api/build '[(ns hello.core) (+ 1 2)] {}) ;; this outputs code

(cljs.build.api/build '[(ns hello.core) (+ 1 2)] {:target :nodejs}) ;; this outputs code


 Comments   
Comment by Bruce Hauman [ 30/Oct/16 11:31 AM ]

From @ykomatsu on Github:

add-preloads seems to remove cljs/nodejs.cljs.

https://github.com/clojure/clojurescript/blob/ab7a4911f1fd3a81210b1a9f2d84857748f8268b/src/main/clojure/cljs/closure.clj#L897

This patch will fix this problem but I am not sure if this is correct solution.

https://github.com/ykomatsu/clojurescript/commit/fc986467e66e6a628dc8f0e8a2ef2b30f715fd23

Comment by Dusan Maliarik [ 09/Dec/16 2:15 PM ]

Would anyone from the team please look at the patch? Thank you

Comment by David Nolen [ 09/Dec/16 6:22 PM ]

Please attach a patch to the ticket for review. Linking out of JIRA is not desirable. Thanks.





[CLJS-1899] Local bindings conflict with global JS namespace Created: 24/Jan/17  Updated: 24/Jan/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Nikita Prokopov Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: None


 Description   

Not sure if it's a bug or expected behaviour, but this:

(defn test-fn []
  (let [href     js/location.href
        location "123"]
    href))

gets compiled to this (not in advanced mode):

cognician.chat.ui.pages.insights.test_fn = (function cognician$chat$ui$pages$insights$test_fn(){
var href = location.href;
var location = "123";
return href;
});

and local location var shadows global I'm trying to access in location.href.

That sort of thing is expected and one should pay attention and work around stuff like this in JS, but in CLJS it's very confusing because nothing hints what am I doing wrong and why that code fails. I remember one of ClojureScript goals was to fix JS semantics, so maybe there's a way this might be addressed? At least throw a warning, maybe?



 Comments   
Comment by Thomas Heller [ 24/Jan/17 5:04 AM ]

This came up recently on the #cljs-dev slack channel. There is definitely a bug somewhere.

(let [href     js/location.href
      location "123"]
  href)

produces

var href_51444 = location.href;
var location_51445 = "123"; // << correct

So it works at the top level, but when inside a defn (and others) we get

(ns test)
(defn test-fn []
  (let [href     js/location.href
        location "123"]
    href))
test.test_fn = (function test$test_fn(){
var href = location.href;
var location = "123"; // << incorrect
return href;
});
Comment by David Nolen [ 24/Jan/17 7:27 AM ]

Taking a quick look it seems that maybe we aren't checking `:js-globals` consistently and often only looking at locals? Also now that externs inference is a thing we should probably compute `:js-globals` from all known externs instead of the obviously incomplete list we currently have in place.





[CLJS-1933] Support CLJS browserless remote REPL from nodejs Created: 09/Feb/17  Updated: 09/Feb/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.9.293
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Mike Longworth Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: enhancement, remote, repl
Environment:

Dev machine OSX - build and Cursive editing and REPL
Remote: RaspberryPI - nodejs
compiler out-files shared between devices with OSXFUSE.



 Description   

I would like to develop clojurescript for a remote nodejs target compiling cljs and running a REPL on my development machine.
https://github.com/clojure/clojurescript/wiki/Remote-REPL suggests a way of doing this however:

!) I haven't managed to get this working.
2) I don't like that the solution relies identical absolute file paths for the compiler output, better to have matching relative paths.

I made a post to request help with this but haven't managed to resolve all the issues:
https://groups.google.com/forum/#!topic/clojurescript/Y4ajOcej8Qo

I have made some progress since the post:
1) I dug into the cljs.repl.node source and found I can stop the node hang I reported by specifying repl-env :debug-port, and get:

Clojure 1.8.0
Debugger listening on port 5002
ClojureScript Node.js REPL server listening on 5001
TypeError: Cannot read property 'nameToPath' of undefined
at Object.goog.require (repl:2:49)
at repl:1:-56
at Object.exports.runInThisContext (vm.js:54:17)
at Domain.<anonymous> ([stdin]:50:34)
at Domain.run (domain.js:221:14)
at Socket.<anonymous> ([stdin]:49:25)
at emitOne (events.js:77:13)
at Socket.emit (events.js:169:7)
at readableAddChunk (_stream_readable.js:146:16)
at Socket.Readable.push (_stream_readable.js:110:10)
TypeError: goog.provide is not a function
at repl:1:-56
at Object.exports.runInThisContext (vm.js:54:17)
at Domain.<anonymous> ([stdin]:50:34)
at Domain.run (domain.js:221:14)
at Socket.<anonymous> ([stdin]:49:25)
at emitOne (events.js:77:13)
at Socket.emit (events.js:169:7)
at readableAddChunk (_stream_readable.js:146:16)
at Socket.Readable.push (_stream_readable.js:110:10)
at TCP.onread (net.js:523:20)
To quit, type: :cljs/quit

This looks like some kind of path problem but I haven't managed to resolve it.

I did some investigations with my original relative-path setup to try and identify the issues:
1) I eliminated absolute paths from the compile output by disabling analysis caching.
2) I ran wireshark on the REPL port and found that absolute paths were being sent by the REPL, this currently makes the relative path option unworkable.

I have many gaps in my knowledge of the REPL operation at the moment and I don't know what the best approach is to getting a good solution for a browserless remote repl setup.



 Comments   
Comment by David Nolen [ 09/Feb/17 12:33 PM ]

It's probably going to be easier to discuss this issue in IRC or Slack first. There's just too many different issues piled into this one. Thanks.





[CLJS-1543] Support Closure libs using goog.module Created: 12/Jan/16  Updated: 13/Jan/16

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Juho Teperi Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

goog.module is a new way to define Closure namespaces: https://github.com/google/closure-library/wiki/goog.module:-an-ES6-module-like-alternative-to-goog.provide

It is used for example in https://github.com/google/incremental-dom

I didn't do full check of how Closure libraries are handled, but one function which is definitely used by cljs.closure is cljs.js-deps/find-classpath-lib which calls cljs.js-deps/parse-js-ns to read a JS file and parse module information from it. Currently the function reads lines before first function declaration and uses a regex to find goog.provide and goog.require calls. Probably Closure Compiler has some built-in functionality to parse files which could be leveraged.

Besides reading module information from files, another question is if using goog.module defined namespaces for traditional/legacy namespaces generated by ClojureScript compiler needs something special. When goog.module is required, goog.require returns the exported object but no global is set. There is however a function to create the globals: https://github.com/google/closure-library/wiki/goog.module:-an-ES6-module-like-alternative-to-goog.provide#how-do-i-use-a-googmodule-from-a-traditional-closure-file

Notes:

  • Can we still assume that goog.requires all occur before first function declaration?
    • Would be fixed by using possible Closure Compiler functionality
    • Class com.google.javascript.jscomp.deps.JsFileParser looks promising
  • "GCL hasn't switched to it so it may be something driven by some users not something that Google uses more broadly" (David at slack)





[CLJS-1995] Possible conflict with automatic aliases for JS modules Created: 02/Apr/17  Updated: 02/Apr/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Thomas Heller Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

https://clojurescript.org/guides/javascript-modules

The hello-es6 example uses a directory to apply :module-type to every file in that directory.

{:file "src" :module-type :es6}

This leads to src/js/hello.js being aliased to the js.hello ns which .cljs files can then :require.

Given a directory structure like this:

{:file "lib-a" :module-type :es6}
{:file "lib-b" :module-type :es6}

.
├── lib-a
│   └── js
│       └── hello.js
├── lib-b
│   └── js
│       └── hello.js

Leads to lib-b silently replacing lib-a as they both claim the js.hello name.

The same issue is present in closure-compliant libs but they typically follow some kind of manual namespacing (ie. goog.string, cljs.core, ...) which ES6/JS libs do not do (and do not even support given their use of relative imports vs absolute imports)

Not sure how to handle this but at the very least there should be some kind of warning that there is a conflicting alias.

Demo here: https://github.com/thheller/hello-es6-conflict






[CLJS-1320] clojure.string/split adds separator matches & failed matches (nil) when the separator is a regex with alternation Created: 26/Jun/15  Updated: 10/Apr/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3308
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: lvh Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

I want to split a string on "; ", and optionally discard a final ";". So, I tried:

(clojure.string/split "ab; ab;" #"(; )|(;$)")

In Clojure, this does what I want:

["ab" "ab"]

In ClojureScript, I get:

["ab" "; " nil "ab" nil ";"]

I'm not sure to what extent this is a platform distinction and to what extent it's a bug. Returning nils and seperators from clojure.string/split's output seems like it's against string.split's contract?



 Comments   
Comment by Erik Assum [ 10/Apr/17 11:12 AM ]

Might not be the answer you want, but Clojurescript uses js' split implementation.
Testing this in the browser you get

> "ab; ab;".split(/(; )|(;$)/)
< ["ab", "; ", undefined, "ab", undefined, ";", ""] (7)
>

from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split

If separator is a regular expression that contains capturing parentheses, then each time separator is matched, the results (including any undefined results) of the capturing parentheses are spliced into the output array. However, not all browsers support this capability.

Which means that to avoid this, you should use non-capturing groups:

(clojure.string/split "ab; ab;" #"(?:; )|(?:;$)")

Which incidentally can be simplified to

(clojure.string/split "ab; ab;" #";(?: |$)")

Which produces the result you're after in both clojure and clojurescript.





[CLJS-1901] Investigate new Google Closure source mapping support Created: 24/Jan/17  Updated: 05/May/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.9.655
Fix Version/s: None

Type: Task Priority: Minor
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Google Closure now contains comprehensive support for (at least from the command line) for source map merging and inline source map generation. We should investigate how reusable this functionality actually is.



 Comments   
Comment by Antonin Hildebrand [ 24/Jan/17 3:30 PM ]

Investigated it a bit, just sharing what I learned so far:

1. historically there used to be a hidden flag `--source_map_input` which could be used to produce source-map-aware error reporting, not source map composition as name would suggest[1]
2. mid 2016, a patch landed[2], which enhanced this for full source map composition
3. by the end of 2016, the feature seems to be public and enabled in command-line tool by default[3][5]
4. as of today, the official source-maps wiki page[4] has not been updated to reflect this latest development

[1] https://github.com/google/closure-compiler/issues/1360#issuecomment-170716968
[2] https://github.com/google/closure-compiler/pull/1971
[3] https://github.com/google/closure-compiler/pull/2008
[4] https://github.com/google/closure-compiler/wiki/Source-Maps
[5] https://github.com/google/closure-compiler/pull/2129

Comment by Antonin Hildebrand [ 24/Jan/17 3:53 PM ]

Closure compiler also newly understands inlined source maps using data URLs in input Javascript files[1].

1. parsing of inline source maps is enabled by default unless `--parse_inline_source_maps=false` is passed, it is independent on `--source_map_input` flag
2. information from `--source_map_input` and inlined source-maps is merged, inlined maps override `--source_map_input`, the last inlined map wins in case of multiple //# sourceMappingURL=<data URL> present [2]

[1] https://github.com/google/closure-compiler/pull/1982
[2] https://github.com/google/closure-compiler/pull/1982#issuecomment-243249065

Comment by Thomas Heller [ 02/May/17 5:23 AM ]

FWIW I added support for this in shadow-build a while ago. It does not need inline source maps to work.

The code can be found here: https://github.com/thheller/shadow-build/blob/master/src/main/shadow/cljs/closure.clj

The relevant bits are .addInputSourceMap on Compiler and .setApplyInputSourceMaps on CompilerOptions.

If everything is properly configured the warnings displayed by Closure will contain an "Originally at:" location which points to the CLJS file.

Closure will also use the input source maps when generating source maps for :advanced builds, so the manual merge done by CLJS at the moment becomes unnecessary. The source maps also appear to be more accurate. Before input source maps I had a few issues where source maps were off by a few lines, but that may have been due to my incorrect source map handling in shadow-build.





[CLJS-2050] js->clj breaks on Objects with the key "v" Created: 24/May/17  Updated: 25/May/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Ian Davis Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

With advanced compilation enabled, a JS Object with the key "v" causes the `(seq? x)` clause of `js->clj` to return true, but since js/Object does not satisfy `ISeqable` the `map` on the following line causes an error. I've identified this issue in the circleci frontend codebase. Working on creating a minimal project test case now.



 Comments   
Comment by Ian Davis [ 24/May/17 8:27 PM ]

Was not able to generate a minimal case. It definitely fails in our repository, but cannot make it fail on a simpler case. Leaving this issue open in case anyone else encounters it, but don't expect any follow up unless there are other reports.

Comment by Thomas Heller [ 25/May/17 1:57 AM ]

The (seq? x) does a protocol check which checks if the given object has a marker property for the protocol. In your case that property was most likely renamed to x.v which then causes a hit.

This was fixed for normal protocols a while back: https://dev.clojure.org/jira/browse/CLJS-1658

But fast-path protocols (ie. ISeq) use a bit check (x.cljs$lang$protocol_mask$partition0$ & (64)) and I assume your value in v satisfies that check?

Comment by David Nolen [ 25/May/17 9:20 AM ]

I believe Thomas's analysis is correct here. I think having the `seq?` and `coll?` checks in `js->clj` was probably ill-considered but changing that will probably introduce a different kind of breakage for a different group of users. You can either provide an externs file for your JS objects and their properties (difficult to do I know if dynamic) or write a simpler custom `js->clj` which only expects JS values (no protocol checks) and use that instead.

Comment by Ian Davis [ 25/May/17 12:15 PM ]

Ok, I figured it was something like that. I considered removing the first three cases, or just reversing the order of the js and protocol checks, but I wasn't entirely sure what kind of breakage that might introduce. If we are just using the modified version in our json parser, it should be fine, right? It seems like those protocol checks are only useful if you have clojure intermixed with the json.





[CLJS-901] Protocolize compiler access to the file system Created: 03/Dec/14  Updated: 18/Nov/16

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Task Priority: Minor
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 4
Labels: None


 Description   

Currently builds are based on files on disk. It is desirable to be able to instead get in memory builds, WebDAV based builds, S3 based builds, etc. Many of these alternative strategies are not in scope for the ClojureScript compiler but this does not mean we should not supply the needed hooks for users to control the behavior.



 Comments   
Comment by Thomas Heller [ 03/Dec/14 9:31 AM ]

This and some other issues opened recently (CLJS-900, CLJS-851, CLJS-899, ...) have some overlap with what I have done in shadow-build [1]. Memory based builds are actually already possible cause it will only touch the disk when asked to, although the API could use some cleanup.

Anyways, might be worthwhile to coordinate these efforts to make CLJS more accessible for everyone.

[1] https://github.com/thheller/shadow-build

Comment by Alan Dipert [ 04/Feb/15 11:36 AM ]

I too think it would be totally awesome to have builds based on sources from disparate places.

One alternative in this spirit I have been thinking about is a "SourceSet" approach. The idea is, instead of teaching CLJS how to consume various place-types directly via protocols, provide an API for building a "SourceSet" value and also a build function that takes the SourceSet as input. I imagine the SourceSet in its simplest form as a map of namespaces to string sources.

With a value to represent sources that is place-agnostic and immutable, 3rd party tools can consume/emit/transform these values before invoking a compile without knowledge or interest in CLJS internals. Conversely CLJS need not be concerned with how SourceSets are constructed.

This whole idea is inspired by boot's FileSets, which work basically the same but can't have the "it fits in memory" assumption.





[CLJS-1473] Require fail on ns/in-ns created namespaces Created: 20/Oct/15  Updated: 21/Oct/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.7.145
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Andrea Richiardi Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: bug
Environment:

3.13.0-65 x86_64 GNU/Linux



 Description   

Just to report that the following does not work at the repl (in Clojure it does):

(ns first.namespace)
(def a 4)
(ns second.es)
(require 'first.namespace) ;; with :reload is the same
java.lang.IllegalArgumentException: Namespace first.namespace does not exist
	at cljs.closure$source_for_namespace.invoke(closure.clj:605)
	at cljs.repl$load_namespace.invoke(repl.cljc:182)
	at cljs.repl$load_dependencies.invoke(repl.cljc:206)
	at cljs.repl$evaluate_form.invoke(repl.cljc:474)
	at cljs.repl$fn__4470$self__4482.invoke(repl.cljc:673)
	at clojure.lang.AFn.applyToHelper(AFn.java:165)
	at clojure.lang.AFn.applyTo(AFn.java:144)
	at clojure.core$apply.invoke(core.clj:630)
	at cljs.repl$wrap_self$g__4450.invoke(repl.cljc:630)
	at cljs.repl$repl_STAR_$read_eval_print__4536.invoke(repl.cljc:854)
	at cljs.repl$repl_STAR_$fn__4542$fn__4551.invoke(repl.cljc:895)
	at cljs.repl$repl_STAR_$fn__4542.invoke(repl.cljc:894)
	at cljs.compiler$with_core_cljs.invoke(compiler.cljc:1146)
	at cljs.repl$repl_STAR_.invoke(repl.cljc:858)
	at cljs.repl$repl.doInvoke(repl.cljc:976)
	at clojure.lang.RestFn.invoke(RestFn.java:410)
	at cljsbuild.repl.rhino$run_repl_rhino.invoke(rhino.clj:8)
	at user$eval4946.invoke(form-init5490341798700416710.clj:1)
	at clojure.lang.Compiler.eval(Compiler.java:6782)
	at clojure.lang.Compiler.eval(Compiler.java:6772)
	at clojure.lang.Compiler.load(Compiler.java:7227)
	at clojure.lang.Compiler.loadFile(Compiler.java:7165)
	at clojure.main$load_script.invoke(main.clj:275)
	at clojure.main$init_opt.invoke(main.clj:280)
	at clojure.main$initialize.invoke(main.clj:308)
	at clojure.main$null_opt.invoke(main.clj:343)
	at clojure.main$main.doInvoke(main.clj:421)
	at clojure.lang.RestFn.invoke(RestFn.java:421)
	at clojure.lang.Var.invoke(Var.java:383)
	at clojure.lang.AFn.applyToHelper(AFn.java:156)
	at clojure.lang.Var.applyTo(Var.java:700)
	at clojure.main.main(main.java:37)

I am available for investigating more and/or taking charge of the issue.



 Comments   
Comment by Andrea Richiardi [ 20/Oct/15 9:31 PM ]

sorry about the mistakes...how to edit?

Comment by Andrea Richiardi [ 21/Oct/15 1:32 PM ]

Confirmed using NodeJs repl:

ClojureScript Node.js REPL server listening on 51885
Watch compilation log available at: out/watch.log
To quit, type: :cljs/quit
cljs.user=> (in-ns 'ns.core)
nil
ns.core=> (def a 3)
#'ns.core/a
ns.core=> (in-ns 's.core.repl)
nil
s.core.repl=> (require 'ns.core)
java.lang.IllegalArgumentException: Namespace ns.core does not exist
	at cljs.closure$source_for_namespace.invoke(closure.clj:605)
	at cljs.repl$load_namespace.invoke(repl.cljc:182)
	at cljs.repl$load_dependencies.invoke(repl.cljc:206)
	at cljs.repl$evaluate_form.invoke(repl.cljc:474)
	at cljs.repl$fn__4583$self__4595.invoke(repl.cljc:673)
	at clojure.lang.AFn.applyToHelper(AFn.java:165)
	at clojure.lang.AFn.applyTo(AFn.java:144)
	at clojure.core$apply.invoke(core.clj:630)
	at cljs.repl$wrap_self$g__4563.invoke(repl.cljc:630)
	at cljs.repl$repl_STAR_$read_eval_print__4649.invoke(repl.cljc:854)
	at cljs.repl$repl_STAR_$fn__4655$fn__4664.invoke(repl.cljc:895)
	at cljs.repl$repl_STAR_$fn__4655.invoke(repl.cljc:894)
	at cljs.compiler$with_core_cljs.invoke(compiler.cljc:1146)
	at cljs.repl$repl_STAR_.invoke(repl.cljc:858)
	at cljs.repl$repl.doInvoke(repl.cljc:976)
	at clojure.lang.RestFn.invoke(RestFn.java:486)
	at user$eval44.invoke(node_repl.clj:10)
	at clojure.lang.Compiler.eval(Compiler.java:6782)
	at clojure.lang.Compiler.load(Compiler.java:7227)
	at clojure.lang.Compiler.loadFile(Compiler.java:7165)
	at clojure.main$load_script.invoke(main.clj:275)
	at clojure.main$script_opt.invoke(main.clj:337)
	at clojure.main$main.doInvoke(main.clj:421)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at clojure.lang.Var.invoke(Var.java:379)
	at clojure.lang.AFn.applyToHelper(AFn.java:154)
	at clojure.lang.Var.applyTo(Var.java:700)
	at clojure.main.main(main.java:37)
Comment by Andrea Richiardi [ 21/Oct/15 1:37 PM ]

I guess it is each repl-env with its -evaluate to be responsible for loading right? Can it be a proble of each and every *load-fn* out there?

Comment by Andrea Richiardi [ 21/Oct/15 2:37 PM ]

I am analyzing `cljs.repl/load-namespace` and it looks like it handles only loading from sources:

line 178 @ clojurescript 1.7.158

 sources (cljsc/add-dependencies
                   (merge (env->opts repl-env) opts)
                   {:requires [(name ns)]
                    :type :seed
                    :url (:uri (cljsc/source-for-namespace
                                 ns env/*compiler*))})

The function `cljs.closure/source-for-namespace` is throwing the exception because of course it cannot find the sources for a manually created namespace.
An idea could be to change `cljs.closure/source-for-namespace` and return nil in case no sources can be found.
Then change `cljs.repl/load-namespace` to check for created namespaces when `souces` is nil.

Mike told me that the namespaces are not reified, so the next question is, is there an atom that contains all the created namespaces?

I am going to wait for input on this, when everybody has time of course.





[CLJS-2018] User supplied externs not loaded with user specified compiler state Created: 25/Apr/17  Updated: 16/Jun/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Jonathan Henry Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

User supplied externs for use with warn-on-infer are only loaded in the 2-arity versions of cljs.closure/build, cljs.build.api/build and cljs.build.api/watch when compiler is nil.

Note: This only affects the warnings that are generated by the analyzer with warn-on-infer; the externs are correctly passed to gclosure.



 Comments   
Comment by Jonathan Henry [ 25/Apr/17 7:34 PM ]

This patch moves the loading of externs from cljs.env/default-compiler-env to cljs.closure/build.

Comment by Jonathan Henry [ 26/Apr/17 12:20 PM ]

Ignore this patch, I just realized this makes it so the built-in externs are no longer loaded for the compiler and analyzer API.

Comment by David Nolen [ 16/Jun/17 9:18 AM ]

I deleted the patch to avoid confusion.





[CLJS-2049] Implicitly require macros from CLJC files - towards Clojure parity Created: 24/May/17  Updated: 24/May/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.9.293
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Dennis Heihoff Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: macro, namespace
Environment:

All



 Description   

When a .cljc file that contains macros is required and aliased in another namespace, macros are not automatically included. In that case the :include-macros flag must be set to true. Since the .cljc file is experienced as a single file one would expect macros to be included just like in Clojure.

David Nolen:

The reason we don't do it automatically already is because it wasn't safe to do so when macro files and runtime files were separate

in the past just because a .clj file and .cljs file had the same name didn't mean anything all - implicitly loading the .clj file was not a good idea.






[CLJS-1722] Upgrade ExceptionInfo to proper deftype Created: 03/Aug/16  Updated: 18/Jun/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Antonin Hildebrand Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None

Attachments: Text File CLJS-1722.patch    
Patch: Code

 Description   

Currently ExceptionInfo is implemented as a raw constructor function which inherits from js/Error with some ad-hoc javascript-level patches to satisfy a tiny subset of deftype functionality (mainly for printing).

Unfortunately this does not play well with cljs-devtools[1]. This problem surfaced when I started playing with ExceptionInfo and cljs-devtools v0.8 which newly supports printing deftypes[2]. ExceptionInfo does not contain getBasis, cljs$lang$type, cljs$lang$ctorStr and similar machinery.

My proposed patch implements ExceptionInfo as a proper deftype and does some patch-work to provide backward compatibility. I'm pretty sure we must not break current contract of ExceptionInfo constructor accepting 3 args and synthesizing other fields on the fly in constructor.

Implementation details:
1) first we define ExceptionInfo as normal deftype (to get a template)
2) then we remember reference to ExceptionInfo in ExceptionInfoTypeTemplate
3) then we redefine ExceptionInfo with raw constructor function which should mimic original behaviour (by scraping newly created js/Error instance, but calling ExceptionInfoTypeTemplate to do proper deftype initialization)
4) then we copy keys from ExceptionInfoTypeTemplate over ExceptionInfo
5) then we set ExceptionInfo's prototype to be ExceptionInfoTypeTemplate's prototype
6) then we fix ExceptionInfo's prototype's constructor to point to our re-defined constructor function
7) then we patch ExceptionInfo's prototype to inherit from js/Error (note this clobbers ExceptionInfoTypeTemplate as well - but we don't care about it)

This effectively gives us properly working ExceptionInfo deftype with redefined constructor function wrapping deftype's constructor for backwards compatibility.
We also patch ExceptionInfo's prototype to inherit from js/Error the same was as original code did.

Note: With working deftype, we can move IPrintWithWriter and toString implementation to the deftype itself.

[1] https://github.com/binaryage/cljs-devtools/issues/23
[2] https://github.com/binaryage/cljs-devtools/releases/tag/v0.8.0



 Comments   
Comment by Thomas Heller [ 04/Aug/16 4:25 AM ]

Why not just add the missing getBasis, cljs$lang$type, cljs$lang$ctorStr bits per set!?

The patch looks like it would mess up advanced compilation although that is just an instinct not something I verified, did you?

Comment by Antonin Hildebrand [ 04/Aug/16 4:44 AM ]

I ran clojurescript tests and I assumed they run also against advanced-mode build. During development when my tests were failing I saw error messages about minified names.

This may seem as a hacky solution, but IMO the original code was also a hack. My hack will stay up-to-date with future changes to deftype implementation. I can imagine people would forget to update this part when touching deftype.

btw. there is another patch coming related to discrepancies between deftype and defrecord. That could have been avoided if defrecord shared common implementation with deftype.

Comment by Thomas Heller [ 04/Aug/16 6:27 AM ]

Closure is usually very strict about re-defining stuff but I guess my instincts were wrong, the tests should cover advanced.

My issue with this is that deftype is for defining Clojure-specific types. ExceptionInfo is not since it inherits from Error, just like you can't have a superclass in Clojure you can't in CLJS. So IF we were to change deftype in the future we might break things in unexpected ways that just re-use deftype but aren't actually deftype.

Yes, you have to do some house-keeping but you can't enforce the rules of deftype when dealing with inheritance.

Just my 2 cents, it has advantages to re-use deftype too (as you suggested).

Comment by Antonin Hildebrand [ 04/Aug/16 6:36 AM ]

Unfortunately I was unable to look up any comments or docs explaining the reasoning why we do that js/Error inheritance there.

My first attempt to "fix" ExceptionInfo was to simply implement it as an ordinary deftype. And that worked just fine (for my tests). Then I tried to re-implement original behaviours on top just to make it 100% compatible.

Comment by Antonin Hildebrand [ 04/Aug/16 12:47 PM ]

Just adding a motivational screenshot:

https://box.binaryage.com/CLJS-1722-example.png

Those yellow warnings are listing which properties are getting copied by gobject/extend call.
The expanded log item is new implementation logged via cljs-devtools v0.8.0.
The last log item is the old implementation logged via cljs-devtools v0.8.0 (cljs-devtools does not recognise ExceptionInfo as CLJS type, but detects IPrintWithWriter and uses it to present the value)





[CLJS-2102] Case fallback (cond) doesn't match consts Created: 19/Jun/17  Updated: 20/Jun/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.9.562
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: A. R Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Reproduce:

(def ^:const ccc 1)
(case 1
  ccc :yes
  :no)
(case 1
  ccc :yes
  :hmm :hmm
  :no)

Second example yields :no because it falls back to cond which doesn't handle the consts properly.



 Comments   
Comment by Kevin Downey [ 20/Jun/17 12:54 PM ]

a related thread https://groups.google.com/d/msg/clojure/u1RZsmjbQ64/p7B9eRwuAQAJ

clojurescript's handling of symbols in case is broken(it diverges from clojure's), but the cond fallback is correct(it matches clojure)

Comment by David Nolen [ 20/Jun/17 2:10 PM ]

As discussed in that thread we're not re-breaking a thing we broke 2 years ago. It's simply not that important and far too late.





[CLJS-2087] Duplicate set/map keys when using characters or quoting Created: 15/Jun/17  Updated: 25/Jun/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.9.293
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: A. R Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Related: CLJS-1587

This ticket deals with the following cases:

{'0 "a", 0 "b", \a "a", "a" "b"}
#{\a "a"}
(hash-set \a "a")
(array-map '0 "a", 0 "b", \a "a", "a" "b")

Potential idea: Use emit-str in cljs.compiler on the keys/set-members and only then check for uniqueness. I'm not sure if this is a good idea though. Anybody have thoughts on this?



 Comments   
Comment by Mike Fikes [ 25/Jun/17 4:01 PM ]

FWIW, tools.reader, used in self-hosted ClojureScript, rejects the first two examples with a diagnostic:

Set literal contains duplicate key: a




[CLJS-1544] cljs.test REPL reload support Created: 13/Jan/16  Updated: 27/Jun/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.7.228
Fix Version/s: 1.9.671

Type: Defect Priority: Minor
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

When adding a test to a test ns that uses cljs.test and re-loading (via require + :reload) that namespace in the REPL after saving the file - invoking run-tests does not include the newly added test.






[CLJS-1419] enhance numeric inference, if + number? test on local var should tag local var in the successful branch Created: 12/Aug/15  Updated: 27/Jun/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.7.145
Fix Version/s: 1.9.671

Type: Enhancement Priority: Minor
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Comments   
Comment by David Nolen [ 12/Aug/15 6:44 AM ]

One small complication is dealing with and as it has an optimizing case.





[CLJS-1412] Add JSDoc type information to individual IFn methods Created: 10/Aug/15  Updated: 27/Jun/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.7.145
Fix Version/s: 1.9.671

Type: Enhancement Priority: Minor
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: type-check


 Description   

Propagate user supplied docstring type information to the various fn arities so that more code may be checked.






[CLJS-1315] Warning on Google Closure enum property access with / Created: 18/Jun/15  Updated: 27/Jun/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.7.145
Fix Version/s: 1.9.671

Type: Defect Priority: Minor
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Edge case in / usage, EventType/CLICK does not trigger a warning. Foo/bar always means that Foo is a namespace, it cannot be used for the static field access pattern common in Java as there's no reflection information in JavaScript to determine this.






[CLJS-1286] REPL environment should be able to provide advice if source mapping fails Created: 23/May/15  Updated: 27/Jun/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.7.145
Fix Version/s: 1.9.671

Type: Defect Priority: Minor
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

For example browser REPL will often need users to supply :host-port, :host, and :asset-path in order to correctly parse files from stacktraces.






[CLJS-1271] Missing warning when assigning namespaces via def Created: 17/May/15  Updated: 27/Jun/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.7.145
Fix Version/s: 1.9.671

Type: Defect Priority: Minor
Reporter: Sebastian Bensusan Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Currently you can assign a Closure namespace to a var without getting a warning.

Minimal sample:

(ns import-names.core
  (:import [goog debug]))

(def debug goog.debug)


 Comments   
Comment by David Nolen [ 29/May/15 12:30 PM ]

The example case is a bit complected. Besides importing a name that matches a def you are also assigning a google closure namespace to a local. This will likely cause problems on its own. We need more information.

Comment by Sebastian Bensusan [ 29/May/15 12:46 PM ]

We should check that :require ed and :import ed namespaces are not used as values and then warn about it.





[CLJS-1237] ns-unmap doesn't work on refers from cljs.core Created: 01/May/15  Updated: 27/Jun/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.7.145
Fix Version/s: 1.9.671

Type: Defect Priority: Minor
Reporter: Chouser Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: ns-unmap

Attachments: Text File 0001-CLJS-1237-ns-unmap-adds-to-namespace-s-excludes.patch     Text File 0002-CLJS-1237-ns-unmap-adds-to-namespace-s-excludes.patch    
Patch: Code

 Description   

In ClojureScript, using ns-unmap on a symbol from cljs.core doesn't exclude it from the current namespace. Note that both a function and a macro still exist, even after unmapping:

To quit, type: :cljs/quit  
cljs.user=> (ns-unmap 'cljs.user 'when) ;; macro
true  
cljs.user=> (ns-unmap 'cljs.user 'not)  ;; function
true  
cljs.user=> (when 1 2)  
2  
cljs.user=> (not false)  
true  

This differs from the behavior of Clojure's ns-unmap. Note the appropriate errors when attempting to use unmapped symbols:

Clojure 1.7.0-beta1
user=> (ns-unmap 'user 'when) ;; macro
nil
user=> (ns-unmap 'user 'not)  ;; function
nil
user=> (when 1 2)
CompilerException java.lang.RuntimeException: Unable to resolve symbol: when in this context, compiling:(NO_SOURCE_PATH:11:1) 
user=> (not false)
CompilerException java.lang.RuntimeException: Unable to resolve symbol: not in this context, compiling:(NO_SOURCE_PATH:12:1) 

Somehow ClojureScript's ns-unmap needs to add the symbol to the current namespace's :excludes set. Note that the def special form does this already (after it displays a warning).

We have two solutions. 0001 extends the ns form's :merge behavior to support :excludes, and then uses this in ns-unmap. If the enhancement to ns isn't wanted, patch 0002 changes ns-unmap to update :excludes directly.



 Comments   
Comment by David Nolen [ 05/May/15 7:23 AM ]

The second patch is preferred. However it seems the second patch is too permissive. The :excludes logic should only be applied if the symbol identifies a core macro or fn.

Comment by Chouser [ 05/May/15 3:46 PM ]

The ns form's own :refer-clojure :exclude accepts arbitrary symbols and adds them to the namespace's :excludes set, which seems like the same permissiveness problem. Do you want a patch that addresses the permissiveness of both ns and ns-unmap in this ticket, or should such a patch go in a new ticket?

Comment by David Nolen [ 05/May/15 4:08 PM ]

New ticket to fix the bug that :exclude doesn't check the symbol list for cljs.core declared vars, and an updated patch here please.





[CLJS-1222] Sequence of a stateful transducer is producing the wrong answer Created: 24/Apr/15  Updated: 27/Jun/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.7.145
Fix Version/s: 1.9.671

Type: Defect Priority: Minor
Reporter: Lucas Cavalcanti Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: bug, cljs, collections
Environment:

OSX 10.10.3, java 1.8.0-ea-b124



 Description   

I'm producing more than one element on the 1-arity of the transducer, and sequence is only considering the last one.

Here is the transducer and the tests that fail for sequence:

(defn sliding-window [n]
  (fn [rf]
    (let [a #js []]
      (fn
        ([] (rf))
        ([result]
         (loop [] ;; Here I'm emitting more than one element
           (when (not-empty a)
             (rf result (vec (js->clj a)))
             (.shift a)
             (recur))))
        ([result input]
         (.push a input)
         (if (== n (.-length a))
           (let [v (vec (js->clj a))]
             (.shift a)
             (rf result v))
           result))))))

;;This test fails! =(
(deftest sliding-window-in-a-sequence
  (is (= [[5 4 3]
          [4 3 2]
          [3 2 1]
          [2 1]
          [1]]
         (sequence (sliding-window 3) [5 4 3 2 1])))

  (is (= [[2 1]
          [1]]
         (sequence (sliding-window 3) [2 1]))))


 Comments   
Comment by Lucas Cavalcanti [ 24/Apr/15 11:18 AM ]

I could make it work by recurring on the result.

([result]
  (loop [res result]
    (if (not-empty a)
      (let [v (vec (js->clj a))]
        (.shift a)
        (recur (rf res v)))
      res)))

even so it's weird that the previous version behaves differently on core.async and sequences in cljs and clj

Comment by David Nolen [ 26/Apr/15 4:04 AM ]

Please demonstrate the problem without core.async. Thanks.

Comment by Lucas Cavalcanti [ 26/Apr/15 7:32 PM ]

Hi,

the last test I posted on the ticket, fails in cljs, but not in clj:

;;This test fails! =(
(deftest sliding-window-in-a-sequence
  (is (= [[5 4 3]
          [4 3 2]
          [3 2 1]
          [2 1]
          [1]]
         (sequence (sliding-window 3) [5 4 3 2 1])))

  (is (= [[2 1]
          [1]]
         (sequence (sliding-window 3) [2 1]))))
Comment by David Nolen [ 27/Apr/15 7:43 AM ]

I've removed the core.async bits from the description to clarify the issue.

Comment by David Nolen [ 10/May/15 2:40 PM ]

The implementation of sliding-window above does not appear to be correct, it doesn't return the result. This ticket needs more information.

Comment by Lucas Cavalcanti [ 10/May/15 3:51 PM ]

As I said on http://dev.clojure.org/jira/browse/CLJS-1222?focusedCommentId=38620&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-38620

changing the 1-arity of the sliding-window to that fixes the transducer.

The point of this ticket now is that the behavior of the same (wrong) transducer in clj (both core.async and sequence) and cljs (core.async) is different than cljs sequence.





[CLJS-1207] Emit a warning if multiple resources found for a ClojureScript namespace Created: 15/Apr/15  Updated: 27/Jun/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.7.145
Fix Version/s: 1.9.671

Type: Enhancement Priority: Minor
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

We should emit a simple warning if a namespace doesn't not appear to be unique on the classpath.






[CLJS-1174] Simple warning if a namespace with dashes not found but a file path with dashes exists Created: 27/Mar/15  Updated: 27/Jun/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.7.145
Fix Version/s: 1.9.671

Type: Enhancement Priority: Minor
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: easy





[CLJS-1159] compiled files with warnings that otherwise don't need recompilation will not emit warnings on the next compile Created: 23/Mar/15  Updated: 27/Jun/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.7.145
Fix Version/s: 1.9.671

Type: Defect Priority: Minor
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: None


 Description   

The aggressive caching approach is odds with warning visibility. It probably makes sense for a compiled file with warnings to always return true for requires-compilation?.






[CLJS-1134] Lift protocols from cljs.closure into cljs.protocols ns Created: 17/Mar/15  Updated: 27/Jun/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.7.145
Fix Version/s: 1.9.671

Type: Task Priority: Minor
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

This is task towards presenting a stable API to users without reaching into the implementation namespaces.






[CLJS-1133] REPL require results in warnings to be emitted twice Created: 17/Mar/15  Updated: 27/Jun/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.7.145
Fix Version/s: 1.9.671

Type: Defect Priority: Minor
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Quick Start Browser REPL with :watch off



 Description   

Run through the Quick Start and go down through to the Browser REPL portion (https://github.com/clojure/clojurescript/wiki/Quick-Start#browser-repl), but exclude the :watch option from repl.clj.

Then further down, where the new symbol is introduced

;; ADDED
(defn foo [a b]
  (+ a b))

instead cause some duplicate symbols to be introduced in order to provoke compiler warnings:

(def a 1)
(def a 1)

(defn foo [a b]
  (+ a b))
(defn foo [a b]
  (+ a b))

Then evaluate the require statement in the tutorial and observe that the warnings are emitted twice:

ClojureScript:cljs.user> (require '[hello-world.core :as hello])
WARNING: a at line 11 is being replaced at line 12 /Users/mfikes/Desktop/hello_world/src/hello_world/core.cljs
WARNING: foo at line 14 is being replaced at line 16 /Users/mfikes/Desktop/hello_world/src/hello_world/core.cljs
WARNING: a at line 11 is being replaced at line 12 /Users/mfikes/Desktop/hello_world/src/hello_world/core.cljs
WARNING: foo at line 14 is being replaced at line 16 /Users/mfikes/Desktop/hello_world/src/hello_world/core.cljs
nil





[CLJS-1125] Simple corrupted compiled file detection Created: 16/Mar/15  Updated: 27/Jun/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.7.145
Fix Version/s: 1.9.671

Type: Enhancement Priority: Minor
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

We should include a line at the end of the file that we check for to determine that the file was not corrupted due to either an incomplete write or a clobbered write. It should be be the SHA of the ClojureScript source it was generated from.






[CLJS-349] cljs.compiler: No defmethod for emit-constant clojure.lang.LazySeq Created: 30/Jul/12  Updated: 27/Jun/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.7.145
Fix Version/s: 1.9.671

Type: Defect Priority: Minor
Reporter: Julien Fantin Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None

Attachments: Text File 0001-CLJS-349-Allow-ISeq-to-be-emitted-by-macros-as-a-con.patch     File fixbug349.diff    

 Description   

The cljs compiler errors when trying to emit-constant for a clojure.lang.LazySeq.

Example : https://www.refheap.com/paste/3901

Here syms is defined as a LazySeq on line 3, then on line 7 it is quoted. The error is included in the refheap.

Emitting a cljs.core.list for this type seems to solve the issue.



 Comments   
Comment by David Nolen [ 31/Aug/12 9:27 AM ]

Can you identify precisely where a LazySeq is getting emitted here? A LazySeq is not literal so this seems like a bug in the macro to me. I could be wrong. Thanks!

Comment by Herwig Hochleitner [ 28/Oct/12 9:31 PM ]

The lazy seq seems to be introduced on line 7, the '~syms form

`(let [mappings# (into {} (map-indexed #(identity [%2 %1]) '~syms))

Clojure allows lazy-seqs to be embedded: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L4538

As an aside: The relevant protocol is not literality, but the print-dup multimethod. Do / Should we have print-dup in CLJS?

Comment by Herwig Hochleitner [ 31/Oct/12 10:10 PM ]

Attached patch 0001 doesn't add a case for LazySeq, but folds two cases for PersistentList and Cons into one for ISeq.

Comment by David Nolen [ 19/Nov/13 9:28 PM ]

This approach seems acceptable but this is an old patch can we update for master?





[CLJS-1644] Recursive protocol method for a record never terminates Created: 23/May/16  Updated: 08/Jul/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.7.228
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Brian Stiles Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Any



 Description   

When extending a protocol for a record, a recursive method can never terminate in some cases.

(defrecord R [a])

(defprotocol P
  (f [x]))

(extend-protocol P
  R
  (f [x]
    (if x
      (recur nil)
      x))
  default
  (f [x]
    (if x
      (recur nil)
      x)))

(prn (f 1))        ; #1
(prn (f (R. 1)))   ; #2

prn call #1 prints nil as expected, but prn call #2 never terminates.

It looks like the compiler creates a variable assigned to this within the while loop such that the test of "x" is always really testing this when it should be testing the value of x passed in by the call to recur.

Note, I'm testing ClojureScript 1.8.51. The "Affects Version/s" field above only gives 1.7.228 as the most recent version.



 Comments   
Comment by Brian Stiles [ 23/May/16 4:14 AM ]

Actually, "always really testing 'this' when it should be testing the value of x passed in by the call to recur" is only true if the type of the value represented by x remains the same. If, as in the example, the type changes, the call should be dispatched to the properly matching method implementation.

This seems to behave as expected in Clojure.

Comment by David Nolen [ 08/Jul/17 10:58 AM ]

Confirmed with Mike Fikes this is still an issue on master even with the recur enhancements.





[CLJS-2237] Defrecord does not escape field names matching JS keywords (with/in/...) Created: 14/Jul/17  Updated: 14/Jul/17

Status: Reopened
Project: ClojureScript
Component/s: None
Affects Version/s: 1.9.660, 1.9.671
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Nikita Prokopov Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Defrecord produces code that's incompatible with ECMASCRIPT3 language:

(defrecord Query [with in])
Compiling "target/main.js" from ["src"]...
Jul 14, 2017 6:58:14 PM com.google.javascript.jscomp.LoggerErrorManager println
WARNING: /Users/prokopov/work/cljs-test/target/cljsbuild-compiler-0/cljs_test/core.js:117: WARNING - Keywords and reserved words are not allowed as unquoted property names in older versions of JavaScript. If you are targeting newer versions of JavaScript, set the appropriate language_in option.
return (!((other13203 == null))) && ((this13202__$1.constructor === other13203.constructor)) && (cljs.core._EQ_.cljs$core$IFn$_invoke$arity$2(this13202__$1.with,other13203.with)) && (cljs.core._EQ_.cljs$core$IFn$_invoke$arity$2(this13202__$1.in,other13203.in)) && (cljs.core._EQ_.cljs$core$IFn$_invoke$arity$2(this13202__$1.__extmap,other13203.__extmap));
                                                                                                                                                            ^

Jul 14, 2017 6:58:14 PM com.google.javascript.jscomp.LoggerErrorManager println
WARNING: /Users/prokopov/work/cljs-test/target/cljsbuild-compiler-0/cljs_test/core.js:117: WARNING - Keywords and reserved words are not allowed as unquoted property names in older versions of JavaScript. If you are targeting newer versions of JavaScript, set the appropriate language_in option.
return (!((other13203 == null))) && ((this13202__$1.constructor === other13203.constructor)) && (cljs.core._EQ_.cljs$core$IFn$_invoke$arity$2(this13202__$1.with,other13203.with)) && (cljs.core._EQ_.cljs$core$IFn$_invoke$arity$2(this13202__$1.in,other13203.in)) && (cljs.core._EQ_.cljs$core$IFn$_invoke$arity$2(this13202__$1.__extmap,other13203.__extmap));
                                                                                                                                                                            ^

Jul 14, 2017 6:58:14 PM com.google.javascript.jscomp.LoggerErrorManager println
WARNING: /Users/prokopov/work/cljs-test/target/cljsbuild-compiler-0/cljs_test/core.js:117: WARNING - Keywords and reserved words are not allowed as unquoted property names in older versions of JavaScript. If you are targeting newer versions of JavaScript, set the appropriate language_in option.
return (!((other13203 == null))) && ((this13202__$1.constructor === other13203.constructor)) && (cljs.core._EQ_.cljs$core$IFn$_invoke$arity$2(this13202__$1.with,other13203.with)) && (cljs.core._EQ_.cljs$core$IFn$_invoke$arity$2(this13202__$1.in,other13203.in)) && (cljs.core._EQ_.cljs$core$IFn$_invoke$arity$2(this13202__$1.__extmap,other13203.__extmap));
                                                                                                                                                                                                                                                  ^

Jul 14, 2017 6:58:14 PM com.google.javascript.jscomp.LoggerErrorManager println
WARNING: /Users/prokopov/work/cljs-test/target/cljsbuild-compiler-0/cljs_test/core.js:117: WARNING - Keywords and reserved words are not allowed as unquoted property names in older versions of JavaScript. If you are targeting newer versions of JavaScript, set the appropriate language_in option.
return (!((other13203 == null))) && ((this13202__$1.constructor === other13203.constructor)) && (cljs.core._EQ_.cljs$core$IFn$_invoke$arity$2(this13202__$1.with,other13203.with)) && (cljs.core._EQ_.cljs$core$IFn$_invoke$arity$2(this13202__$1.in,other13203.in)) && (cljs.core._EQ_.cljs$core$IFn$_invoke$arity$2(this13202__$1.__extmap,other13203.__extmap));
                                                                                                                                                                                                                                                               ^

Jul 14, 2017 6:58:14 PM com.google.javascript.jscomp.LoggerErrorManager printSummary
WARNING: 0 error(s), 4 warning(s)
Successfully compiled "target/main.js" in 6.224 seconds.

Probably there should be some name escaping happening? I see that (defn with []) is compiled as cljs-test.core.with$. Should we do the same for records?



 Comments   
Comment by David Nolen [ 14/Jul/17 12:19 PM ]

The problem has less to do with records than how to handle reserved names. As far as I'm concerned the Closure warnings are sufficient, but if somebody wants to devise a warning patch that warns on using reserved fields names on deftpye/record when the output language is ES3, then be my guest.

Comment by David Nolen [ 14/Jul/17 12:20 PM ]

Related CLJS-871

Comment by Nikita Prokopov [ 14/Jul/17 12:37 PM ]

Is there any reason why CLJS defaults to language_in=ES3? Shouldn’t CLJS lock in the version of JS it outputs? As I understand, programmers have no control over how JS looks, but CLJS compiler has knowledge and control over what version of JS it outputs (and feeds into Closure)? In other words, why not set language_in to ES5 by default?





[CLJS-2252] Self-host: :redef-in-file doesn't trigger for bootstrapped Created: 16/Jul/17  Updated: 16/Jul/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.9.671
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: bootstrap


 Description   

If you redefine a symbol in a file and require that file using self-hosted ClojureScript, the :redef-in-file diagnostic doesn't trigger.

It is difficult to create a minimal repro for this, as it requires a setup that loads files. (Perhaps one can be made with the script/test-self-parity infrastructure).

It appears that this can be resolved by setting ana/file-defs at the right places and unsetting it at the right async completion points.






[CLJS-2074] Compiler option to ignore JS files provided by :foreign-libs Created: 06/Jun/17  Updated: 07/Jun/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Thomas Heller Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

It is increasingly common that people want to use JS packages not provided by :foreign-libs. Many CLJS libs however are built on the assumption that you are using :foreign-libs.

Om, Reagent and others expect cljsjs.react to provide a global js/React. Currently users need to work around [1] those :foreign-libs dependencies by using :exclusions in lein or boot and by creating empty stub files to ensure that the cljsjs.react namespace still exist so the libraries can be compiled

This CLJSJS pull request [2] wants to provide those empty stub files in a surrogate package since work around this has become to common. As detailed in the PR comments I think this is a dangerous precedent and that we should come up with a better solution.

The simplest way forward would be to add a compiler option to just keep all (or some) :foreign-libs from being included in the build. The externs are still useful but the JS could just be ignored.

The better solution probably involves using the JS packages by their actual name (via https://dev.clojure.org/jira/browse/CLJS-2061) so the need for cljsjs alias packages goes away.

[1] http://blob.tomerweller.com/reagent-import-react-components-from-npm
[2] https://github.com/cljsjs/packages/pull/1192






[CLJS-1559] Closure :libs ignored Created: 05/Feb/16  Updated: 05/Feb/16

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.7.228
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Dominykas Mostauskis Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: None


 Description   

:libs compilation option doesn't work. Whether specifying directories, or specific files. If trying to `import` one of the js classes (properly namespaced with `goog.provide`) into clojurescript, compilation fails with "no such namespace". If the libs code is not referenced in clojurescript, it compiles, and the output directory does not contain the libs js files.

Compilation options:

(cljs.closure/build
    "src/main/clojurescript"
    {:main 'example.core
     :libs ["/src/main/javascript/"]
     :optimizations :none
     :output-dir "js"
     :output-to "js/main.js"
     :source-map true
     :asset-path "/js"
     })

Javascript file:

goog.provide("test.Test");

test.Test = function(x) {
  this.x = x;
};


 Comments   
Comment by Mike Fikes [ 05/Feb/16 1:51 PM ]

Hi Dominykas, is the absolute path intentional? I suspect the intent was to not have the leading /.

Comment by Dominykas Mostauskis [ 05/Feb/16 2:01 PM ]

I made this typo when posting. On my setup paths are relative to project root.

Comment by David Nolen [ 05/Feb/16 2:38 PM ]

As far as I know quite a few people rely on this functionality. Please provide a complete minimal example or this issue will be closed. All source should be in the ticket or in this comment thread, no external links. Thanks.

Comment by Dominykas Mostauskis [ 05/Feb/16 3:50 PM ]

Can't reproduce. Tips would be appreciated. Banging my head against the wall here.





[CLJS-1485] Error when requiring `goog` namespace in a ns declaration Created: 10/Nov/15  Updated: 27/Jun/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.7.145
Fix Version/s: 1.9.671

Type: Defect Priority: Minor
Reporter: Avicenna Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

I wanted to use functions from goog namespace although--as I found out later, I didn't have to because goog is already exists in my namespace. So, I put (:require [goog]) in a ns declaration. Then, when I tried to reload that particular namespace by doing :require :reload in a cljs repl, I got:

Error: Namespace "x.x.x" already declared.

Doing :require :reload again in the cljs repl makes the repl throws

Error: Namespace "cljs.user" already declared.
(NO_SOURCE_FILE)
(out/goog/base.js:273:40)

I tested the steps below using clojurescript 1.7.145 and 1.7.170.

Here are the steps to reproduce which are taken from clojurescript quickstart-browser repl section:

1. Download the standalone clojurescript 1.7.170 jar https://github.com/clojure/clojurescript/releases/download/r1.7.170/cljs.jar

2. Create a directory hello_world and copy the JAR into that directory, then from inside the hello_world directory:

mkdir -p src/hello_world;touch repl.clj;touch index.html;touch src/hello_world/core.cljs

3. repl.clj content

(require 'cljs.repl)
(require 'cljs.build.api)
(require 'cljs.repl.browser)

(cljs.build.api/build "src"
  {:main 'hello-world.core
   :output-to "out/main.js"
   :verbose true})

(cljs.repl/repl (cljs.repl.browser/repl-env)
  :watch "src"
  :output-dir "out")

4. index.html content

<html>
    <body>
        <script type="text/javascript" src="out/main.js"></script>
    </body>
</html>

5. src/hello_world/core.cljs content

(ns hello-world.core
  (:require [clojure.browser.repl :as repl]))

(defonce conn
  (repl/connect "http://localhost:9000/repl"))

(enable-console-print!)

(println "Hello world!")

(defn foo [a b]
  (+ a b))

6. run clojurescript repl

java -cp cljs.jar:src clojure.main repl.clj

7. Open http://localhost:9000 in browser (I use google chrome). Open javascript console.

8. enter expression below in the clojurescript repl

(require '[hello-world.core :as hello] :reload)

10. Look the browser javascript console. Nothing new shown.

11. Quit from the repl using :cljs/quit

12. Add [goog] in ns declaration in src/hello_world/core.cljs so that the content of the file becomes:

(ns hello-world.core
  (:require [clojure.browser.repl :as repl]
            [goog]))

(defonce conn
  (repl/connect "http://localhost:9000/repl"))

(enable-console-print!)

(println "Hello world!")

(defn foo [a b]
  (+ a b))

13. Run the clojurescript repl again

java -cp cljs.jar:src clojure.main repl.clj

14. Now refresh the http://localhost:9000 in browser. Make sure the javascript console stays open.

13. enter expression below in the clojurescript repl

(require '[hello-world.core :as hello] :reload)
;;=> nil

it just returns nil

15. See the javascript console, it shows

Uncaught Error: Namespace "hello_world.core" already declared.

16. Executing this expression again (require '[hello-world.core :as hello] :reload) shows nothing new in the browser's javascript console while the clojurescript repl throws

Error: Namespace "cljs.user" already declared.
(NO_SOURCE_FILE)
(out/goog/base.js:273:40)





[CLJS-434] ClojureScript compiler prepends "self__" to defmulti forms when metadata in form of ^:field. Created: 01/Dec/12  Updated: 27/Jun/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.7.145
Fix Version/s: 1.9.671

Type: Defect Priority: Minor
Reporter: Andrew Mcveigh Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: bug
Environment:

Mac OS X (10.7), java version "1.6.0_37", leiningen 2 preview 10, cljsbuild 0.2.9.
clojure/clojurescript master 01 December 2012 - 5ac1503



 Description   

Using the def form, with the specific metadata ^:field causes the cljs compiler
to prepend "self__" to the output js form.

The browser (latest chrome/firefox) does not recognize "self__".

Test Case: Tested against master: 5ac1503
-------------

(ns test-def)

(def ^:foo e identity)
e
; test_def.e = cljs.core.identity;
; test_def.e;

(def ^:field f identity)
f
; test_def.f = cljs.core.identity;
; self__.test_def.f;
; Uncaught ReferenceError: self__ is not defined

https://gist.github.com/4185793



 Comments   
Comment by Brandon Bloom [ 01/Dec/12 5:37 PM ]

code tags

Comment by David Nolen [ 20/Jan/13 12:54 AM ]

This one is a bit annoying. We should probably use namespaced keywords internally.





[CLJS-2329] REPL should not error out if quote is missing on string require Created: 18/Aug/17  Updated: 18/Aug/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Andrea Richiardi Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

At the REPL, the following should not happen I think, cause it feels unidiomatic:

(require "something") ;; there is no quote before the apices

----  Could not Analyze  <cljs form>   line:1  column:1  ----

  Library name must be specified as a symbol in :require / :require-macros; offending spec: ["something"] at line 1 <cljs repl>

  1  (require '"something")
     ^--- 

----  Analysis Error  ----

Minor, solvable with:

(require '"something") ;; quote before the apices





[CLJS-2359] Improve cljs.test runtime error reporting Created: 13/Sep/17  Updated: 13/Sep/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Andrea Richiardi Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

It would be an awesome addition to improve the reporter so that

ERROR in (test-hydrate-saladman) (TypeError:NaN:NaN)
Uncaught exception, not in assertion.
expected: nil
  actual: #object[TypeError TypeError: Cannot read property 'call' of null]

Ran 1 tests containing 1 assertions.
0 failures, 1 errors.

would display the full stack trace of the runtime error whenever it happens.
At the moment a user is left on its own with no location, no hints whatsoever.






[CLJS-2366] :arglists inconsistency in cljs Created: 18/Sep/17  Updated: 24/Sep/17

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.9.908
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: David Goldfarb Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

n/a



 Description   

ClojureScript does not seem to fully support setting :arglists meta-data to a function. In particular, it seems to fail when the real parameter list contains an '&'.

In Clojure,

(:arglists (meta (defn f {:arglists '([x])} [& a] a)))

returns ([x]). But, in ClojureScript, it returns ([& a])

Note that simpler forms do work correctly:

(:arglists (meta (defn f {:arglists '([x])} [a] a)))

returns ([x]) in both environments.

(Tested in in ClojureScript 1.9.908 and Clojure 1.9.0-alpha17)



 Comments   
Comment by David Goldfarb [ 24/Sep/17 3:57 AM ]

Looks like this is a duplicate of https://dev.clojure.org/jira/browse/CLJS-2351


<