<< 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-364] compiler needs to put all args of an invocation after 20 into an array-seq Created: 29/Aug/12  Updated: 29/Aug/12

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-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-2399] :foreign-libs with module conversion does not works properly (possible regression) Created: 16/Nov/17  Updated: 16/Nov/17

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






[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-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: 1
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-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-2665] Port clojure.spec.test.alpha/enumerate-namespace Created: 15/Mar/18  Updated: 15/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


 Description   

Make ClojureScript consistent with https://github.com/clojure/spec.alpha/commit/452a916a0842cb413acd6d177e5bbc4b323bb058






[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-2735] Refine doc string for defmulti Created: 11/Apr/18  Updated: 11/Apr/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: docstring


 Description   

CLJ-835 but for ClojureScript.

Perhaps we can copy Clojure's current docstring over en masse, replacing "Clojure" references to "ClojureScript", and ensuring that it is accurate for ClojureScript's defmulti semantics / behavior.






[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-2738] Can't use aws-amplify or aws-sdk with npm-deps Created: 15/Apr/18  Updated: 05/May/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: 3
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.





[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-2725] Doc on spec keywords Created: 05/Apr/18  Updated: 05/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: 1
Labels: None


 Description   

For example, in Clojure:

user=> (doc :clojure.core.specs.alpha/arg-list)
-------------------------
:clojure.core.specs.alpha/arg-list
Spec
  (and vector? (cat :args (* :clojure.core.specs.alpha/binding-form) :varargs (? (cat :amp #{(quote &)} :form :clojure.core.specs.alpha/binding-form))))
nil





[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-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: 0
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-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-2781] Validate `:global-exports` 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: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Currently we don't validate `:global-exports`. It must map known provides to some symbol that represents a JavaScript global var.






[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-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-1726] demunge is too agreesive and incorrect in some cases Created: 04/Aug/16  Updated: 04/Aug/16

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


 Description   

I have implemented some "demunging" logic in cljs-devtools (and dirac) to present original user-friendly names in UI.

During my testing I spotted some wrong edge-cases and incorrect behaviours of demunge:

1) it is too aggressive in replacing dollars - some dollars can be "real" dollars as part of original name
2) it does not revert js-reserved? transformation applied during munging
3) it is oblivious to underscores/dashes - some underscores were "real" underscores before munging
(this may be not complete)

I have worked around those issues on my side and implemented some heuristics[1] based on context, but it is far from perfect.

I'm not sure how to properly fix those, so I wanted to open a ticket with discussion. Maybe people will have some clever ideas.

Currently munging is lossy and we probably don't want to touch it for compatibility reasons.
Maybe we could mark original underscores and dollars in some way, so demunge could properly skip them.

1) One strategy could be to use some (rare) unicode characters, but that would be problematic for people to type.
2) Another strategy could be to escape original dollars and underscores somehow (using more dollars and underscores .
3) Better ideas?

[1] https://github.com/binaryage/cljs-devtools/blob/52899e61e33373df36be8dcb23c69377936821b2/src/lib/devtools/munging.cljs#L154-L185






[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-981] Better benchmarking infrastructure Created: 17/Jan/15  Updated: 12/Feb/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: 0
Labels: newbie


 Description   

We should use ProcessBuilder to run the various benchmark scripts and control which benchmarks we test and which engines we run. Benchmarks should produce EDN data that can be written to a file, loaded into Incanter, etc.






[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-1917] `case` doesn't handle matching against lists Created: 28/Jan/17  Updated: 28/Jan/17

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

Type: Defect Priority: Minor
Reporter: António Nuno Monteiro Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

The following works in Clojure but not ClojureScript

(let [foo '(:a :b)]
  (case foo
    '(:a :b) :works))





[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-1963] cljs.analyzer/load-core is called for every analyzed form Created: 01/Mar/17  Updated: 25/Jun/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   

In cljs.analyzer/analyze-form the load-core fn is called. load-core guards against doing its work multiple times. It then always calls (intern-macros 'cljs.core), which also checks whether it was called before. This ends up doing the checks very often. load-core should probably be called in a less frequent manner.

Performance impact is very minimal but I did a quick test in my work project and load-core is called 416671 times there (without cache) when 1 would be enough.



 Comments   
Comment by Mike Fikes [ 25/Jun/17 4:22 PM ]

Previously, it used to not always call (intern-macros 'cljs.core), with this changing with this commit: https://github.com/clojure/clojurescript/commit/7025bd212fb925cb90db680aa7a5eb3f4c0de4bb





[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-2209] case docstring should explain constants may be evaluated (cljs only) Created: 10/Jul/17  Updated: 10/Jul/17

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

Type: Enhancement Priority: Minor
Reporter: Phill Wolf Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: docstring

Approval: Vetted

 Description   

The ClojureScript docstring for case says, "The test-constants are not evaluated." But that statement is not complete. The ClojureScript "Differences from Clojure" page <https://www.clojurescript.org/about/differences> says ":const metadata: ... causes case test constants which are symbols resolving to ^:const Vars to be inlined with their values". The case docstring should reflect that. Related discussion at <https://groups.google.com/d/msg/clojure/u1RZsmjbQ64/p7B9eRwuAQAJ>.






[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-2257] Expand dotted symbols into field accesses in the analyzer Created: 17/Jul/17  Updated: 17/Jul/17

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

Type: Enhancement Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Currently, there is a lot of implicit information in a :var node in the analyzer around dotted symbols.

The :name of a :var node can contain implicit field accesses, and this information must be manually disambiguated with every new tool that consumes the CLJS AST (like core.typed).

A solution might be to expand specific dotted :var nodes into :dot nodes containing a :var node. Locals in particular might benefit from this transformation, would others? (Global variables, js/* variables)






[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





[CLJS-2380] deftype/defrecord with Object resolves incorrectly Created: 08/Oct/17  Updated: 08/Oct/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   

Whenever any deftype/defrecord defines methods on Object the CLJS compiler will emit an invalid type annotation which Closure complains about when running with type checking enabled.

(ns demo.type)

(deftype Foo [a b]
  Object
  (foo [this x]
    x))

produces this JS

/**
* @constructor
 * @implements {demo.type.Object}
*/
demo.type.Foo = (function (a,b){
this.a = a;
this.b = b;
});

produces the warning

Bad type annotation. Unknown type demo.type.Object

Looking at the analyzer data suggests that it indeed resolves incorrectly.

...
 :defs
 {Foo
  {:num-fields 2,
   :protocols #{demo.type/Object},
   :name demo.type/Foo,
   :file "demo/type.cljs",
   :end-column 13,
   :type true,
   :column 10,
   :line 3,
   :record false,
   :end-line 3,
   :skip-protocol-flag nil},

Not entirely sure how this bypasses checks but it might be a sign that there is an overly general check for Object which does not check the namespace.

AFAICT there are no bad effects on the CLJS analyzer/compiler. Closure does complain when type checking is enabled but otherwise seems unaffected.

Not yet sure where the issue starts, but looks like cljs.analyzer/resolve-var not correctly resolving Object without an ns, via [1].

[1] https://github.com/clojure/clojurescript/blob/998933f5090254611b46a2b86626fb17cabc994a/src/main/clojure/cljs/core.cljc#L1669-L1673






[CLJS-2381] Race condition in cljs.analyzer/load-core Created: 10/Oct/17  Updated: 10/Oct/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   

There is a race condition in cljs.analyzer/load-core.

#?(:clj
   (defn load-core []
     (when (not @-cljs-macros-loaded)
       (reset! -cljs-macros-loaded true)
       (if *cljs-macros-is-classpath*
         (locking load-mutex
           (load *cljs-macros-path*))
         (locking load-mutex
           (load-file *cljs-macros-path*))))
     (intern-macros 'cljs.core)))

When 2+ threads with independent cljs.env/*compiler* bindings call load-core at the same time only one will trigger the actual load and the others will proceed directly to intern-macros and begin interning the macros into their compiler env. Since the load of the first thread may not yet be finished with loading the actual cljs.core macros the second thread will have an incomplete set of macros in its compiler env.

Related: https://dev.clojure.org/jira/browse/CLJS-1963






[CLJS-1990] Clojurescript programs targeting nodejs should support global installation Created: 28/Mar/17  Updated: 24/Apr/17

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

Type: Enhancement Priority: Minor
Reporter: Greg Haskins Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: None

Attachments: Text File 0001-CLJS-1990-Use-module-relative-__dirname-for-bootstra.patch    

 Description   

The top-level entry point in a :target :nodejs application uses $CWD relative paths to load the bootstrapping. See "path.resolve('.')" here: https://github.com/clojure/clojurescript/blob/296d0a69340e832b92ed742b3cd0304a06bea27f/src/main/clojure/cljs/closure.clj#L1460 for example.

This works fine for a local build, but is problematic when we try to globally install clojurescript (such as via 'npm install -g') because it requires the caller $CWD to be something that is likely to be unnatural (e.g. /usr/lib/node_modules/$pkg). Suggested fix is to replace "path.resolve('.')" with "__dirname".



 Comments   
Comment by Matt Lee [ 24/Apr/17 2:34 AM ]

Also see: CLJS-1444





[CLJS-1444] Node.js shim requires `node` invocation to be in the same directory as shim script Created: 10/Sep/15  Updated: 13/Oct/17

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

Type: Defect Priority: Minor
Reporter: Martin Klepsch Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: None

Attachments: Text File 0001-In-bootstrapping-code-use-__dirname-to-calculate-pat.patch    

 Description   

Don't have time to provide a proper repro now but the basic issue can be illustrated by this:

~/c/boot-cljs-example (master=) node target/main.js
module.js:338
    throw err;
          ^
Error: Cannot find module '/Users/martin/code/boot-cljs-example/out/goog/bootstrap/nodejs.js'
    at Function.Module._resolveFilename (module.js:336:15)
    at Function.Module._load (module.js:278:25)
    at Module.require (module.js:365:17)
    at require (module.js:384:17)
    at Object.<anonymous> (/Users/martin/code/boot-cljs-example/target/main.js:6:1)
    at Module._compile (module.js:460:26)
    at Object.Module._extensions..js (module.js:478:10)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Function.Module.runMain (module.js:501:10)
~/c/boot-cljs-example (master=) cd target/
~/c/b/target (master=) node main.js
Starting...

This is compiled with boot because that was what I had at hand right now. The compiled shim looks like this:

var path = require("path");
try {
    require("source-map-support").install();
} catch(err) {
}
require(path.join(path.resolve("."),"out","goog","bootstrap","nodejs.js"));
require(path.join(path.resolve("."),"out","cljs_deps.js"));
goog.global.CLOSURE_UNCOMPILED_DEFINES = {"cljs.core._STAR_target_STAR_":"nodejs"};
goog.require("boot.cljs.main");
goog.require("cljs.nodejscli");

The problem here is that path.resolve(".") will return the directory the node command was invoked in and not the directory of the shim. (See the "Cannot find module..." error above)

A solution could be to use __dirname which always resolves to the directory of the current file. This might result in some breakage for existing setups.



 Comments   
Comment by Sebastian Bensusan [ 14/Oct/15 11:31 AM ]

I have a proposed solution but I fear that supporting "run from anywhere" adds essential complexity to the resulting code. My thought process:

1. Relative paths are desirable to produce "context free code." If the user chooses absolute paths, then that behavior is respected and there's nothing to handle (no "path algebra") .

2. When dealing with relative paths, the whole system needs to establish a "frame of reference", a root path. The ClojureScript compiler assumes the path from which it is compiling to be that frame of reference, which usually coincides with the top root of the project. Though arbitrary, it is the only choice that makes sense.

3. The frame of reference is not explicit anywhere in the code, since it is defined as ".". If it were explicit, it would reveal context, as in "/home/some-user/their-folder/this-project/".

4. When we approach the code from another reference point (executing the script from another directory), we first need to find the original compiler path (reference point,) and then resolve all paths from there. The compiler uses `cljs.closure/path-relative-to` for this purpose.

Path algebra:
compiler-path = __dirname - output-to

Node.js

var compiler-path = __dirname.replace(output-to, "")
path.resolve (compiler-path, output-dir, "goog", "base.js")
path.resolve (compiler-path, output-dir, "cljs_deps.js")

which assumes that if output-to was given relatively, then output-dir is also relative. If they are not in sync, more work needs to be done to keep them that way.

It's not up to me to decide if the extra complexity is worth the use-case. I actually hope there is a simpler solution to solve this that I'm not seeing.

Comment by Karol Majta [ 14/Mar/16 10:43 AM ]

I find this behavior really weird and would opt for switching to __dirname. I am also not sure i fully understand consequences of such switch (I have little cljs experience, speaking more from the perspective of nodejs user). My point is: current behavior renders clojurescript hard to use for commandline and desktop applications (namely electron).

For command line and desktop applications assumptions about CWD cannot be made. For now i run my applications through a bootstrap script JS script:

process.chdir(__dirname);
require('./target/out');

I am lucky that my code does not have to use the real CWD, but it's a hack more than a real solution.

Speaking from nodejs perspective:

1. Using absolute paths is considered a bad practice anyway.
2. Nodejs programs that don't use external packages (don't depend on node_modules) can be run from any CWD
3. Nodejs programs that do depend on node_modules will break if run from a different directory than the one containing node_modules, but this is expected behavior.

Comment by J. Pablo Fernández [ 26/Jan/17 5:42 AM ]

I just run into this problem when trying to develop an Electron application. The way it's working right now is essentially unpackageable. I think it would be nice to have this behavior even as an option and I'm happy to work on a patch.

Comment by J. Pablo Fernández [ 26/Jan/17 5:57 AM ]

As far as I can see, this is the relevant code:

https://github.com/clojure/clojurescript/blob/cdaeff298e0f1d410aa5a7b6860232270d287084/src/main/clojure/cljs/closure.clj#L1410-L1411

Comment by J. Pablo Fernández [ 26/Jan/17 6:15 AM ]

A potential workaround seems to use :simple optimization.

Comment by Matt Lee [ 21/Apr/17 12:02 PM ]

I have also just hit this issue in an electron app that I'm building. @pupeno did you get anywhere with your offer to work on a patch? I too would be happy to look in to a patch for this. Although I think I'll need some pointers to get started.

Comment by Matt Lee [ 22/Apr/17 5:36 AM ]

From a quick experiment this morning it looks like replacing path.resolve(".") with __dirname at https://github.com/clojure/clojurescript/blob/aa5f001300e9aebd976cb180f5b7ccb37fcb6898/src/main/clojure/cljs/closure.clj#L1460-L1461 works for a couple of simple electron and node apps. By work I specifically mean that the error doesn't occur even when the app is started from a current working directory that is different to the compilation directory, i.e. the code is path independent.

I'll attach a patch for this once I've done some more complete testing. Before then any feedback on this approach would be appreciated.

Comment by Matt Lee [ 23/Apr/17 1:51 AM ]

Attaching patch for the suggested fix of using __dirname instead of "." in the generated script. I have tested this with nodejs 6.10.0 and electron 1.6.5.

Comment by Matt Lee [ 24/Apr/17 2:34 AM ]

Also see: CLJS-1990

Comment by Matthias Nehlsen [ 13/Oct/17 5:19 PM ]

Having the same problem where I can't use optimization :none when packaging with electron-builder. Any chance to accept the suggested patch? Thanks!





[CLJS-2062] js->clj throws "No protocol method IEmptyableCollection.-empty..." Created: 29/May/17  Updated: 31/Oct/17

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

Type: Defect Priority: Minor
Reporter: Phill Wolf Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

js->clj says

(cond

    [...]
                
    (coll? x)
    (into (empty x) (map thisfn x))

The gap is that (coll? x) checks for ICollection, while (empty x) requires IEmptyableCollection. When x passes the first test but fails the second, js->clj throws "Error: No protocol method IEmptyableCollection.-empty defined for type : [object Object]."

Inasmuch as js->clj is recursive through Javascript objects that tend to contain everything but the kitchen sink, it is inevitably a matter of best effort rather than high principle. In a word, this is no place to split hairs. If the collection is not emptyable, I expect js->clj to make some effort to preserve order but not type: use a vector!



 Comments   
Comment by Rohit Aggarwal [ 30/May/17 12:02 PM ]

Phill Wolf can you give a concrete failing case?

Comment by John Szakmeister [ 30/Oct/17 2:57 PM ]

It's hard to give a concrete case here--it seems to only really come out with advanced compilation. I had a routine that was returning something like this from a server: {"Br": 0, "B": 100, "P": 1000} as JSON. js->clj would trip generate the "no protocol method" error mentioned in the description on this. I found that if I moved this snippet:

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

ahead of this snippet:

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

that the error went away--I'm not sure if it's the right thing to do though. I suspect that the keys are somehow colliding again with known things, and something is being treated like a collection when it is not. Then, when (empty x) is called, we fail because we the object doesn't implement the required protocol.

I thought this kind of situation was fixed in the past by CLJS-1658 and 7e15b1f2b894d93ef94ff86d75226f1fd3919580, but maybe something else is going on that we're hitting false positives again.

Comment by Thomas Heller [ 30/Oct/17 4:20 PM ]

This is probably not fixable without breaking the semantics of js->clj for someone else. At least I can't think of something easy.

Here is a short reproduction of whats happening:

  • coll? checks ICollection which is a fast-path protocol
  • fast-path protocols do a bit check, instead of the previously fixed sentinel check
  • bit check is done on a property named cljs$lang$protocol_mask$partition0$ which gets shortened by Closure to something unknown. Given the "short" keys in your example Object that is very likely to conflict given that Closure starts with a,b,c,...

This can be reproduced in the Node REPL:

[6:1]~cljs.user=> (def obj #js {"cljs$lang$protocol_mask$partition0$" 8})
#'cljs.user/obj
[6:1]~cljs.user=> (coll? obj)
true
[6:1]~cljs.user=> (empty obj)
eval error Error: No protocol method IEmptyableCollection.-empty defined for type object: [object Object]

One easy fix is to just forget about js->clj and use something that only supports JSON values and doesn't use protocols.

I wrote one you can use here:
https://github.com/thheller/shadow-cljs/blob/master/src/main/shadow/json.cljs#L4-L37

Maybe we should add a json->clj to core and properly document the problematic behaviour of js->clj?

Comment by John Szakmeister [ 31/Oct/17 7:36 AM ]

Maybe we should add a json->clj to core and properly document the problematic behaviour of js->clj?

I think that would be advisable. I implemented my own json->clj in my project that worked around this issue a while back, but I think something in the core would be very beneficial here.

BTW, nice reproduction recipe. It's unfortunate that advanced compilation shortens that to something that potentially conflicts.





[CLJS-2393] process.env preload is added after all existing preloads Created: 31/Oct/17  Updated: 17/Nov/17

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

Type: Defect Priority: Minor
Reporter: Eugene Pakhomov Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: npm-deps


 Description   

When there're other preloads and the check for process-shim returns true, `process.env` is added to the end of the vector of all preloads.
That causes problems when one of the previous preloads requires something that checks `process.env` during loading.

E.g. I have a Reagent application with `:npm-deps` set to React and a few other libraries. And I have a preload exactly like this one: https://github.com/flexsurfer/re-frisk/blob/master/src/re_frisk/preload.cljs
The issue is that `re-frisk.core` requires Reagent, which requires React, which checks `process.env` - all before `process.env` was actually created.

I think that `process.env` should go before all existing preloads.



 Comments   
Comment by Hendrik Poernama [ 02/Nov/17 8:02 AM ]

Workaround is to manually add process.env to the first of :preloads vector





[CLJS-2360] ClojureScript ignores first two arguments passed to a macro when using vargs Created: 13/Sep/17  Updated: 19/Nov/17

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

Type: Defect Priority: Minor
Reporter: Ethan McCue Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: bug


 Description   

The following code produces different results in clojure and in clojurescript

(defmacro beep [& args]
  (cons 'list args))
(print (beep 0 1 2 3))

In clojure that code outputs (0 1 2 3)
In clojurescript that code outputs (2 3)



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

Ethan, I suspect this ticket is invalid. Are you defining the macro in the REPL? If you do that, you will see the consequence that macros are really just functions called by the compiler (with two extra special arguments &env and &form, which you are passing as 0 and 1 in your example code).

Macros in ClojureScript need to be defined in a separate namespace and consumed using :require-macros. See more at https://clojurescript.org/about/differences#_macros





[CLJS-1458] re-matches might give false negative when using match groups Created: 25/Sep/15  Updated: 20/Nov/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: 0
Labels: None

Attachments: Text File CLJS-1458-re-matches-might-give-false-negative-2.patch     Text File cljs-1458-re-matches-might-give-false-negative.patch    
Patch: Code and Test

 Description   

Current behaviour:

(re-matches #"(a|aa)" "aa") => nil

Expected:

(re-matches #"(a|aa)" "aa") => ["aa" "aa"]

JVM version works as expected, only CLJS is affected



 Comments   
Comment by David Nolen [ 14/Oct/15 11:36 AM ]

This is the kind of ticket that tends to break existing code. We should get some people who are interested in this ticket to actually try it out.

Comment by Mike Fikes [ 31/Jan/16 3:45 PM ]

FWIW, I gave cljs-1458-re-matches-might-give-false-negative.patch a try in bootstrapped ClojureScript and it is working fine there (each of the additional unit tests produce the expected results in bootstrapped).

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

Patch no longer applies.

Comment by Nikita Prokopov [ 20/Nov/17 3:47 AM ]

New patch





[CLJS-1631] The str function should handle JavaScript symbols Created: 21/Apr/16  Updated: 20/Nov/17

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

Type: Enhancement Priority: Minor
Reporter: Roman Scherer Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: None

Attachments: Text File 0001-CLJS-1631-Make-str-handle-js-symbols.patch    
Patch: Code and Test

 Description   

The str function should handle primitive JavaScript symbols produced by Symbol.for. At the moment the str function raises an exception, because it runs into some JavaScript safety checks by using implicit string coersion via (.join #js [x] "").
More info on the safety check here: http://www.2ality.com/2014/12/es6-symbols.html
This ticket is also related to:

(def x (.for js/Symbol "x"))
(str x)
TypeError: Cannot convert a Symbol value to a string
    at Array.join (native)
    at Function.cljs.core.str.cljs$core$IFn$_invoke$arity$1 (/home/roman/workspace/clojurescript/.cljs_node_repl/cljs/core.js:9561:12)
    at Object.cljs$core$str [as str] (/home/roman/workspace/clojurescript/.cljs_node_repl/cljs/core.js:9543:22)
    at repl:1:100
    at repl:9:3
    at repl:14:4
    at Object.exports.runInThisContext (vm.js:54:17)
    at Domain.<anonymous> ([stdin]:41:34)
    at Domain.run (domain.js:228:14)
    at Socket.<anonymous> ([stdin]:40:25)

Calling the toString method on a symbol directly works

(.toString x)
;;=> "Symbol(x)"


 Comments   
Comment by Mike Fikes [ 19/Nov/17 9:09 PM ]

Unit tests fail in (presumably older environments) in Travis:

JavaScriptCore:

ERROR in (test-cljs-1631) (core-advanced-test.js:3724:60)
expected: (= "Symbol(x)" (str (.for js/Symbol "x")))
  actual: #object[ReferenceError ReferenceError: Can't find variable: Symbol]

Nashorn:

ERROR in (test-cljs-1631) (ReferenceError:NaN:NaN)
expected: (= "Symbol(x)" (str (.for js/Symbol "x")))
  actual: #object[ReferenceError ReferenceError: "Symbol" is not defined]

Since this appears to only affect the tests, and not the production code, perhaps the tests could be conditional on (exists? js/Symbol).

Comment by Thomas Heller [ 20/Nov/17 6:43 AM ]

There is a lot of history behind the str fn/macro and why they do what they to.

See: https://dev.clojure.org/jira/browse/CLJS-890

The patch just uses toString which is not an option until we sort out CLJS-890.





[CLJS-2398] cljs.core.Var shouldn't satisfy IWithMeta Created: 12/Nov/17  Updated: 19/Nov/17

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

Type: Defect Priority: Minor
Reporter: Brandon Bloom Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: patch

Attachments: Text File 0001-Remove-IWithMeta-implementation-from-Var.patch    
Patch: Code

 Description   

cljs.core.Var implements IWithMeta, which differs from vars in Clojure which do not have immutable metadata. with-meta shouldn't be supported on vars, only alter-meta! should.

Unlike Clojure, ClojureScript doesn't use dynamic dispatch for alter-meta!. The implementation of cljs.core/alter-meta! will happily mutate the metadata of any object with a "meta" field, even if it's not a ref/var/whatever identity. This means that if you want to have metadata on your custom type, you have to have a "meta" field, rather than implement methods for getting/changing metadata. That's not too ideal, but doesn't present an immediate problem for me.

The reason I care about IWithMeta is that I need to distinguish metadata handling between values and reference types. Ideally, there would be an IAlterMeta protocol as well, but (and (satisfies? IMeta x) (not (satisfies? IWithMeta x))) suffices. On the JVM, the same can be done with IMeta and IObj.



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

Unit test failure:

ERROR in (test-1248) (core-advanced-test.js:64:417)
Uncaught exception, not in assertion.
expected: nil
  actual: #object[Error Error: No protocol method IWithMeta.-with-meta defined for type object: #'cljs.core/first]




[CLJS-1827] Improve reader performance on Firefox/Windows Created: 20/Oct/16  Updated: 19/Nov/17

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

Type: Enhancement Priority: Minor
Reporter: Michael Sperber Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: performance, reader
Environment:

Firefox on Windows


Attachments: Text File cljs-reader.patch    
Patch: Code

 Description   

cljs.reader/read-string speeds up by a factor of 2 on Firefox/Windows through this change without complicating the code.

(Other JS engines, including Firefox on Linux/Mac do not seem to be affected as significantly.)



 Comments   
Comment by David Nolen [ 20/Oct/16 10:33 AM ]

It would be nice to have a bit more information on this ticket as to what Google Closure does that's unnecessary or whether this path is actually a faithful port of Clojure behavior (copies the implementation of the EDN reader in these hot spots??). Finally the patch names David Frese, have they submitted a CA?

Thanks!

Comment by Michael Sperber [ 21/Oct/16 5:49 AM ]

I believe the Google functions are too general, work on strings in addition to characters etc.

It's not clear to us though why only Firefox on Windows benefits.

(David Frese is a co-worker - yes, has submitted a CA.)

Comment by Mike Fikes [ 19/Nov/17 7:41 PM ]

Patch no longer applies; needs re-baseline.
Also, doesn't work with git am; recommend creating patch using https://clojurescript.org/community/patches





[CLJS-1810] Refactoring of find-and-cache-best-method Created: 05/Oct/16  Updated: 19/Nov/17

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

Type: Enhancement Priority: Minor
Reporter: Andrey Zaytsev Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None

Attachments: Text File 0001-refactor-find-and-cache-best-method.patch    
Patch: Code

 Description   

find-and-cache-best-method was pretty messy and confusing. cache reset is done in -get-method fn itself and it was basically a dead code. find-best-method is the replacement of it and operates with immutable data instead of internal multimethod's mutable state.
prefers* function didn't mutate the atom too, so now it takes an immutable value.
dominates is now an internal helper of find-best-method since it is private and not used by anything else.



 Comments   
Comment by Mike Fikes [ 19/Nov/17 7:43 PM ]

Patch no longer applies; needs re-baseline.





[CLJS-1784] Cleanup set creation functions Created: 20/Sep/16  Updated: 19/Nov/17

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

Type: Enhancement Priority: Minor
Reporter: Thomas Mulvaney Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None

Attachments: Text File CLJS-1784.patch    
Patch: Code

 Description   

Use .fromArray for consistency/speed when handling zeroed IndexedSeqs.

Use reduce as the default construction path to take advantage of reducible collections.



 Comments   
Comment by Rohit Aggarwal [ 26/Sep/16 4:13 PM ]

Thomas Mulvaney, could you provide some benchmarks for the speed assertion? It would be nice to run it on Chrome/Firefox/Safari.

Comment by Thomas Mulvaney [ 28/Sep/16 1:30 AM ]

Sure thing, I'll do some more benchmarks.

Comment by Mike Fikes [ 19/Nov/17 7:45 PM ]

Patch no longer applies; needs re-baseline.





[CLJS-1783] Unify List creation code Created: 20/Sep/16  Updated: 19/Nov/17

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

Type: Enhancement Priority: Minor
Reporter: Thomas Mulvaney Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None

Attachments: Text File CLJS-1783.patch    
Patch: Code

 Description   

There is some duplication and redundant functions around List creation.

In this patch a fromArray method was added to List, consistent with other persistent data structures in the code base.



 Comments   
Comment by Mike Fikes [ 19/Nov/17 7:45 PM ]