<< Back to previous view

[CLJS-1299] reader/read-string does not handle \space literal Created: 05/Jun/15  Updated: 04/Jul/15

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

Type: Defect Priority: Major
Reporter: Ray Huang Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

OSX


Attachments: Text File CLJS1299-0001.patch    

 Description   

I notice that in Clojure Script, it doesn't know how to interpret \space using reader/read-string

In Clojure:
entangle.single=> (pr-str {:foo \space})
"{:foo
space}"

Then, attempting to deserialize in ClojureScript:
entangle.client => (reader/read-string "{:foo
space}")
#<Error: Map literal must contain an even number of forms>
Error: Map literal must contain an even number of forms
at Function.cljs.reader.reader_error.cljs$core$IFn$_invoke$arity$variadic (http://localhost:10000/public/js/out/cljs/reader.js:156:8)
at cljs$reader$reader_error (http://localhost:10000/public/js/out/cljs/reader.js:152:33)
at cljs$reader$read_map (http://localhost:10000/public/js/out/cljs/reader.js:436:26)
at cljs$reader$read (http://localhost:10000/public/js/out/cljs/reader.js:810:34)
at cljs$reader$read_string (http://localhost:10000/public/js/out/cljs/reader.js:837:25)



 Comments   
Comment by Ray Huang [ 04/Jul/15 11:07 AM ]

I've created a patch to support these literals. This based on the JVM's `CharacterReader` class. I've added a test case as well and it passes all the tests.





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

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

Type: Enhancement Priority: Major
Reporter: Herwig Hochleitner Assignee: Unassigned
Resolution: Unresolved Votes: 0
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






[CLJS-1327] Use Transit JSON for analysis caches Created: 03/Jul/15  Updated: 03/Jul/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3308
Fix Version/s: Next

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


 Description   

A significant amount of time is spent reading caches both during cold builds and REPL start. Switching to Transit for the analysis cache format should deliver a very large performance boost.






[CLJS-1191] Update clojure.walk to the current version on clojure Created: 06/Apr/15  Updated: 03/Jul/15  Resolved: 03/Jul/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3308
Fix Version/s: Next

Type: Defect Priority: Major
Reporter: Stuart Mitchell Assignee: Unassigned
Resolution: Completed Votes: 4
Labels: enhancement, performance

Attachments: Text File 50.patch     Text File CLJS-1191.patch     Text File CLJS-1191-rebase.patch     Text File CLJS-1191-tests.patch    
Patch: Code

 Description   

Currently clojure.walk can not handle records

It is using an old version of clojure.walk and clojure has improved the implementation because of

http://dev.clojure.org/jira/browse/CLJ-1105


src/cljs/clojure/walk.cljs | 4 ++++
1 file changed, 4 insertions

diff --git a/src/cljs/clojure/walk.cljs b/src/cljs/clojure/walk.cljs
index f2ebd8d..541ecea 100644
— a/src/cljs/clojure/walk.cljs
+++ b/src/cljs/clojure/walk.cljs
@@ -43,7 +43,11 @@ the sorting function."}
{:added "1.1"}
[inner outer form]
(cond
+ (list? form) (outer (apply list (map inner form)))
+ (satisfies? IMapEntry form) (outer (vec (map inner form)))
(seq? form) (outer (doall (map inner form)))
+ (satisfies? IRecord form)
+ (outer (reduce (fn [r x] (conj r (inner x))) form form))
(coll? form) (outer (into (empty form) (map inner form)))
:else (outer form)))



 Comments   
Comment by David Nolen [ 07/Apr/15 5:56 AM ]

Please attach the patch as a file. Thanks!

Comment by Stuart Mitchell [ 07/Apr/15 7:18 PM ]

I think this one works

it is a mail formatted patch

Comment by David Nolen [ 08/Apr/15 6:07 AM ]

Please follow the patch conventions described here https://github.com/clojure/clojurescript/wiki/Patches. Thank you.

Comment by David Nolen [ 12/Apr/15 4:53 PM ]

Stuart, I don't see you on the list of contributors. Please submit a CA so I can apply the patch. Thanks!

Comment by Stuart Mitchell [ 13/Apr/15 7:49 PM ]

Hopefully this is the right format

Comment by Stuart Mitchell [ 13/Apr/15 7:50 PM ]

Contributor agreement signed as well

Comment by Sebastian Bensusan [ 01/May/15 1:24 PM ]

Tested the patch on the REPL, works as expected except for walking fns that modify the keys:

> (defrecord Foo [name])
cljs.user/Foo
> (w/prewalk #(if (keyword? %) (str %) %) (Foo. "foo"))
#cljs.user.Foo{:name "foo", ":name" "foo"}

It is not consistent with walking the same fn over a map:

> (w/prewalk #(if (keyword? %) (str %) %) {:name "foo"})

{":name" "foo"}

This behavior was noted in the original Clojure patch as well: http://dev.clojure.org/jira/browse/CLJ-1239 and might be undesirable since it surprises the user.

Comment by Daniel Skarda [ 10/Jun/15 9:59 AM ]

Our project shares many files between server and client (Clojure and ClojureScript). I noticed the same bug today, because tests in CLJ went fine, while same tests in CLJS failed (then I prepared a patch just to find this ticket...)

From my perspective, I would prefer that CLJ and CLJS have the same implementation of clojure.walk.

For example - you implement some clever scheme to avoid kind of surprise you described. If it is not implemented in Clojure in the same way, it will be surprise for people writing code portable between CLJ and CLJS.

So my proposal is to take current Clojure implementation as a master and wait, how clojure.walk implementation will be improved in future releases of Clojure. Then we can port it to ClojureScript.

Comment by Daniel Skarda [ 10/Jun/15 10:10 AM ]

Tests for patch by Stuart

Comment by David Nolen [ 01/Jul/15 1:38 PM ]

Happy to apply these but they need to be rebased to master. Thanks.

Comment by Stuart Mitchell [ 02/Jul/15 9:21 PM ]

Hi this patch does not include the tests as that patch still applies cleanly.

Comment by David Nolen [ 03/Jul/15 2:58 PM ]

fixed
https://github.com/clojure/clojurescript/commit/f706fabfd5f952c4dfb4dc2caeea92f9e00d8287
https://github.com/clojure/clojurescript/commit/f1ff78d882bbaaa5135f205dfa19b01895462a3b





[CLJS-1326] In bootstrapped cljs, read-number of "0" gives "invalid number format" Created: 03/Jul/15  Updated: 03/Jul/15  Resolved: 03/Jul/15

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

Type: Defect Priority: Minor
Reporter: Joel Martin Assignee: Unassigned
Resolution: Declined Votes: 0
Labels: bootstrap
Environment:

cljs-bootstrap REPL (https://github.com/kanaka/cljs-bootstrap)



 Description   

tools.reader/read-number (https://github.com/swannodette/tools.reader) of "0" throws an error. The same for "1" works fine.

cljs-bootstrap.repl> 0
Error: Invalid number format [0]
    at new cljs$core$ExceptionInfo (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/core.js:33157:10)
    at Function.cljs.core.ex_info.cljs$core$IFn$_invoke$arity$3 (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/core.js:33219:9)
    at Function.cljs.core.ex_info.cljs$core$IFn$_invoke$arity$2 (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/core.js:33215:26)
    at cljs$core$ex_info (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/core.js:33201:26)
    at Function.cljs.tools.reader.reader_types.reader_error.cljs$core$IFn$_invoke$arity$variadic (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/tools/reader/reader_types.js:802:25)
    at cljs$tools$reader$reader_types$reader_error (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/tools/reader/reader_types.js:798:52)
    at cljs$tools$reader$read_number (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/tools/reader.js:446:52)
    at /home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/tools/reader.js:1550:38
    at cljs$tools$reader$reader_types$log_source (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/tools/reader/reader_types.js:873:16)
    at cljs$tools$reader$target (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/tools/reader.js:1528:50)

This is because reader/read-number has:

(or (match-number s) (reader-error rdr "Invalid number format [" s "]")))

which compiled to this JS:

var or__4073__auto__ = cljs.tools.reader.impl.commons.match_number.call(null,s);
if(or__4073__auto__){
return or__4073__auto__;
} else {
return cljs.tools.reader.reader_types.reader_error.call(null,rdr,"Invalid number format [",s,"]");
}

Since match_number returns a JS number, or_4073auto_ is 0, therefore falsey.



 Comments   
Comment by Joel Martin [ 03/Jul/15 9:31 AM ]

FYI, to reproduce, run this in https://github.com/kanaka/cljs-bootstrap

lein run -m clojure.main script/build.clj
node repl.js
cljs-bootstrap.repl> 0
Error: Invalid number format [0]
...
Comment by David Nolen [ 03/Jul/15 2:55 PM ]

This ticket doesn't have nearly enough information. I checked the output of tools.reader and I don't see this generated code at all. The test is wrapped in the required call to truth_.





[CLJS-1325] defrecord broken in bootstrapped cljs (error during set!) Created: 03/Jul/15  Updated: 03/Jul/15

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

Type: Defect Priority: Minor
Reporter: Joel Martin Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: bootstrap
Environment:

cljs-bootstrap node.js RELP (https://github.com/kanaka/cljs-bootstrap)



 Description   

This is a follow-on to http://dev.clojure.org/jira/browse/CLJS-1321 for getting defrecord to work in the bootstrap node REPL.

cljs-bootstrap.repl> (defprotocol IFoo (foo [this]))
nil
cljs-bootstrap.repl> (defrecord Baz [b] IFoo (foo [this] (prn "some baz:" b)))
Error: Can't set! local var or non-mutable field
    at new cljs$core$ExceptionInfo (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/core.js:33157:10)
    at Function.cljs.core.ex_info.cljs$core$IFn$_invoke$arity$3 (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/core.js:33219:9)
    at cljs$core$ex_info (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/core.js:33205:26)
    at Function.cljs.analyzer.error.cljs$core$IFn$_invoke$arity$3 (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/analyzer.js:699:26)
    at cljs$analyzer$error (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/analyzer.js:685:28)
    at Function.cljs.analyzer.error.cljs$core$IFn$_invoke$arity$2 (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/analyzer.js:695:28)
    at cljs$analyzer$error (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/analyzer.js:681:28)
    at /home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/analyzer.js:2311:27
    at /home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/analyzer.js:2315:3
    at cljs.core.MultiFn.call.G__11387__6 (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/core.js:31419:149)

The same as above but with debug added to the analyzer set! method to print the form:

cljs-bootstrap.repl> (defprotocol IFoo (foo [this]))
DEBUG set! p__9852: (set! *unchecked-if* true)
DEBUG set! p__9852: (set! *unchecked-if* false)
nil
cljs-bootstrap.repl> (defrecord Baz [b] IFoo (foo [this] (prn "some baz:" b)))
DEBUG set! p__9852: (set! (.. Baz -prototype -cljs$core$ILookup$-lookup$arity$2) (cljs.core$macros/fn ([this__7850__auto__ k__7851__auto__] (cljs.core$macros/this-as this__7850__auto__ (cljs.core/-lookup this__7850__auto__ k__7851__auto__ nil)))))
DEBUG set! p__9852: (set! (.. Baz -prototype -cljs$core$ICollection$-conj$arity$2) (cljs.core$macros/fn ([this__7855__auto__ entry__7856__auto__] (cljs.core$macros/this-as this__7855__auto__ (if (cljs.core/vector? entry__7856__auto__) (cljs.core/-assoc this__7855__auto__ (cljs.core/-nth entry__7856__auto__ 0) (cljs.core/-nth entry__7856__auto__ 1)) (cljs.core/reduce cljs.core/-conj this__7855__auto__ entry__7856__auto__))))))
DEBUG set! p__9852: (set! (.. Baz -prototype -cljs$core$ILookup$-lookup$arity$3) (cljs.core$macros/fn ([this__7852__auto__ k25 else__7853__auto__] (cljs.core$macros/this-as this__7852__auto__ (cljs.core$macros/case k25 :b b (cljs.core/get __extmap k25 else__7853__auto__))))))
DEBUG set! p__9852: (set! (.. Baz -prototype -cljs$core$IPrintWithWriter$-pr-writer$arity$3) (cljs.core$macros/fn ([this__7864__auto__ writer__7865__auto__ opts__7866__auto__] (cljs.core$macros/this-as this__7864__auto__ (cljs.core$macros/let [pr-pair__7867__auto__ (cljs.core$macros/fn [keyval__7868__auto__] (cljs.core/pr-sequential-writer writer__7865__auto__ cljs.core/pr-writer "" " " "" opts__7866__auto__ keyval__7868__auto__))] (cljs.core/pr-sequential-writer writer__7865__auto__ pr-pair__7867__auto__ "#cljs-bootstrap.repl.Baz{" ", " "}" opts__7866__auto__ (cljs.core/concat [(cljs.core/vector :b b)] __extmap)))))))
DEBUG set! p__9852: (set! (.. Baz -prototype -cljs$core$IMeta$-meta$arity$1) (cljs.core$macros/fn ([this__7848__auto__] (cljs.core$macros/this-as this__7848__auto__ __meta))))
DEBUG set! p__9852: (set! (.. Baz -prototype -cljs$core$ICloneable$-clone$arity$1) (cljs.core$macros/fn ([this__7844__auto__] (cljs.core$macros/this-as this__7844__auto__ (new Baz b __meta __extmap __hash)))))
DEBUG set! p__9852: (set! (.. Baz -prototype -cljs$core$ICounted$-count$arity$1) (cljs.core$macros/fn ([this__7854__auto__] (cljs.core$macros/this-as this__7854__auto__ (cljs.core$macros/+ 1 (cljs.core/count __extmap))))))
DEBUG set! p__9852: (set! (.. Baz -prototype -cljs$core$IHash$-hash$arity$1) (cljs.core$macros/fn ([this__7845__auto__] (cljs.core$macros/this-as this__7845__auto__ (cljs.core$macros/caching-hash this__7845__auto__ hash-imap __hash)))))
DEBUG set! p__9852: (set! __hash h__7674__auto__)
Error: Can't set! local var or non-mutable field
    at new cljs$core$ExceptionInfo (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/core.js:33157:10)
    at Function.cljs.core.ex_info.cljs$core$IFn$_invoke$arity$3 (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/core.js:33219:9)
    at cljs$core$ex_info (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/core.js:33205:26)
    at Function.cljs.analyzer.error.cljs$core$IFn$_invoke$arity$3 (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/analyzer.js:699:26)
    at cljs$analyzer$error (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/analyzer.js:685:28)
    at Function.cljs.analyzer.error.cljs$core$IFn$_invoke$arity$2 (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/analyzer.js:695:28)
    at cljs$analyzer$error (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/analyzer.js:681:28)
    at /home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/analyzer.js:2312:27
    at /home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/analyzer.js:2316:3
    at cljs.core.MultiFn.call.G__11387__6 (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/core.js:31419:149)


 Comments   
Comment by Joel Martin [ 03/Jul/15 9:31 AM ]

FYI, to reproduce, run this in https://github.com/kanaka/cljs-bootstrap

lein run -m clojure.main script/build.clj
node repl.js
cljs-bootstrap.repl> (defprotocol IFoo (foo [this]))
cljs-bootstrap.repl> (defrecord Baz [b] IFoo (foo [this] (prn "some baz:" b)))
Error: Can't set! local var or non-mutable field
...




[CLJS-1321] defrecord broken in bootstrapped cljs Created: 01/Jul/15  Updated: 02/Jul/15  Resolved: 02/Jul/15

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

Type: Defect Priority: Minor
Reporter: Joel Martin Assignee: David Nolen
Resolution: Completed Votes: 0
Labels: bootstrap
Environment:

cljs-bootstrap REPL (https://github.com/swannodette/cljs-bootstrap)



 Description   

First problem that I run into is that emit-defrecord makes use of .getNamespace and .getName on rname. That should probably be (namespace rname) and (name rname). After that change is made the next error is "Can't set! local var or non-mutable field" somewhere in defrecord. Not sure what the cause of that one is.



 Comments   
Comment by David Nolen [ 02/Jul/15 6:03 PM ]

fixed https://github.com/clojure/clojurescript/commit/8a5023b849cfc509931b3ff509a9f7ee48dd03ec

Comment by David Nolen [ 02/Jul/15 6:04 PM ]

I did not look into the set! issue. Separate ticket should be opened for that if it persists.

Comment by Mike Fikes [ 02/Jul/15 6:46 PM ]

Confirmed fixed downstream (https://github.com/mfikes/replete/issues/25), apart from other Can't set! local var or non-mutable field error, which needs a separate ticket.





[CLJS-1323] possible to reload cljs.core in browser REPL Created: 01/Jul/15  Updated: 02/Jul/15  Resolved: 02/Jul/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3308
Fix Version/s: Next

Type: Defect Priority: Major
Reporter: David Nolen Assignee: David Nolen
Resolution: Not Reproducible Votes: 0
Labels: None


 Description   

Accidentally doing so will wreck havoc on the browser REPL as all the core types will get redefined. For some reason cljs.core is the only namespace that is not on the goog.dependencies_.written list, once as the relative path and once again as the absolute path. Uncovered while attempting to test the bootstrap support in browser environments.



 Comments   
Comment by David Nolen [ 02/Jul/15 6:02 PM ]

Misinterpreted the issue. Was loading the macros ns which shares the same name. Needed to rewrite in to a macro ns instead.





[CLJS-985] ex-info loses stack information Created: 20/Jan/15  Updated: 02/Jul/15  Resolved: 23/Jan/15

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

Type: Defect Priority: Major
Reporter: Nikita Prokopov Assignee: Unassigned
Resolution: Completed Votes: 1
Labels: None

Attachments: Text File cljs-985-ex-info-stack.patch    

 Description   

Native js Error keeps stacktrace:

(js/console.log (.-stack (js/Error. "message")))

Error: message
    at eval (/Users/prokopov/Dropbox/ws/datascript/test/test/datascript.cljs[eval5]:10:14)
    at eval (native)
    at SocketNamespace.<anonymous> (http://localhost:65000/socket.io/lighttable/ws.js:118:26)
    at SocketNamespace.EventEmitter.emit [as $emit] (http://localhost:65000/socket.io/socket.io.js:633:15)
    at SocketNamespace.onPacket (http://localhost:65000/socket.io/socket.io.js:2248:20)
    at Socket.onPacket (http://localhost:65000/socket.io/socket.io.js:1930:30)
    at Transport.onPacket (http://localhost:65000/socket.io/socket.io.js:1332:17)
    at Transport.onData (http://localhost:65000/socket.io/socket.io.js:1303:16)
    at WebSocket.websocket.onmessage (http://localhost:65000/socket.io/socket.io.js:2378:12)

But ex-info does not:

(js/console.log (.-stack (ex-info "message")))

Error
    at file:///Users/prokopov/Dropbox/ws/datascript/web/target-cljs/cljs/core.js:32066:38

Problem is that ex-info inherits stack property from prototype which is instantiated at script load time here:

(deftype ExceptionInfo [message data cause])

(set! (.-prototype ExceptionInfo) (js/Error.))
(set! (.. ExceptionInfo -prototype -constructor) ExceptionInfo)

The possible solution is to create new instance of js/Error at (ex-info) and manually copy stack property to ExceptionInfo object. Related SO: http://stackoverflow.com/questions/783818/how-do-i-create-a-custom-error-in-javascript

Problem is that Chrome has setter on stack property, and it only allows for this property to be set inside a constructor functions.

Proposed fix creates new Error each time ex-info is called and sets ExceptionInfo.prototype to newly created error. This way new ExceptionInfo instance will inherit stack from newly created Error with correct stack.

This patch has been tested in Chrome 39 Mac, Safari 8 Mac, Firefox 35 Mac and IE 10 Win. Here's test code I used:

(defn -ex-info
  ([msg data]
    (set! (.-prototype ExceptionInfo) (js/Error msg))
    (set! (.. ExceptionInfo -prototype -name) "ExceptionInfo")
    (set! (.. ExceptionInfo -prototype -constructor) ExceptionInfo)
    (ExceptionInfo. msg data nil))
  ([msg data cause]
    (set! (.-prototype ExceptionInfo) (js/Error msg))
    (set! (.. ExceptionInfo -prototype -name) "ExceptionInfo")
    (set! (.. ExceptionInfo -prototype -constructor) ExceptionInfo)
    (ExceptionInfo. msg data cause)))

(try
  (throw (ex-info "[ -- Current ex-info message -- ]" 123))
  (catch ExceptionInfo e
    (js/console.log "Current ex-info::" (.-stack e))))

(try
  (throw (js/Error "[ -- Native message -- ]"))
  (catch js/Error e
    (js/console.log "Native error::" (.-stack e))))

(try
  (throw (-ex-info "[ -- Patched ex-info message -- ]" 123))
  (catch ExceptionInfo e
    (js/console.log "Patched ex-info::" (.-stack e))))

Test results:

Chrome, Firefox, IE, Safari

Note that current implementation reports line number and overall stacktrace from cljs.core file where Error prototype is created in current implementation.
Note that patched version reports correct line number (it should be close to native error stack), stack, message and exception name.
Also note that IE is fine even without patch — that's because in IE stack is capturead at throw place, not at new Error() call site.



 Comments   
Comment by Nikita Prokopov [ 20/Jan/15 2:48 PM ]

Ok, this is crazy, but this seems to solve the issue:

(defn ex-info [msg data cause]
  (set! (.-prototype ExceptionInfo) (js/Error msg))
  (set! (.. ExceptionInfo -prototype -name) "cljs.core.ExceptionInfo")
  (set! (.. ExceptionInfo -prototype -constructor) ExceptionInfo)
  (ExceptionInfo. msg data cause))

Basically we change prototype before creating each object.

(taken from http://stackoverflow.com/questions/783818/how-do-i-create-a-custom-error-in-javascript#answer-12030032)

I guess high performance is not needed from ex-info, so this solution is somewhat okay-ish? Should I make a patch from it?

Comment by David Nolen [ 20/Jan/15 2:55 PM ]

It would be nice to get confirmation from others that this works under the major browser - Safari, Firefox, Chrome, and modern IE.

Comment by Nikita Prokopov [ 20/Jan/15 3:12 PM ]

I can confirm Firefox 34, Firefox 35, Safari 8.0.2 and Chrome 39 (all Mac) for now

Comment by Nikita Prokopov [ 22/Jan/15 3:50 AM ]

David, I updated issue, added patch, test code and test results (including IE). There’s no unit test on this because stack traces are very engine-specific. Please take a look

Comment by David Nolen [ 22/Jan/15 2:24 PM ]

Nikita, thanks for the update will check it out.

Comment by David Nolen [ 23/Jan/15 6:13 PM ]

fixed https://github.com/clojure/clojurescript/commit/93dce672e1af8f698cfc2a61e293cb48aeeddc2c

Comment by Aleksey Kladov [ 01/Jul/15 7:19 PM ]

Looks like it should be reopened because of this commit
https://github.com/clojure/clojurescript/commit/de130a335bd761d580d04dadb8a5a43d3c0a35b4

js/Error is constructed with empty message on this line https://github.com/clojure/clojurescript/commit/de130a335bd761d580d04dadb8a5a43d3c0a35b4#diff-a98a037c6c098dd3707e861df3c2f5acR9197

So, when stack is assigned here
https://github.com/clojure/clojurescript/commit/de130a335bd761d580d04dadb8a5a43d3c0a35b4#diff-a98a037c6c098dd3707e861df3c2f5acR9210
it does not have a message.

I guess that the fix will be to change `(let [e (js/Error.)]` to `(let [e (js/Error. message)]`

Comment by David Nolen [ 02/Jul/15 5:59 PM ]

fixed in master





[CLJS-1324] Compiler fails to raise warning/error when invoking a keyword without arguments Created: 02/Jul/15  Updated: 02/Jul/15

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

Type: Defect Priority: Minor
Reporter: Sean Grove Assignee: Sean Grove
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Invoking a keyword with no arguments doesn't raise a warning/error in the compiler, but it likely should, e.g `(:any-key)`

It raises an error in the browser: "Uncaught TypeError: (intermediate value).cljs$core$IFn$_invoke$arity$0 is not a function".






[CLJS-1312] JS module support: Properly convert UMD pattern Created: 15/Jun/15  Updated: 02/Jul/15  Due: 21/Aug/15

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

Type: Enhancement Priority: Major
Reporter: Maria Neise Assignee: Maria Neise
Resolution: Unresolved Votes: 1
Labels: None


 Description   

Many popular libraries use the following or a similar idiom:

if (typeof define == "function" && define.amd) {
    define(function() {
        return greeting;
    });
} else if (typeof module != "undefined" &&
           module.exports) {
    module.exports = greeting;
} else {
    window["greeting"] = greeting;
}

The ProcessCommonJSModules class converts this to the following:

if (typeof define == "function" && define.amd) {
    define(function() {
        return greeting;
    });
} else {
    if (typeof module != "undefined" && module$greeting) {
        module$greeting = greeting;
    } else {
        window["greeting"] = greeting;
    }
}

module will not be defined, so the greeting object will not be assigned to the new module namespace. We need to check with the Google Closure compiler mailing list if we can submit a patch that replaces module so that the condition succeeds.



 Comments   
Comment by Maria Neise [ 15/Jun/15 1:35 PM ]

Asked about this on Google Closure compiler mailing list: https://groups.google.com/forum/#!topic/closure-compiler-discuss/-M1HBUn35fs





[CLJS-1322] Investigate why Babel cannot load into JDK 8 Nashorn Created: 01/Jul/15  Updated: 01/Jul/15

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

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


 Description   

It appears neither the developer browser.js file nor the browser.min.js file can be loaded into Nashorn due to a method size limit exception. The code appears to originate around the lodash include. This may be a red herring but this is a good starting point for investigation.






[CLJS-1177] A compiler support for non-Closure transforms (JSX, etc) Created: 28/Mar/15  Updated: 01/Jul/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3126
Fix Version/s: GSoC

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


 Description   

There are now a variety of JS dialects, JSX, TypeScript etc. which need to be transformed first into regular JS before module processing. We should devise a standard way to deal with this. As we cannot predict what various dialects may arise in the future it's probably best to provide something like :preprocess-module option to cljs.closure/build.



 Comments   
Comment by David Nolen [ 17/Jun/15 5:20 PM ]

We should verify with Babel now that React is moving away from JSX.

Comment by David Nolen [ 01/Jul/15 6:02 PM ]

I went ahead and looked into this a bit. Looks like getting Babel to work will take some time. Babel has difficulties loading into Nashorn due to code size limits that originate from Lodash usage. JSX while deprecated is still the most widely used option so we have some time yet and the interface supplied by both tools is exactly the same. So we should test this feature with JSX and switch to Babel when the issues are resolved.





[CLJS-1282] Add a :pprint option to the default reporter in cljs.test Created: 22/May/15  Updated: 28/Jun/15

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

Type: Enhancement Priority: Minor
Reporter: Sebastian Bensusan Assignee: Sebastian Bensusan
Resolution: Unresolved Votes: 0
Labels: test

Attachments: Text File cljs_1282.patch     Text File cljs_1282_v02.patch    

 Description   

Now that cljs.pprint has landed, cljs.test could report failures and exceptions with it. The exact API is TBD.



 Comments   
Comment by Sebastian Bensusan [ 22/Jun/15 4:00 PM ]

The :cljs.test/pprint reporter is implemented as a small deviation from the :cljs.test/default reporter.

The API is equivalent to that of custom reporters:

(run-tests
  (empty-env :cljs.test/pprint)
  'my-test.namespace)
Comment by David Nolen [ 24/Jun/15 5:51 AM ]

Looks good mostly but small typo: `print-comparisson` instead of `print-comparison`.

Comment by Sebastian Bensusan [ 28/Jun/15 5:13 PM ]

Added the rebased file with the typo corrected.





[CLJS-1320] clojure.string/split adds separator matches & failed matches (nil) when the separator is a regex with alternation Created: 26/Jun/15  Updated: 27/Jun/15

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?






[CLJS-1319] Cannot locate module namespace when filename contains dash Created: 22/Jun/15  Updated: 24/Jun/15  Resolved: 24/Jun/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: GSoC
Fix Version/s: GSoC

Type: Defect Priority: Major
Reporter: Maria Neise Assignee: Maria Neise
Resolution: Completed Votes: 0
Labels: None

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

 Description   

When the filename contains a dash, for example foo-bar, the compiler can't find the namespace for the module, e.g.

No such namespace: module$libs$foo_bar, could not locate module$libs$foo_bar.cljs, module$libs$foo_bar.cljc, or Closure namespace "module$libs$foo_bar" at line 1 src/hello_world/core.cljs {:file "src/hello_world/core.cljs", :line 1, :column 1, :tag :cljs/analysis-error}



 Comments   
Comment by Maria Neise [ 22/Jun/15 5:04 PM ]

Attached a fix for this. The problem was, that we didn't munge the new module-name that is generated by the Google Closure compiler, meaning we didn't replace underscores with dashes.

Comment by David Nolen [ 24/Jun/15 5:43 AM ]

fixed https://github.com/clojure/clojurescript/commit/73117d5a451bca5ab1a5aa8c7fa8cbce67ab98d0





[CLJS-1281] preserve test order Created: 21/May/15  Updated: 22/Jun/15  Resolved: 22/Jun/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

Type: Enhancement Priority: Minor
Reporter: David Nolen Assignee: Sebastian Bensusan
Resolution: Completed Votes: 0
Labels: newbie

Attachments: Text File cljs_1281.patch    

 Description   

We can keep tests sorted by :line var meta information.



 Comments   
Comment by Sebastian Bensusan [ 22/Jun/15 11:48 AM ]

Took David's suggestion and added a (sort-by :line) when creating the ns test-block.

Comment by David Nolen [ 22/Jun/15 12:08 PM ]

fixed





[CLJS-1318] Fix typo in documentation of `specify` Created: 22/Jun/15  Updated: 22/Jun/15

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

Type: Enhancement Priority: Trivial
Reporter: Yehonathan Sharvit Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None

Attachments: Text File patch.txt    
Patch: Code

 Description   

Fix typo in documentation of `specify`



 Comments   
Comment by Yehonathan Sharvit [ 22/Jun/15 6:27 AM ]

here is a patch that fixes the doc of `specify`





[CLJS-1317] Incremental compilation issues for :nodejs target Created: 21/Jun/15  Updated: 21/Jun/15  Resolved: 21/Jun/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3308
Fix Version/s: Next

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


 Description   

When using the :nodejs target, files which do not require recompilation trigger recompilation anyway. This is simple to replicate by making a trivial Node.js ClojureScript project which simply requires pprint for example and supplying a watch script and running it.



 Comments   
Comment by David Nolen [ 21/Jun/15 4:59 PM ]

The issue is that under :nodejs cljs.core will get recompiled trigger recompilation of dependent namespaces which includes cljs.pprint.

Comment by David Nolen [ 21/Jun/15 6:16 PM ]

fixed https://github.com/clojure/clojurescript/commit/e1e190569f8588fa6e1e30c0e4a4686d08b57eed





[CLJS-1316] let does not detect invalid binding vector when it contains destructuring Created: 19/Jun/15  Updated: 19/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3308
Fix Version/s: Next

Type: Defect Priority: Major
Reporter: Justin Glenn Smith Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

The presence of destructuring in a `let` binding vector prevents detection of basic errors.

cljs.user=> *clojurescript-version*
"0.0-3308"
cljs.user=> (let [{a :a} {:a 0} b] a)
0
cljs.user=> (let [a 0 b] a)
clojure.lang.ExceptionInfo: bindings must be vector of even number of elements at line 1 <cljs repl> {:file "<cljs repl>", :line 1, :column 1, :tag :cljs/analysis-error}

David Nolen mentions that this looks like something busted with the cljs.core/assert-args macro






[CLJS-1314] Node REPL can't load :libs Created: 17/Jun/15  Updated: 18/Jun/15

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:

Node REPL with the latest CommonJS loading impl


Attachments: Text File 0001-Illustration-of-fix.patch    

 Description   

I've been trying the CommonJS support and have been failing to get it to work in Node, and likewise so has Maria Neise. This is in the case of invoking build prior to launching the REPL as well as trying a new suggestion in CLJS-1313.

I cranked up the verbosity to see what is going on and ultimately hit upon the idea that

goog.require('module$libs$german');

isn't going to work in Node and instead needs the same alternative logic that is employed for :foreign-libs in cljs.compiler/load-libs, in particular this needs to be emitted.

cljs.core.load_file("out/german.js");

I hacked the code a bit and got the "german" CommonJS module to load in Node and be useable:

To quit, type: :cljs/quit
cljs.user=> (require '[german :refer [hello]])
Compiling out/cljs/core.cljs
Using cached cljs.core out/cljs/core.cljs
Compiling out/cljs/core.cljs
Using cached cljs.core out/cljs/core.cljs
goog.provide('cljs.user');
goog.require('cljs.core');
goog.require('cljs.repl');
goog.require('cljs.pprint');
cljs.core.load_file("out/german.js");

nil
cljs.user=> (hello)
module$libs$german.hello.call(null)
"Hallo"

The attached patch illustrates the hack to get the above to work. The real fix would be a generalization of this.



 Comments   
Comment by Mike Fikes [ 17/Jun/15 8:44 PM ]

(Sorry for the overly generalized ticket title; it should probably be weakened to just talk about foreign libs that have been converted to native libs.)

Comment by Mike Fikes [ 17/Jun/15 8:59 PM ]

Reproduction steps (note all of this is also in a repo at https://github.com/mfikes/test-commonjs ):

Set up a node_repl.clj:

(require 'cljs.repl)
(require 'cljs.build.api)
(require 'cljs.repl.node)

(def foreign-libs [{:file "libs/greeting.js"
       :provides ["greeting"]
       :module-type :commonjs}
      {:file "libs/german.js"
       :provides ["german"]
       :module-type :commonjs}])

(cljs.build.api/build "src"
  {:main 'foo.bar
   :output-to "out/main.js"
   :verbose true
   :foreign-libs foreign-libs})

(cljs.repl/repl (cljs.repl.node/repl-env)
  :watch "src"
  :output-dir "out"
  :foreign-libs foreign-libs)

Make a libs directory with german.js:

exports.hello = function() {
    return "Hallo";
};

and greeting.js:

var german = require("german");

exports.hello = function(name) {
    return german.hello() + ", " + name;
};

create a src/foo/bar.cljs with

(ns foo.bar
  (:require [greeting :refer [hello]]))

(enable-console-print!)

(println (hello "Welt!"))

Make a QuickStart cljs.jar uberjar and place it at root of tree and then

rlwrap java -cp cljs.jar:src clojure.main node_repl.clj

followed by

(require 'foo.bar)

You should see:

../out/foo/bar.js:6
cljs.core.println.call(null,module$libs$greeting.hello.call(null,"Welt!"));
                                                      ^
TypeError: Cannot read property 'call' of undefined
    at Object.<anonymous> (/Users/mfikes/Projects/test-commonjs/out/foo/bar.js:6:55)
    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 Module.require (module.js:365:17)
    at require (module.js:384:17)
    at global.CLOSURE_IMPORT_SCRIPT (repl:75:16)
    at Object.goog.require (repl:19:60)
    at repl:5:6
Comment by Mike Fikes [ 17/Jun/15 9:29 PM ]

Another comment: My "hack" works, but to be honest, I don't appreciate why the code doesn't work without the hack. And I couldn't defend it if you asked me to. Node can evidently load Closure modules that were produced by CLJS, so why would they fail for Closure modules produced by CommonJS processing? I bet there is more behind this and my hack may be papering over some deeper more fundamental problem.

For reference, in Node, my :js-dependency-index has

{nil {:requires [], :provides ["module$libs$german"], :url #object[java.net.URL 0x37d3d232 "file:/Users/mfikes/Projects/test-commonjs/out/german.js"], :closure-lib true, :lib-path "out/german.js"}

while in Ambly, the same has

{nil {:requires [], :provides ["module$libs$german"], :url #object[java.net.URL 0x34652065 "file:/Volumes/Ambly-81C53995/german.js"], :closure-lib true, :lib-path "/Volumes/Ambly-81C53995/german.js"}

(To clarfy, the above two :js-dependency-index bits are only part of the index... there is also all of the normal goog stuff.)





[CLJS-1315] Warning on Google Closure enum property access with / Created: 18/Jun/15  Updated: 18/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3308
Fix Version/s: Next

Type: Defect Priority: Major
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-1230] ES 2015 Module Processing Created: 30/Apr/15  Updated: 18/Jun/15  Resolved: 18/Jun/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: GSoC

Type: Enhancement Priority: Major
Reporter: David Nolen Assignee: Maria Neise
Resolution: Completed Votes: 0
Labels: None

Attachments: Text File CLJS-1230.patch    

 Description   

Add support for ECMAScript 6 modules.



 Comments   
Comment by Maria Neise [ 18/Jun/15 10:03 AM ]

I just attached a patch for adding ECMAScript 6 support. It was quite straight forward and works with the current version of the Google Closure compiler (v20150609).

Comment by David Nolen [ 18/Jun/15 10:04 AM ]

fixed https://github.com/clojure/clojurescript/commit/ac0b169cb082bd2ff4ac917274cb91628adba947





[CLJS-1313] REPL support for libs compiler opts Created: 17/Jun/15  Updated: 17/Jun/15

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

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

Attachments: Text File CLJS-1313-v1.patch    

 Description   

Today, module processing and the lib dependency index setup occurs only when cljs.closure/build is invoked. This ticket asks for the same setup to occur if either :libs or :foreign-libs options are passed when a REPL is launched (without an explicit build step occurring first, as is done in the Quick Start examples involving cljs.repl/repl).

An example:

(cljs.repl/repl (cljs.repl.node/repl-env)
  :foreign-libs [{:file "libs/greeting.js"
                  :provides ["greeting"]
                  :module-type :commonjs}
                 {:file "libs/german.js"
                  :provides ["german"]
                  :module-type :commonjs}])

The above would be sufficient to cause, for example, CommonJS module processing to occur, and the results to be available within the REPL.

Additionally, the implementation should defer processing to after REPL -setup has been called, in case the REPL establishes an :output-dir for :merge-opts during -setup, thereby ensuring that any module processing output goes to the correct :output-dir.



 Comments   
Comment by Mike Fikes [ 17/Jun/15 6:51 PM ]

The attached CLJS-1313-v1.patch is working fine for Ambly, but it fails for the Node REPL. Interestingly, Maria Neise was finding that CommonJS processing was not quite working properly under Node, even with an explicit build step, when compared to Nashorn. Apart from general discussion that could be had about suitability of such a patch, there is a specific concern with Node that needs to be sorted.

Comment by Mike Fikes [ 17/Jun/15 8:45 PM ]

So, with further investigation, it looks like the issue with using this patch with Node is actually a separate problem with Node: CLJS-1314

Additionally, I can confirm that the patch functions properly for Nashorn.





[CLJS-1227] Raise error when if form has more than 4 statements Created: 28/Apr/15  Updated: 17/Jun/15  Resolved: 17/Jun/15

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

Type: Enhancement Priority: Minor
Reporter: Nikita Prokopov Assignee: David Nolen
Resolution: Completed Votes: 1
Labels: None

Attachments: Text File cljs-1227-raise-error-when-if-has-more-than-4-statements-2.patch    
Patch: Code

 Description   

This is a trivial change, but might be very helpful. I've been struck by this a lot: form mistakenly put inside if form after then and else is silently ignored. Solution: raise an error when if contains more than 4 elements.



 Comments   
Comment by Mike Fikes [ 14/Jun/15 7:38 PM ]

This patch logically works fine for me, but with the rename src/clj/cljs/analyzer.clj -> src/main/clojure/cljs/analyzer.cljc it no longer applies cleanly.

Comment by Nikita Prokopov [ 15/Jun/15 10:18 AM ]

@mfikes I’ve updated the patch

Comment by David Nolen [ 17/Jun/15 5:29 PM ]

fixed https://github.com/clojure/clojurescript/commit/b11a9e6dd57ffca3d67c40c219b21055486bf202





[CLJS-1231] AMD Module Processing Created: 30/Apr/15  Updated: 17/Jun/15  Resolved: 17/Jun/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: GSoC

Type: Enhancement Priority: Major
Reporter: David Nolen Assignee: Maria Neise
Resolution: Completed Votes: 0
Labels: None

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

 Description   

Add support for including AMD modules into a ClojureScript project.



 Comments   
Comment by Maria Neise [ 17/Jun/15 4:28 PM ]

Just attached a patch which adds AMD module support. AMD modules are first converted to CommonJS modules and then converted to Google Closure modules. This allows us to reuse the functionality we previously added to convert CommonJS modules.

Comment by David Nolen [ 17/Jun/15 4:47 PM ]

fixed https://github.com/clojure/clojurescript/commit/87f39511a54d7b91ae86f581fda90f280f985816





[CLJS-1311] Improve error reporting when converting CommonJS modules Created: 15/Jun/15  Updated: 17/Jun/15  Due: 21/Aug/15

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

Type: Enhancement Priority: Major
Reporter: Maria Neise Assignee: Maria Neise
Resolution: Unresolved Votes: 2
Labels: None


 Description   

When using the Google Closure compiler via the command line and trying to convert a CommonJS module which has trailing commas, the compiler throws a parse error, e.g.:

chance.js:1109: ERROR - Parse error. IE8 (and below) will parse trailing commas in array and object literals incorrectly. If you are targeting newer versions of JS, set the appropriate language_in option.
                        '09' + self.string({ pool: '0123456789', length: 8}),

At the moment, we don't throw any errors when converting a CommonJS module and an error occurs. Instead, just the following gets emitted by the Google Closure compiler:

goog.provide("module$libs$chance");var module$libs$chance={}

We need to change this behaviour to throw an error.



 Comments   
Comment by Kristian Mandrup [ 16/Jun/15 10:53 PM ]

Yes, by default don't convert the CommonJS module, unless perhaps if you set a specific --force compile option.





[CLJS-1308] :analyze-path should be extended to take a vector of paths Created: 11/Jun/15  Updated: 16/Jun/15  Resolved: 16/Jun/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3308
Fix Version/s: Next

Type: Defect Priority: Major
Reporter: David Nolen Assignee: David Nolen
Resolution: Completed Votes: 1
Labels: newbie

Attachments: Text File CLJS-1308.patch    

 Description   

Currently limited to analyzing only a single directory.



 Comments   
Comment by Antony Woods [ 11/Jun/15 9:47 AM ]

Some information about this feature:
http://blog.fikesfarm.com/posts/2015-06-10-analyze-path-ftw.html

Source:
https://github.com/clojure/clojurescript/blob/master/src/main/clojure/cljs/repl.cljc#L742
https://github.com/clojure/clojurescript/blob/master/src/main/clojure/cljs/repl.cljc#L828

Comment by Antony Woods [ 11/Jun/15 9:59 AM ]

Is the desired behavior to take 'either a vector of paths or a single path', or to take 'only a vector'?

Comment by David Nolen [ 11/Jun/15 10:17 AM ]

It needs to be either otherwise it will break existing uses.

Comment by David Nolen [ 16/Jun/15 2:23 PM ]

fixed https://github.com/clojure/clojurescript/commit/06a7944927cb0dee91ea681739fa290d9fb4016b





[CLJS-911] Cljs's clojure.string.replace replacement fn takes different args to Clj's clojure.string.replace Created: 17/Dec/14  Updated: 14/Jun/15

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

Type: Defect Priority: Minor
Reporter: Peter Taoussanis Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: None
Environment:

ClojureScript 0.0-2411



 Description   

Clojure's `clojure.string.replace` takes a replacement fn which receives args `[[group1 group2 ...]]`.
ClojureScript's `clojure.string.replace` takes a replacement fn which receives args `[group1 group2 ...]` (i.e. & args).

It's my understanding that something like the `clojure.string` ns is intended partly to help pave over superficial API differences like this.

Modding ClojureScript's `string.replace` to match Clojure's behaviour would be trivial, but this would be a breaking change for anyone that's come to rely on the faulty[?] behaviour.

Would you like a patch for this? Can submit for http://dev.clojure.org/jira/browse/CLJS-794 while I'm at it (both involve a change to `clojure.string/replace`).

Thanks!



 Comments   
Comment by Joseph Smith [ 24/Feb/15 2:33 PM ]

+1 fixing this (preferably making the ClojureScript version work like the Clojure version).

Comment by Mike Fikes [ 14/Jun/15 7:25 PM ]

This ticket appears to be duplicate of CLJS-1304, which has an attached patch under consideration.





[CLJS-1310] ns libspec error message misses :import Created: 14/Jun/15  Updated: 14/Jun/15

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

Type: Defect Priority: Minor
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: errormsgs
Environment:

node repl


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

 Description   

Let's say you misspell :import in an ns form. You will get an error message that doesn't indicate that :import is a supported libspec:

cljs.user=> (ns foo.bar (:impert [goog Timer]))
clojure.lang.ExceptionInfo: Only :refer-clojure, :require, :require-macros, :use and :use-macros libspecs supported at line 1 <cljs repl> {:file "<cljs repl>", :line 1, :column 1, :tag :cljs/analysis-error}
	at clojure.core$ex_info.invoke(core.clj:4591)
	at cljs.analyzer$error.invoke(analyzer.cljc:405)
	at cljs.analyzer$error.invoke(analyzer.cljc:403)
	at cljs.analyzer$eval1819$fn__1821$fn__1825.invoke(analyzer.cljc:1569)
	at clojure.core.protocols$fn__6519.invoke(protocols.clj:148)
	at clojure.core.protocols$fn__6476$G__6471__6485.invoke(protocols.clj:19)
	at clojure.core.protocols$seq_reduce.invoke(protocols.clj:31)
	at clojure.core.protocols$fn__6502.invoke(protocols.clj:81)
	at clojure.core.protocols$fn__6450$G__6445__6463.invoke(protocols.clj:13)
	at clojure.core$reduce.invoke(core.clj:6515)
	at cljs.analyzer$eval1819$fn__1821.invoke(analyzer.cljc:1566)
	at clojure.lang.MultiFn.invoke(MultiFn.java:251)
	at cljs.analyzer$analyze_seq.invoke(analyzer.cljc:1943)
	at cljs.analyzer$analyze$fn__2069.invoke(analyzer.cljc:2035)
	at cljs.analyzer$analyze.invoke(analyzer.cljc:2028)
	at cljs.repl$evaluate_form.invoke(repl.cljc:429)
	at cljs.repl$eval_cljs.invoke(repl.cljc:548)
	at cljs.repl$repl_STAR_$read_eval_print__4305.invoke(repl.cljc:823)
	at cljs.repl$repl_STAR_$fn__4311$fn__4318.invoke(repl.cljc:860)
	at cljs.repl$repl_STAR_$fn__4311.invoke(repl.cljc:859)
	at cljs.compiler$with_core_cljs.invoke(compiler.cljc:982)
	at cljs.repl$repl_STAR_.invoke(repl.cljc:825)
	at cljs.repl$repl.doInvoke(repl.cljc:941)
	at clojure.lang.RestFn.invoke(RestFn.java:410)
	at user$eval4488.invoke(NO_SOURCE_FILE:3)
	at clojure.lang.Compiler.eval(Compiler.java:6792)
	at clojure.lang.Compiler.eval(Compiler.java:6755)
	at clojure.core$eval.invoke(core.clj:3079)
	at clojure.main$eval_opt.invoke(main.clj:289)
	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)





[CLJS-1309] get-expander declared twice in analyzer impl Created: 14/Jun/15  Updated: 14/Jun/15

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

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

N/A


Attachments: Text File CLJS-1309.patch    

 Description   

(declare get-expander) appears twice in analyzer.cljc. Second declare can be removed.






[CLJS-1217] cljs.test/run-tests with default env has no way to access summary Created: 21/Apr/15  Updated: 14/Jun/15  Resolved: 14/Jun/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

Type: Enhancement Priority: Major
Reporter: Jenan Wise Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: None


 Description   

clojure.test/run-tests returns a summary map that can be used to programmatically determine if a test has any errors or failures. As of the inclusion of async tests, cljs.test/run-tests returns nil. This makes it a bit verbose and redundant to write test runners that wish to use the default reporting but need to signal programmatically when there are errors or failures (such as when integrating with continuous build systems). As far as I can tell, the easiest approach under the current implementation looks like this:

;; All we care about is the error+fail count
;; and want cljs.test to print everything else as
;; normal.

(def error-count (atom 0))

(defmethod report [::test :pass] [m]
  ((get-method report [:cljs.test/default :pass]) m))

(defmethod report [::test :begin-test-ns] [m]
  ((get-method report [:cljs.test/default :begin-test-ns]) m))

(defmethod report [::test :error] [m]
  (swap! error-count inc)
  ((get-method report [:cljs.test/default :error]) m))

(defmethod report [::test :fail] [m]
  (swap! error-count inc)
  ((get-method report [:cljs.test/default :fail]) m))

(defmethod report [::test :summary] [m]
  ((get-method report [:cljs.test/default :summary]) m))

(defn runner
  []
  (run-tests (empty-env ::test) '...))

(from here)

This is true even when only sync tests are being used.

The docs mention that there is no support for coordination in cljs.test, which makes sense, but it seems like there should be a way to access the summary value without writing all of the report methods. Also, under the current implementation cljs.test/successful? appears to be unusable.



 Comments   
Comment by Sebastian Bensusan [ 01/May/15 1:30 PM ]

This problem is solved by the inclusion of :end-run-tests as specified in CLJS-1226.

You can define:

(defmethod cljs.test/report [:cljs.test/default :end-run-tests] [m]
  (cljs.test/successful? m]))

since m is the summary with {:type :end-run-tests}.





[CLJS-1277] relax requirement that files must declare a namespace, default to cljs.user Created: 19/May/15  Updated: 14/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

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


 Description   

This aligns better with Clojure itself supports.



 Comments   
Comment by David Nolen [ 14/Jun/15 10:30 AM ]

There are a few hurdles in order to make progress on this ticket. The first is that in order to be useful something like require etc. outside the ns needs to be supported in order to be useful. These should probably only be allowed to appear once. The same namespace cannot be supplied multiple times so the namespace will probably need to be made unique somehow.





[CLJS-1306] Browser REPL :asset-path with leading slash breaks source map support Created: 09/Jun/15  Updated: 14/Jun/15  Resolved: 14/Jun/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3308
Fix Version/s: Next

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


 Comments   
Comment by David Nolen [ 14/Jun/15 10:04 AM ]

fixed https://github.com/clojure/clojurescript/commit/3cf3098d7e183a02d290e5b7eaf1f5cca1508ecb





[CLJS-1304] Behavior of clojure.string/replace differs from Clojure Created: 09/Jun/15  Updated: 13/Jun/15

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

Type: Defect Priority: Major
Reporter: Luke VanderHart Assignee: Andrew Rosa
Resolution: Unresolved Votes: 0
Labels: None

Attachments: Text File CLJS-1304.patch    

 Description   

When using clojure.string/replace with a function as the replacement value, and using a regular expression with capturing groups, the behavior differs between Clojure and ClojureScript. In Clojure, the replacement fn is passed a tuple of the match and capturing group. In ClojureScript, it is only passed the match value.

In Clojure:

=> (println (str/replace "foobar" #"f(o)o" #(do (println %) "X")))
[foo o]
"Xbar"

In ClojureScript:

=> (println (str/replace "foobar" #"f(o)o" #(do (println %) "X")))
foo
Xbar


 Comments   
Comment by Daniel Woelfel [ 11/Jun/15 3:31 AM ]

If you're looking for a workaround, you can still get the match result from the 2nd arg:

=> (println (clojure.string/replace "foobar" #"f(o)o" (fn [& args] (do (println args) "X"))))
(foo o 0 foobar)
Xbar
Comment by Andrew Rosa [ 13/Jun/15 12:40 PM ]

Implementation and tests for the requested behaviour. Despite of the `vec` not being strictly necessary, I stick with it so the behaviour will be identical on both implementations.

Comment by David Nolen [ 13/Jun/15 5:07 PM ]

Is there any reason here to not just copy the Clojure implementation?

Comment by Andrew Rosa [ 13/Jun/15 5:25 PM ]

Hi David,

Clojure's impl was the first place that I look for, but this feature in special is written against the underlaying Java libraries. You can check it here.

Studying the Clojure implementation I found that there are some of re-* family of functions missing on ClojureScript side, and unfortunately they are heavily inspired on Java's Regex structure (return matchers, find and extract groups). MAYBE we can something like them to ClojureScript, but I don't know the real value there. Anyway, I think that port them or not is subject for another ticket - if you want that I investigate more, I could create it.

Comment by Francis Avila [ 13/Jun/15 5:47 PM ]

I made a proposal some time ago to bring clj and cljs re handling closer together: CLJS-776

Comment by David Nolen [ 13/Jun/15 8:51 PM ]

Andrew, was just looking for rationale. What you've done looks OK to me. People should try the patch and give feedback. Thanks!

Comment by Andrew Rosa [ 13/Jun/15 10:41 PM ]

Hi David, I understand and appreciate your concerns I just want to make clear what I've search and done, sorry if I sound rude - maybe I stepped on my language limitations.

Francis, really this re-* thing is tricky to deal with. I will take a closer look onto your ticket and see if I can add any idea.

Thanks everyone!





[CLJS-1303] runtime namespaces support for cljs.tools.reader Created: 09/Jun/15  Updated: 12/Jun/15

Status: In Progress
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3308
Fix Version/s: Next

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


 Description   

We should just piggieback on goog.dependencies_. This has all of the known namespaces. We should add the usual namespace helpers ns-map etc. but we should throw if COMPILED is false. This stuff can only work under :optimizations :none.






[CLJS-1290] :refer does not work with Closure JS namespaces Created: 27/May/15  Updated: 12/Jun/15  Resolved: 12/Jun/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

Type: Defect Priority: Major
Reporter: David Nolen Assignee: Maria Neise
Resolution: Completed Votes: 0
Labels: newbie

Attachments: Text File CLJS-1290.patch    

 Description   
(require '[goog.string :refer [startsWith]])

fails due to attempted var checking. We just need to disable var existence checks if we don't have a ClojureScript namespace.



 Comments   
Comment by Maria Neise [ 11/Jun/15 10:46 AM ]

Instead of disabling the check for non-ClojureScript namespaces, I thought we maybe could check if we have a Google Closure module. Attached patch CLJS-1290.patch.

Comment by David Nolen [ 12/Jun/15 10:55 AM ]

Wow awesome thanks! A much better solution!

Comment by David Nolen [ 12/Jun/15 10:56 AM ]

fixed https://github.com/clojure/clojurescript/commit/59a04ebffade090281d976fb7cd9033ab85db691





[CLJS-1092] CommonJS Module processing Created: 07/Mar/15  Updated: 12/Jun/15  Resolved: 12/Jun/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3211
Fix Version/s: GSoC

Type: Defect Priority: Major
Reporter: David Nolen Assignee: Maria Neise
Resolution: Completed Votes: 1
Labels: None

Attachments: Text File CLJS-1092.patch    

 Description   

Given a CommonJS file we should able to produce an IJavaScript map with :requires, :provides, etc.



 Comments   
Comment by Maria Neise [ 10/Jun/15 5:06 PM ]

I've attached the first patch for CommonJS support. It converts the modules before creating the dependency index and changes the compiler options so that the modules are treated as normal Google Closure modules. This version already replaces the "old" namespace with the "new" namespace when the require specification is analyzed for a cljs namespace. This results in an IJavaScript for the compiled sources that already includes the "new" module name as a requirement, which helps when looking up the dependency in the dependency index.

Happy to discuss this version and different approaches

Comment by David Nolen [ 11/Jun/15 9:15 AM ]

Maria this looks fantastic. The only problem is that it requires an unreleased version of Google Closure Compiler where the classes that were made public won't be available. I believe we'll want to do a conditional import and conditional compile only if the classes can be found. Clojure's reducers have a good example of this https://github.com/clojure/clojure/blob/master/src/clj/clojure/core/reducers.clj.

Comment by Maria Neise [ 11/Jun/15 11:04 AM ]

Ah, right, forgot about that. I will have a look at the conditional import and conditional compile and make changes to the patch accordingly. Thank you for the quick feedback

Comment by Maria Neise [ 11/Jun/15 6:13 PM ]

I attached a new version of the patch. We only compile and later call the relevant functions, if the constructors we need exist. We need to check for the constructors. Only checking for the classes is not sufficient, as it would still be successful even if they and their constructors would be private.

Comment by David Nolen [ 12/Jun/15 7:55 AM ]

Looks good! Will review in detail shortly.

Comment by David Nolen [ 12/Jun/15 10:05 AM ]

fixed https://github.com/clojure/clojurescript/commit/47947137127c9a724fafbeb17c5f7af7412809de





[CLJS-934] In the REPL return vars after defs Created: 30/Dec/14  Updated: 12/Jun/15  Resolved: 12/Jun/15

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

Type: Enhancement Priority: Minor
Reporter: David Nolen Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: None

Attachments: Text File CLJS-934-v1.patch     Text File CLJS-934-v2.patch     Text File CLJS-934-v3.patch     Text File CLJS-934-v4.patch    

 Description   

We don't want to emit these in during normal compilation. However it's nice to unify the REPL experience with Clojure's. Currently we just display the value of the def. REPLs could set a :repl build flag which is checked by the emit* :def case. For this to work the analyzer should compile the var AST and include it in the def AST so the compiler can optionally use it.



 Comments   
Comment by Mike Fikes [ 14/Jan/15 4:03 PM ]

A change was recently made to introduce new behavior if a :repl-verbose flag is set.

Perhaps all flags that control REPL behavior could be prefixed with :repl-, with the flag controlling this ticket controlled by :repl-def-vars or somesuch.

Comment by Mike Fikes [ 08/Jun/15 9:50 PM ]

The attached CLJS-934-v1.patch is worth giving a spin if you are interested in this ticket. It generally works with a few notes and caveats.

Demo:

$ script/noderepljs 
ClojureScript Node.js REPL server listening on 55574
To quit, type: :cljs/quit
cljs.user=> (defn square [x] (* x x))
#'cljs.user/square
cljs.user=> (def a 3)
#'cljs.user/a
cljs.user=> (def a)
#'cljs.user/a
  • It is triggered on detecting the presence of :repl-env, but could be revised to look for a dedicated :repl build flag.
  • It works for the non-init case (def a) which previously would fail in the REPL.
  • It works if the resulting var is later used. (def z (def a 3)) followed by @z yields 3.
  • But, it fails for situations where the resulting var is immediately used. @(def a 3) or {{((defn f [x] (+ 3 x)) 2)}}.

Happy to make revisions if desired, and also happy if this patch is declined but used as inspiration for a better one.

Comment by Mike Fikes [ 08/Jun/15 11:19 PM ]

The attached CLJS-934-v1.patch causes defmulti to fail at the REPL:

cljs.user=> (defmulti foo :op)
repl:1
Y,null,(cljs.core.truth_(cljs.user.foo)?cljs.user.foo.cljs$lang$test:null)]));
                                                                             ^
SyntaxError: Unexpected token ;
    at Object.exports.runInThisContext (vm.js:73:16)
    at Domain.<anonymous> ([stdin]:41:34)
    at Domain.run (domain.js:197:16)
    at Socket.<anonymous> ([stdin]:40:25)
    at Socket.emit (events.js:107:17)
    at readableAddChunk (_stream_readable.js:163:16)
    at Socket.Readable.push (_stream_readable.js:126:10)
    at TCP.onread (net.js:529:20)

Additionally, it doesn't return the var if you define a multi-arity fn.

Comment by Mike Fikes [ 09/Jun/15 11:39 AM ]

The attached CLJS-934-v2.patch takes a slight alternate approach that emits correct JavaScript for various cases by doing the assignment and var production in a closure.

With this, "immediate" use works: @(def a 3) so does

((defn f [x] (+ 3 x)) 2)
.

This also clears up issues that occur with defmulti and defonce.

The only unfortunate puzzle remaining at this point is that (defn f [] (def a 3)) fails, with the var generation appearing to occur twice in the JavaScript for some odd reason that I haven't sorted.

Sharing this patch as it appears to be a lot closer to a potential solution.

Comment by Mike Fikes [ 09/Jun/15 3:42 PM ]

The attached CLJS-934-v3.patch addresses the issue encountered with a form that looks like

(defn f [] (def a 3))

While it works, I suspect the implementation has an unnecessary amount of explicit JavaScript emitln emission related to return and function use that can be done in a cleaner way.

Comment by Mike Fikes [ 09/Jun/15 4:32 PM ]

In hindsight, I read the code for compiler.cljc and it's more common to explicitly embed emitln with return and function constructs than I expected. So, in short, CLJS-934-v3.patch may be good for review.

Comment by Mike Fikes [ 11/Jun/15 9:38 AM ]

IRC Feedback from David:

[10:29:00]  <dnolen>	mfikes: so the var thing looks pretty good. However for compiler hackers it generates a lot of noise because of the var metadata dump. I think we need some way to disable it for the case where we want to debug code gen.
[10:29:38]  <mfikes>	OK.... maybe AST emission can also be conditional?
[10:30:12]  <mfikes>	I have a concern that it could slow down or bloat AST generation if it is always on.
[10:30:45]  <dnolen>	yeah I think what we want is :def-emits-vars which always defaults to false, in REPLs defaults to true.
[10:30:55]  <dnolen>	however you can pass the option to override.
[10:31:32]  <mfikes>	OK... I can try working something like that into a revision to the patch
[10:31:57]  <dnolen>	otherwise it works great, definitely removes a big difference in the REPL experience.
[10:32:45]  <dnolen>	so the patch should use :def-emits-vars to gen the AST and emit etc. REPL should be changed to default to true if not specified.
[10:33:13]  <dnolen>	if not specified just means false, will work since lookup will return nil.
[10:33:25]  <dnolen>	in the compiler case (not REPL case)
[10:33:47]  <mfikes>	dnolen: Sounds cool. I can work that into it. :)
[10:33:54]  <dnolen>	k thanks!
Comment by Mike Fikes [ 11/Jun/15 1:18 PM ]

CLJS-934-v4.patch makes two primary revisions:

  1. Introduces a REPL option :def-emits-vars which defaults to true and which is conveyed into the analysis/compilation environment by cljs.repl
  2. The var AST is no longer unconditionally included in the def AST and the analyzer instead looks for :def-emits-vars

Notably, this patch doesn't go so far as to treat :def-emits-vars additionally as a build-affecting compiler option. Rationale: It affects AST generation. It also seems currently unlikely that there would be desire to actually support compiling code with this enabled.

Comment by Mike Fikes [ 11/Jun/15 1:43 PM ]

One bit of follow-up with respect to CLJS-934-v4.patch. I failed to notice that the JavaScript is also generated and displayed if :repl-verbose true is set.

Patch 4 REPL interactions look like this if :repl-verbose is set:

cljs.user=> (def a 3)
cljs.user.a = (3)
#'cljs.user/a
cljs.user=> (defn square [x] (* x x))
cljs.user.square = (function cljs$user$square(x){
return (x * x);
})
#'cljs.user/square

In the above, in particular, you don't see the additional var emission JavaScript which is actually included when producing wrap-js, which does *1 *2 *3 *e, etc., as well.

If the purpose of :repl-verbose is to simply help the end user in seeing the "logical" JavaScript that corresponds to forms, then the above is great, but if it is for truly diagnosing low-level things, then including this extra var stuff is possible and would look like the below. (I'm suspecting it is the former and not the latter, as *1 and friends are omitted when :repo-verbose is true, but an additional patch could be created which produces the output below.)

cljs.user=> (def a 3)
(function (){
cljs.user.a = (3); return (
new cljs.core.Var(function(){return cljs.user.a;},new cljs.core.Symbol("cljs.user","a","cljs.user/a",185392220,null),cljs.core.PersistentHashMap.fromArrays([new cljs.core.Keyword(null,"ns","ns",441598760),new cljs.core.Keyword(null,"name","name",1843675177),new cljs.core.Keyword(null,"file","file",-1269645878),new cljs.core.Keyword(null,"end-column","end-column",1425389514),new cljs.core.Keyword(null,"source","source",-433931539),new cljs.core.Keyword(null,"column","column",2078222095),new cljs.core.Keyword(null,"line","line",212345235),new cljs.core.Keyword(null,"end-line","end-line",1837326455),new cljs.core.Keyword(null,"arglists","arglists",1661989754),new cljs.core.Keyword(null,"doc","doc",1913296891),new cljs.core.Keyword(null,"test","test",577538877)],[new cljs.core.Symbol(null,"cljs.user","cljs.user",877795071,null),new cljs.core.Symbol(null,"a","a",-482876059,null),"<cljs repl>",7,"a",1,1,1,cljs.core.List.EMPTY,null,(cljs.core.truth_(cljs.user.a)?cljs.user.a.cljs$lang$test:null)])));})()

#'cljs.user/a
cljs.user=> (defn square [x] (* x x))
(function (){
cljs.user.square = (function cljs$user$square(x){
return (x * x);
}); return (
new cljs.core.Var(function(){return cljs.user.square;},new cljs.core.Symbol("cljs.user","square","cljs.user/square",-1166044571,null),cljs.core.PersistentHashMap.fromArrays([new cljs.core.Keyword(null,"ns","ns",441598760),new cljs.core.Keyword(null,"name","name",1843675177),new cljs.core.Keyword(null,"file","file",-1269645878),new cljs.core.Keyword(null,"end-column","end-column",1425389514),new cljs.core.Keyword(null,"source","source",-433931539),new cljs.core.Keyword(null,"column","column",2078222095),new cljs.core.Keyword(null,"line","line",212345235),new cljs.core.Keyword(null,"end-line","end-line",1837326455),new cljs.core.Keyword(null,"arglists","arglists",1661989754),new cljs.core.Keyword(null,"doc","doc",1913296891),new cljs.core.Keyword(null,"test","test",577538877)],[new cljs.core.Symbol(null,"cljs.user","cljs.user",877795071,null),new cljs.core.Symbol(null,"square","square",-1842001092,null),"<cljs repl>",13,"square",1,1,1,cljs.core.list(new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Symbol(null,"x","x",-555367584,null)], null)),null,(cljs.core.truth_(cljs.user.square)?cljs.user.square.cljs$lang$test:null)])));})()

#'cljs.user/square
Comment by David Nolen [ 12/Jun/15 7:54 AM ]

The approach in patch 4 is the right one. When any of the debugging modes are engaged we don't want to generate the "extra" stuff.

Comment by David Nolen [ 12/Jun/15 9:44 AM ]

fixed https://github.com/clojure/clojurescript/commit/92551f1bc39a7d0a0235b94e871a9fe66475686f





[CLJS-1307] Doc for ns missing Created: 10/Jun/15  Updated: 11/Jun/15  Resolved: 11/Jun/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3308
Fix Version/s: None

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

script/noderepljs on OS X


Attachments: Text File CLJS-1307.patch    

 Description   

(doc ns) yields no doc string

$ script/noderepljs 
ClojureScript Node.js REPL server listening on 58122
To quit, type: :cljs/quit
cljs.user=> (doc ns)

nil


 Comments   
Comment by Mike Fikes [ 10/Jun/15 12:06 PM ]

The attached CLJS-1307.patch assumes that ns is a special form in ClojureScript, and takes the current documentation from the Wiki as at least a starting point:

cljs.user=> (doc ns)
-------------------------
ns
   (name docstring? attr-map? references*)
Special Form
  You must currently use the ns form only with the following caveats

    * You must use the :only form of :use
    * :require supports :as and :refer
      - both options can be skipped
      - in this case a symbol can be used as a libspec directly
        - that is, (:require lib.foo) and (:require [lib.foo]) are both
          supported and mean the same thing
      - prefix lists are not supported
    * The only option for :refer-clojure is :exclude
    * :import is available for importing Google Closure classes
      - ClojureScript types and records should be brought in with :use
        or :require :refer, not :import ed
    * Macros are written in Clojure, and are referenced via the new
      :require-macros / :use-macros options to ns
      - :require-macros and :use-macros support the same forms that
        :require and :use do

  Implicit macro loading: If a namespace is required or used, and that
  namespace itself requires or uses macros from its own namespace, then
  the macros will be implicitly required or used using the same
  specifications. This oftentimes leads to simplified library usage,
  such that the consuming namespace need not be concerned about
  explicitly distinguishing between whether certain vars are functions
  or macros.

  Inline macro specification: As a convenience, :require can be given
  either :include-macros true or :refer-macros [syms...]. Both desugar
  into forms which explicitly load the matching Clojure file containing
  macros. (This works independently of whether the namespace being
  required internally requires or uses its own macros.) For example:

  (ns testme.core
  (:require [foo.core :as foo :refer [foo-fn] :include-macros true]
            [woz.core :as woz :refer [woz-fn] :refer-macros [app jx]]))

  is sugar for

  (ns testme.core
  (:require [foo.core :as foo :refer [foo-fn]]
            [woz.core :as woz :refer [woz-fn]])
  (:require-macros [foo.core :as foo]
                   [woz.core :as woz :refer [app jx]]))

  Please see http://clojure.org/special_forms#ns
Comment by David Nolen [ 11/Jun/15 9:20 AM ]

fixed https://github.com/clojure/clojurescript/commit/48d50bfbba31a80586c89916f8c28a4f09481a25





[CLJS-1305] Node.js REPL load-file regression Created: 09/Jun/15  Updated: 09/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3308
Fix Version/s: Next

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


 Description   

Appears to be the same as the one we encountered in browser REPL due to the Closure Library dep bump.






[CLJS-1302] (js/goog.base (js* "this")) no longer works Created: 09/Jun/15  Updated: 09/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3308
Fix Version/s: Next

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


 Description   
(defn Foo
  []
  (goog/base (js* "this")))
(goog/inherits Foo js/Object)

(defn Foo
  []
  (this-as this
    (goog/base this)))
(goog/inherits Foo js/Object)





[CLJS-1301] local :foreign-libs are not picked up the first time browser REPL is started Created: 05/Jun/15  Updated: 06/Jun/15  Resolved: 06/Jun/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3308
Fix Version/s: Next

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


 Description   

Attempting to use local CodeMirror addons surfaced the issue. After the first REPL run load-file appears to work. However the the first REPL run returns an error from cljs.analyzer/analyze-deps about not being able to find the deps.



 Comments   
Comment by David Nolen [ 06/Jun/15 12:47 PM ]

fixed https://github.com/clojure/clojurescript/commit/b73595e26f3f45f1fd8ab4d97fb3f9ab941ff696





[CLJS-1298] source-on-disk conditional should include :source-url Created: 05/Jun/15  Updated: 05/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3308
Fix Version/s: Next

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

All



 Description   

cljs.closure/source-on-disk is conditional on having the IJavaScript having a :source-url. Currently this conditional is exercised after the call to util/ext. But util/ext has a precondition that will fail on a nil :source-url.

Solution: protect util/ext by checking for :source-url before calling util/ext.

(defn source-on-disk
  "Ensure that the given IJavaScript exists on disk in the output directory.
  Return updated IJavaScript with the new location if necessary."
  [opts js]
  (if (write-js? js)
    (write-javascript opts js)
    ;; always copy original ClojureScript sources to the output directory
    ;; when source maps enabled
    (let [out-file (when-let [ns (and (:source-map opts)
                                      (:source-url js) ;;<--- ADD THIS HERE
                                      (first (:provides js)))]
                     (io/file (io/file (util/output-directory opts))
                       (util/ns->relpath ns (util/ext (:source-url js)))))
          source-url (:source-url js)]
      (when (and out-file source-url
                 (or (not (.exists ^File out-file))
                     (> (.lastModified (io/file source-url))
                        (.lastModified out-file))))
        (spit out-file (slurp source-url)))
      js)))

Or some refactoring of the above.



 Comments   
Comment by David Nolen [ 05/Jun/15 2:20 PM ]

In what cases will an IJavaScript not have a :source-url? Just trying to get some context.

Comment by Bruce Hauman [ 05/Jun/15 2:42 PM ]

Good question. When the sources are already output javascript and they have an output dir relative :url but not a :source-url, this doesn't seem like it should happen.

I'm getting a situation like this

:url #object[java.net.URL 0x5f921081 "file:/Users/brucehauman/workspace/temp/hello-world/resources/goog/uri/utils.js"]
:source-url nil

Comment by David Nolen [ 05/Jun/15 2:58 PM ]

Ok that seems like the real underlying issue. Do you have a small reproducer by chance?

Comment by Bruce Hauman [ 05/Jun/15 3:08 PM ]

It seems like its when the :asset-path is "". And :output-dir is at the root of a resource path like :output-dir "resources".





[CLJS-1300] REPLs do no write out updated deps.js when compiling files Created: 05/Jun/15  Updated: 05/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3308
Fix Version/s: Next

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


 Description   

For example a user may edit a file including a new dependency. This will work at the REPL but if a browser refresh is made the emitted goog.require will fail due to the initial deps.js file being stale.






[CLJS-1297] defrecord does not emit IKVReduce protocol Created: 03/Jun/15  Updated: 04/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3308
Fix Version/s: Next

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


 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.





[CLJS-994] print a warning when :externs file paths can't be found. Created: 30/Jan/15  Updated: 01/Jun/15

Status: Reopened
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

Type: Enhancement Priority: Major
Reporter: Crispin Wellington Assignee: David Nolen
Resolution: Unresolved Votes: 0
Labels: cljs, enhancement, errormsgs, patch,
Environment:

Linux 64bit

java version "1.7.0_65"
OpenJDK Runtime Environment (IcedTea 2.5.3) (7u71-2.5.3-0ubuntu0.14.04.1)
OpenJDK 64-Bit Server VM (build 24.65-b04, mixed mode)


Attachments: Text File clojurescript-extern-missing-warning.patch    
Patch: Code

 Description   

clojurescript silently ignores missing externs files possibly leading a developer to chase their tail.

Presently it can be very confusing using advanced compilation if you have made a mistake in the path name of one of your :externs files. This patch makes the compiler print a warning on stderr so you can quickly determine the cause of the broken advanced compilation output.

As a side effect, when doing a basic lein-cljsbuild a warning is always printed:

```
WARNING: js resource path closure-js/externs does not exist
```

This is because lein-cljsbuild quietly adds this extra path to your :externs listing without you knowing.



 Comments   
Comment by David Nolen [ 31/Jan/15 1:59 PM ]

You need to bind *out* to *err*, or just print to it directly a la cljs.util/debug-prn.

Comment by Crispin Wellington [ 31/Jan/15 7:30 PM ]

I did bind out to err. Check the patch.

Comment by David Nolen [ 01/Feb/15 12:30 PM ]

Crispin, oops sorry you are correct. Thanks.

Comment by David Nolen [ 13/Mar/15 7:33 AM ]

fixed https://github.com/clojure/clojurescript/commit/5f66a78bf469a9875e51aa39c29d3e66ce890eb4

Comment by David Nolen [ 14/Mar/15 5:55 AM ]

The solution does not work for cljsbuild. It's unclear why there so much machinery in place over the approach taken for deps.clj.

Comment by David Nolen [ 15/Mar/15 10:37 AM ]

Stalled on this cljsbuild issue https://github.com/emezeske/lein-cljsbuild/issues/383

Comment by Crispin Wellington [ 23/Mar/15 2:50 AM ]

This lein-cljsbuild issue is what made me make it just a warning initially, and not a hard error like raising IllegalArgumentException does. Though I agree it should be a hard error. If we start with a warning, it enables the immediate problem for the developer to be resolved, and leaves a wart that the cljs-build project can then see that need fixing on their end. Then when that end is fixed it could be made a hard error. If cljsbuild is fixed fairly soon then all is well, but if it takes a long time, a warning might be a good first step.





[CLJS-836] Replace seq-based iterators with direct iterators for all non-seq collections that use SeqIterator Created: 08/Aug/14  Updated: 01/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

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

Attachments: Text File cljs_836_v1.patch     Text File cljs_836_v2.patch    
Patch: Code and Test

 Description   

See http://dev.clojure.org/jira/browse/CLJ-1499



 Comments   
Comment by Peter Schuck [ 12/Dec/14 4:56 PM ]

This is a port of the patches / diffs at http://dev.clojure.org/jira/browse/CLJ-1499. I'm getting around a 2X perf improvement when running the benchmark quite.

Comment by David Nolen [ 13/Dec/14 8:43 AM ]

Thanks, looks great! Will check with Alex Miller about the status of CLJ-1499 and see if we can apply this one.

Comment by Peter Schuck [ 03/Apr/15 10:10 AM ]

CLJ-1499 has been applied to Clojure. I updated the patch to update the tests.





[CLJS-1125] Simple corrupted compiled file detection Created: 16/Mar/15  Updated: 01/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

Type: Enhancement Priority: Major
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-1141] memoization of js-dependency-index and get-upstream-deps needs knobs Created: 18/Mar/15  Updated: 01/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

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

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

 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.





[CLJS-1247] Add *out* and *err* Created: 04/May/15  Updated: 01/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

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


 Comments   
Comment by David Nolen [ 06/May/15 9:02 AM ]

See CLJS-710





[CLJS-620] Warnings are generated when using a macro in argument position Created: 14/Oct/13  Updated: 01/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

Type: Defect Priority: Minor
Reporter: Julien Eluard Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None

Attachments: File CLJS-620.diff    

 Description   

Using a macro in argument position (e.g. (map macro [])) generates a warning:
WARNING: Use of undeclared Var test/node at line 4 src/test.cljs

Find a reproduction project here.



 Comments   
Comment by Jozef Wagner [ 15/Oct/13 3:30 AM ]

and what would you like, a better warning? Clojurescript allows same name for macro and for function, so you can both have macro + and fn +. Macro version will be used when is first in the list, fn version otherwise.

Comment by Jonas Enlund [ 15/Oct/13 3:38 AM ]

For reference, Clojure generates the following error message:

user=> (map when [])
CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/when, compiling:(NO_SOURCE_PATH:1:1)

The "obvious" approach would be to add

(when-let [m (get-expander sym env)]
  (throw (error env (str "Can’t take value of a macro: " m))))

to resolve-var[1]. Unfortunately this doesn’t work in ClojureScript due to the way inlining works. A simple workaround is to add {:inline true} metadata to macros that are later redefined as functions in core.cljs and check for invalid macro usage like this:

(when-let [m (get-expander sym env)]
  (and (-> m meta :inline not)    
       (throw (error env (str "Can’t take value of a macro: " m)))))

Another approach would perhaps be to rethink how inlining works as it seems kind of brittle to have macros in cljs/core.clj with the same name as functions in cljs/core.cljs (especially since both namespaces are auto-imported. Is cljs.core/inc a function, a macro, or both?). Maybe there’s a better way?

[1] https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/analyzer.clj#L193

Comment by Julien Eluard [ 15/Oct/13 6:23 AM ]

My bad, didn't realize it didn't make sense. Of course it's obvious now. I was confused by recent changes around function/macro name validation.
Now the warning could probably be improved a little but that doesn't seem very important. The Clojure warning is not that much better.

Comment by David Nolen [ 15/Oct/13 11:58 AM ]

We're not going to change how inlining works - the whole point is that we can reuse the same names. Adding :inline metadata seems like a promising way to warn of incorrect usage of inlining macros.





[CLJS-1128] Describe internationalization strategies via Google Closure on the wiki Created: 16/Mar/15  Updated: 01/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

Type: Task Priority: Minor
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: documentation, newbie


 Description   

This can be done via Google Closure defines or via pulling a specific locale. A page should document how this can be done.






[CLJS-1133] REPL require results in warnings to be emitted twice Created: 17/Mar/15  Updated: 01/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

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-1276] var equality differs from Clojure Created: 18/May/15  Updated: 01/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

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


 Description   

(= #'x #'x) and (identical? #'x #'x) both fail. One solution would be to implement IEquiv and add var-identical? a la keyword-identical?.






[CLJS-773] Use unchecked-*-int functions for real 32-bit math Created: 26/Feb/14  Updated: 01/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

Type: Enhancement Priority: Major
Reporter: Francis Avila Assignee: Francis Avila
Resolution: Unresolved Votes: 0
Labels: numerics
Environment:

r2173



 Description   

Currently the unchecked-* functions and macros simply alias the primitive js operators. It would be nice if the unchecked-*-int family of functions and macros implemented C/Java-like signed int operations with silent overflows (just like in Clojure) using asm.js coersion idioms. This should also allow us to share such code between clojure and clojurescript without worrying about their different numerics.

A use case is that porting hash algorithms from java to clojurescript is trickier and more verbose than it needs to be.



 Comments   
Comment by David Nolen [ 08/May/14 6:43 PM ]

This sounds interesting, would like to see more thoughts on approach, benchmarks etc.

Comment by David Nolen [ 02/Dec/14 5:46 AM ]

Bump, this enhancements sound simple & fine.

Comment by Francis Avila [ 02/Dec/14 1:26 PM ]

I'll have time to do this in about a week. The implementation is straightforward (basically use xor 0 everywhere). The goal is correctness, but I expect performance to be as good as or better than it is now on most platforms. I'm not sure if advanced mode will drop intermediate truncations or what impact this has on performance.

Some higher-level numeric analysis using the asm.js type system is possible but I doubt it's worth it.

Comment by Francis Avila [ 16/Mar/15 11:14 AM ]

I completely forgot about this, sorry. I see you have scheduled it for the "next" release. Are you assigning it as well or will you still accept a patch?

Comment by David Nolen [ 16/Mar/15 11:26 AM ]

Be my guest





[CLJS-1127] validate compiled file written to disk Created: 16/Mar/15  Updated: 01/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

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


 Description   

If we validate the file written to disk then we can catch common error of running multiple build processes and abort.






[CLJS-1139] Repeated applications of `ns` form at the REPL are not additive Created: 17/Mar/15  Updated: 01/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

Type: Defect Priority: Major
Reporter: Michael Griffiths Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Quick start guide with Node REPL



 Description   

In a Clojure REPL, it is possible to declare the same namespace again, without existing namespaces aliases being altered or removed:

user=> (ns my-test-ns.core (:require [clojure.string :as string]))
nil
my-test-ns.core=> (def a string/blank?)
#'my-test-ns.core/a
my-test-ns.core=> (ns my-test-ns.core)
nil
my-test-ns.core=> (def a string/blank?)
#'my-test-ns.core/a
my-test-ns.core=>

ClojureScript REPLs do not behave in the same way:

ClojureScript:cljs.user> (ns my-test-ns.core (:require [clojure.string :as string]))
true
ClojureScript:my-test-ns.core> (def a string/blank?)
#<function clojure$string$blank_QMARK_(s){
return goog.string.isEmptySafe(s);
}>
ClojureScript:my-test-ns.core> (ns my-test-ns.core)
nil
ClojureScript:my-test-ns.core> (def a string/blank?)
WARNING: No such namespace: string, could not locate string.cljs at line 1 <cljs repl>
WARNING: Use of undeclared Var string/blank? at line 1 <cljs repl>
repl:13
throw e__3919__auto__;
      ^
ReferenceError: string is not defined
    at repl:1:109
    at repl:9:3
    at repl:14:4
    at Object.exports.runInThisContext (vm.js:74:17)
    at Domain.<anonymous> ([stdin]:41:34)
    at Domain.run (domain.js:197:16)
    at Socket.<anonymous> ([stdin]:40:25)
    at Socket.emit (events.js:107:17)
    at readableAddChunk (_stream_readable.js:163:16)
    at Socket.Readable.push (_stream_readable.js:126:10)
ClojureScript:my-test-ns.core>





[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: 01/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

Type: Defect Priority: Major
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 0
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-1174] Simple warning if a namespace with dashes not found but a file path with dashes exists Created: 27/Mar/15  Updated: 01/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

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





[CLJS-1237] ns-unmap doesn't work on refers from cljs.core Created: 01/May/15  Updated: 01/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

Type: Defect Priority: Major
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-1280] double analysis warnings when using cljs.repl/load-file special fn Created: 21/May/15  Updated: 01/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

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





[CLJS-1287] CLJS exceptions should use same format as Clojure 1.7 (#exception {...}) Created: 25/May/15  Updated: 01/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

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


 Description   

Recent Clojure 1.7-RC adds new print format compatible with EDN syntax:

(ex-info "foobar" {:bar :baz})
#error {
 :cause "foobar"
 :data {:bar :baz}
 :via
 [{:type clojure.lang.ExceptionInfo
   :message "foobar"
   :data {:bar :baz}
   :at [clojure.core$ex_info invoke "core.clj" 4591]}]
 ...
}

(try (.indexOf 0 "baz") (catch Throwable e e))
#error {
 :cause "No matching method found: indexOf for class java.lang.Long"
 :via
 [{:type java.lang.IllegalArgumentException
   :message "No matching method found: indexOf for class java.lang.Long"
   :at [clojure.lang.Reflector invokeMatchingMethod "Reflector.java" 53]}]
 ...
}

Unfortunatelly ClojureScript format is different (and sometimes even not compatible with EDN):

(ex-info "foobar" {:bar :baz})
#ExceptionInfo{:message "foobar", :data {:bar :baz}}

(try (.indexOf 0  "baz") (catch js/Error e e))
#<TypeError: Object 0 has no method 'indexOf'>

The request to unify the output of exceptions might sound like "nitpicking".

However please consider applications, which share (lots of) code between server and client.
Any arbitrary difference between Clojure and ClojureScript adds future accidental complexity.

Hint: looking for green light and answer patches welcome

Last thing to consider is how to deal with stacktraces in the patch. Recent CLJS parses have a parser implemented on server side in Clojure. Should the patch move parsing to ClojureScript?



 Comments   
Comment by David Nolen [ 25/May/15 10:14 AM ]

Yes patch welcome. Thanks!





[CLJS-349] cljs.compiler: No defmethod for emit-constant clojure.lang.LazySeq Created: 30/Jul/12  Updated: 01/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

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-434] ClojureScript compiler prepends "self__" to defmulti forms when metadata in form of ^:field. Created: 01/Dec/12  Updated: 01/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

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-1129] :modules tutorial for wiki Created: 16/Mar/15  Updated: 01/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

Type: Task Priority: Minor
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: documentation, newbie


 Description   

The documentation is nice but something that walks people through the steps would be nicer.






[CLJS-1136] Initial require fails to fully load added symbols Created: 17/Mar/15  Updated: 01/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

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

Quick Start Browser REPL (OS X / Safari)



 Description   

In the Quick Start, a portion runs the user through adding a symbol (a function named foo) and then requiring the namespace and using that symbol. I'm finding that require fails and that I need to add the :reload directive.

To reproduce:

  1. Run through the Quick Start up through the browser REPL section.
  2. Set src/hello_world/core.cljs so that it does not have the foo function defined.
  3. Remove the out directory: rm -rf out
  4. Start up the REPL: rlwrap java -cp cljs.jar:src clojure.main repl.clj
  5. Connect Safari by going to http://localhost:9000
  6. Show the error console in Safari. (You'll see Hello world.)
  7. Run tail -f out/watch.log
  8. Add the foo function that adds a b to src/hello_world/core.cljs and save it.
  9. Observe that watch.log reflects recompilation
  10. Do {{ (require '[hello-world.core :as hello]) }}
  11. Do {{ (hello/foo 2 3) }}

At this point you will get:
TypeError: undefined is not an object (evaluating 'hello_world.core.foo.call')

But:

ClojureScript:cljs.user> (ns-interns 'hello-world.core)
{foo #'hello-world.core/foo, conn #'hello-world.core/conn}
ClojureScript:cljs.user> (source hello/foo)
(defn foo [a b]
  (+ a b))
nil

Now, if you :reload

ClojureScript:cljs.user> (require '[hello-world.core :as hello] :reload)
nil
ClojureScript:cljs.user> (hello/foo 2 3)
5


 Comments   
Comment by Mike Fikes [ 17/Mar/15 11:30 AM ]

Prior to step 8:

ClojureScript:cljs.user> (ns-interns 'hello-world.core)
{}

Between steps 9 and 10:

ClojureScript:cljs.user> (ns-interns 'hello-world.core)
{foo #'hello-world.core/foo, conn #'hello-world.core/conn}

My guess: Watching is causing symbols to be interned, but not usable, and this is interfering with require forcing you to include :reload.

Comment by David Nolen [ 22/Mar/15 9:46 AM ]

I'm not sure that this is actually an issue, the browser has already required the namespace, it's the entry point. Thus you really do need a :reload. But the reason you see interned symbols is that the watch process shares the compilation environment with the REPL. It may be the case that with the dramatically improved REPLs the watch option becomes entirely unnecessary and counterintuitive, let's see how it goes.





[CLJS-1286] REPL environment should be able to provide advice if source mapping fails Created: 23/May/15  Updated: 01/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

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-712] resolve-var for symbol with dot still wrong Created: 03/Dec/13  Updated: 01/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

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-719] this-as behaves incorrectly in "scoping function" Created: 07/Dec/13  Updated: 01/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

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


 Description   

When a this-as expression gets put in a "scoping function", e.g. in a let-binding, the value bound via this-as refers to the scoping function, and not to the outer scope.

Example:

(def foo
  (js-obj
    "bar" "baz"
    "getBarRight" (fn [] (this-as self (.-bar self)))
    "getBarWrong" (fn []
                    (let [bar (this-as self (.-bar self))]
                      bar))))
     
(.log js/console (.getBarRight foo)) ;; => "baz"
(.log js/console (.getBarWrong foo)) ;; => undefined

Whereas foo.getBarRight expands to something like

function() {
  var self = this; // this refers to foo
  return self.bar; // returns "bar"
}

foo.getBarWrong on the other hand expands to

function() {
  var bar = function() {
    var self = this; // this refers to enclosing function
    return self.bar; // returns undefined
  }();
  return bar; // returns undefined
}





[CLJS-818] Externs don't get loaded when running under immutant as cljs.js-deps/find-js-classpath fails Created: 18/Jun/14  Updated: 01/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

Type: Defect Priority: Major
Reporter: James Cash Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Java 1.8.0_05, Clojure 1.6.0, clojurescript 0.0-2234, immutant 1.1.1


Attachments: Text File 818.patch     PNG File Screen Shot 2014-06-18 at 20.14.59 .PNG    

 Description   

When compiling clojurescript that relies on library-provided externs (e.g. Om needing React.js externs), the clojurescript is compiled without errors, but the generated javascript fails to work, due to the externs not being loaded. Externs don't get loaded, as cljs.js-deps/find-js-classpath doesn't find the javascript externs file. This occurs because it uses cljs.js-deps/all-classpath-urls, which filters out the immutant classloader, since org.immutant.core.ImmutantClassLoader is not an instance of java.net.URLClassLoader (and hence lacks a .getURLs method anyway).



 Comments   
Comment by Toby Crawley [ 19/Jun/14 9:23 AM ]

Chas: Is there a reason not to depend on dynapath here? This exact case is kinda why it exists

Comment by David Nolen [ 19/Jun/14 10:47 AM ]

Patch welcome for this.

Comment by James Cash [ 19/Jun/14 2:12 PM ]

Simply replacing cljs.js-deps/all-classpath-urls with dynapath.util/all-classpath-urls worked for me. I don't know if there are policies around adding dependencies to cljs, but the following patch is working for me. Would it be preferable to re-implement the functionality instead?

Comment by David Nolen [ 19/Jun/14 2:19 PM ]

We are not going to take on a dependency for this. The code should be copied over, thanks.

Comment by James Cash [ 19/Jun/14 3:46 PM ]

Due to the way dynapath works, I don't think a straightforward copying of the code will work, since it relies on a protocol. Backing up a step though, would it be reasonable for externs to be loaded via io/resource, in the same way that the :preamble is?

Comment by Toby Crawley [ 19/Jun/14 3:54 PM ]

Unfortunately, the code can't be copied over. Dynapath works by providing a protocol that providers/users of funky classloaders can implement, allowing libraries that use dynapath to access the dynamic features of those classloaders without having to care about the loader's concrete type. Dynapath itself provides implementations for j.n.URLClassLoader and c.l.DynamicClassloader by default, so libraries don't have to do anything special to access the dynamic features of those classes.

java.classpath also provides a similar mechanism that the Immutant classloader implements as well. If you are more open to dependencies that are under org.clojure, using that will work as well. Ideally, I'd like to see java.classpath subsume dynapath.

Comment by James Cash [ 19/Jun/14 4:23 PM ]

Made a new patch that sidesteps the all-classpath-urls issue by just using io/resource instead of iterating over all urls

Comment by David Nolen [ 01/Jul/14 9:26 PM ]

Can people chime in whether the patch works for them, thanks.





[CLJS-868] no arity warnings on recursive calls Created: 03/Oct/14  Updated: 01/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

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


 Description   

If a function recursively invokes itself within its own body the invoke will not be checked for arity mismatch.






[CLJS-968] Metadata on function literal inside of a let produces invalid Javascript Created: 07/Jan/15  Updated: 01/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

Type: Defect Priority: Major
Reporter: Bobby Eickhoff Assignee: David Nolen
Resolution: Unresolved Votes: 1
Labels: bug
Environment:

Originally found with [org.clojure/clojurescript "0.0-2496"]
Still reproducible with the latest cljsc (b5e9a5116259fc9f201bee4b9c6564f35306f9a5)



 Description   

Here is a minimal test case that produces the invalid Javascript:

(defn f []
  (let [a 0]
    ^{"meta" "data"}
    (fn [] true)))

The compiled Javascript includes the invalid token sequence "return return". (Per Chrome: Uncaught SyntaxError: Unexpected token return)

The problem does not occur if the metadata applies to a map literal instead of a function literal.
The problem only occurs when the function and metadata are inside of a let.



 Comments   
Comment by Bobby Eickhoff [ 07/Jan/15 9:45 PM ]

I forgot to try with-meta. Using with-meta does not produce this syntax error, so it's only a problem with the reader macro for metadata.

Comment by David Nolen [ 08/Jan/15 7:41 AM ]

Any quick thoughts about this one Nicola? Quite possibly a compiler issue on the CLJS side.

Comment by Nicola Mometto [ 08/Jan/15 8:07 AM ]

David, I understand why this happens but I don't know enough about how cljs's js emission to propose a fix.
The issue is that with this commit: https://github.com/clojure/clojurescript/commit/d54defd32d6c5ffcf6b0698072184fe8ccecc93a the following scenario is possible:

{:op :meta
 :env {:context :return}
 :expr {:op :fn
        :env {:context :expr}
        :methods [{:op :fn-method 
                   :env {:context :return} ..}]
        ..}
 ..}

i.e. analyze-wrap-meta changes the context of the :fn node to :expr but keeps the context of the :fn-methods to :return.

This causes both
https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/compiler.clj#L575-L576
and
https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/compiler.clj#L488 (https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/compiler.clj#L233)

to be true and emit a "return".

Comment by David Nolen [ 06/May/15 7:15 PM ]

Hrm, it appears analyze-wrap-meta may need to defer to a helper to change the :context of the given AST node.





[CLJS-1228] cljs.util/topo-sort is polynomial on larger dependency graphs Created: 28/Apr/15  Updated: 01/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

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


 Comments   
Comment by David Nolen [ 08/May/15 7:35 AM ]

This problem was reported due the performance of cljs.analyzer/ns-dependents when used by cljs.compiler/compile-file. However as cljs.compiler/compile-file does not need the topological sorting bit, we should supply a faster alternative to cljs.analyzer/ns-dependents which simply returns a distinct seq which can be poured into a set.





[CLJS-428] Using */ inside of a docstring causes compiler to produce invalid JavaScript Created: 25/Nov/12  Updated: 01/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

Type: Defect Priority: Minor
Reporter: Murphy McMahon Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Linux, lein-cljsbuild


Attachments: Text File cljs_428.patch    

 Description   

Due to how function docstrings are output by the ClojureScript compiler, the use of

*/
within a docstring causes the compiler to produce invalid JavaScript, breaking compilation, since '*/' will close the docstring's JavaScript comment block and the remaining docstring text will be uncommented as a result.



 Comments   
Comment by Murphy McMahon [ 25/Nov/12 12:32 PM ]

I didn't realize JIRA treats asterisks as markup, so just for clarification: the characters that produce the defect are slash asterisk, ie JavaScript's block comment closing syntax.

Comment by David Nolen [ 22/Dec/12 3:30 PM ]

Do you have a suggested fix for this?

Comment by Sebastian Bensusan [ 18/May/15 7:23 AM ]

I added one extra step in cljs.compiler/emit-comment to replace all occurrences of "*/" into "* /" and it worked for V8, Spidermonkey, and Nashorn.

Notes:

  • The patch includes a test.
  • I couldn't find a standard way to escape */ on JavaScript. If there are other suggestions, like *\/, I wouldn't mind resubmitting the patch.




[CLJS-485] clojure.string/replace ignores regex flags Created: 12/Mar/13  Updated: 01/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

Type: Defect Priority: Minor
Reporter: Esa Virtanen Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: bug, patch, test

Attachments: Text File 0001-Take-regex-flags-m-i-into-account-in-clojure.string-.patch    
Patch: Code and Test

 Description   

The replace function in namespace clojure.string ignores regex flag provided in the match pattern. For example:

CLJS
clojure.string/replace "I am NOT matched" #"(?i)not " "")
=> "I am NOT matched"
CLJ
clojure.string/replace "I am NOT matched" #"(?i)not " "")
=> "I am matched"

The attached patch fixes this by parsing the m and i flags, if set, from the match object, instead of explicitly setting only "g".



 Comments   
Comment by Chas Emerick [ 19/Mar/14 9:29 AM ]

I can confirm the bug. The attached patch applies cleanly, and works as expected.

Esa, sorry for the long delay (this one must have slipped through the cracks)! Could you please submit a contributor's agreement, so that your patch can be merged? More info is here:

http://clojure.org/contributing





[CLJS-794] RegExp flags are being dropped by `string/replace` Created: 09/Apr/14  Updated: 01/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

Type: Defect Priority: Minor
Reporter: Peter Taoussanis Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

`clojure.string/replace` accepts either a string or pattern argument to match against.

For pattern arguments, the current implementation discards the original RegExp and creates a new one:
`(.replace s (js/RegExp. (.-source match) "g") replacement)`

This is killing any flags on the original pattern (case insensitivity, for example). As a result, things like `(str/replace "Foo" #"(?i)foo" "bar")` currently fail. The result is "Foo", it should be "bar".

Can I submit a patch that'll check for and preserve other (i/m/y) flags?

Thanks



 Comments   
Comment by David Nolen [ 02/Dec/14 5:42 AM ]

A patch is welcome for this. Thanks.





[CLJS-1195] generic reusable command line argument parsing for REPLs Created: 10/Apr/15  Updated: 01/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

Type: Enhancement Priority: Minor
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: newbie


 Description   

REPLs are more or less started in the same way and all the builtin ones provide a -main entry point. We should supply reusable command line argument parsing that any REPL can use to get standard command line driven start.






[CLJS-1222] Sequence of a stateful transducer is producing the wrong answer Created: 24/Apr/15  Updated: 01/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3211
Fix Version/s: Next

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-1238] Setting *main-cli-fn* when using :target :nodejs shouldn't be manditory Created: 01/May/15  Updated: 01/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

Type: Enhancement Priority: Minor
Reporter: Jeremy Shoemaker Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: None

Attachments: Text File nodejs-main-cli-fn.patch    
Patch: Code

 Description   

Currently, when you use :target :nodejs in the build options for ClojureScript, the resulting code requires you to set *main-cli-fn* to a function.

This prevents someone from writing a library that can be used by JavaScript developers because it forces code execution on require. It also makes writing a CLI tool that can be distributed using NPM less straightforward. I ran into this issue trying to create a Leiningen template for writing CLI tools that could be installed using npm install or npm link. I had a wrapper script to take care of the CLI use-case, and intended to write the ClojureScript module in a more library oriented way, but ran into issues. I could work around this by not using the wrapper script, but it got me thinking about the more general library issue.

I don't see any reason why you should be forced to set *main-cli-fn* and so I'm suggesting making it optional.

Attached is a patch that makes it optional but retains the check for whether the value it is set to is a function in the case where it is set.

This is my first time submitting a change to a project using a git patch and not a pull request, so let me know if I've made the patch wrong.



 Comments   
Comment by Jeremy Shoemaker [ 01/May/15 7:27 PM ]

I just noticed the priority defaulted to "Major". I don't know if I'd say it's major, so feel free to bump it down if that doesn't seem appropriate.





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

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

Type: Defect Priority: Major
Reporter: Joel Holdbrooks Assignee: Unassigned
Resolution: Unresolved Votes: 1
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.





[CLJS-1134] Lift protocols from cljs.closure into cljs.protocols ns Created: 17/Mar/15  Updated: 01/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

Type: Task Priority: Major
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-1147] reconnect logic for browser REPLs Created: 18/Mar/15  Updated: 01/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

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-1194] data_readers.cljc Created: 10/Apr/15  Updated: 01/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

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


 Description   

Now that conditional reading has landed we can implement support for data_readers.cljc to get both compile time and runtime support.



 Comments   
Comment by David Nolen [ 10/Apr/15 7:45 PM ]

This needs http://dev.clojure.org/jira/browse/CLJ-1699 to be useful.

Comment by Nikita Prokopov [ 19/May/15 7:58 AM ]

CLJ-1699 has landed.

Right now CLJS tries to compile data_readers.cljc as a regular source code file:

Exception in thread "main" java.lang.AssertionError: No ns form found in src/data_readers.cljc, compiling:(/private/var/folders/0h/9vv4g3d955l6ctwwl4k9xjy40000gn/T/form-init3533791126017861878.clj:1:125)
	at clojure.lang.Compiler.load(Compiler.java:7249)
	at clojure.lang.Compiler.loadFile(Compiler.java:7175)
	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)
Comment by David Nolen [ 19/May/15 8:53 AM ]

This should be addressed first: http://dev.clojure.org/jira/browse/CLJS-1277





[CLJS-1207] Emit a warning if multiple resources found for a ClojureScript namespace Created: 15/Apr/15  Updated: 01/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

Type: Enhancement Priority: Major
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-1236] `constructor` needs to munged if used as namespace segment Created: 01/May/15  Updated: 01/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

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


 Description   

Will make goog.require believe that the namespace has already been loaded and throw an exception since all JS objects have the constructor property.



 Comments   
Comment by David Nolen [ 04/May/15 8:19 AM ]

This issue is not quite as simple as it sounds as we actually need a special case for namespace munging. For example we don't want to munge Foo.constructor but we do want to munge ns.foo.constructor. To implement the fix correctly it would require changing all the cases where library names are munged.





[CLJS-1296] browser REPL should queue prints before connection then flush after connection Created: 01/Jun/15  Updated: 01/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

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


 Description   

If the page loads and attempts to print before the connection is made the application will unintuitively error out.






[CLJS-375] loop doesn't seem to preserve tag information as evidenced by extra cljs.core.truth_ calls Created: 06/Sep/12  Updated: 01/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

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





[CLJS-744] ISequential types should implement JS indexOf, lastIndexOf Created: 05/Jan/14  Updated: 01/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

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





[CLJS-1070] top-level boolean inference does not work Created: 28/Feb/15  Updated: 01/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

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


 Description   

Problem for using boolean Closure defines



 Comments   
Comment by Francis Avila [ 30/Mar/15 12:02 PM ]

I am unsure if this is the same issue, but forms like ^boolean (js/isFinite n) also do not seem to analyze correctly: if, and, and or will still emit a call to truth_.





[CLJS-1271] Missing warning when assigning namespaces via def Created: 17/May/15  Updated: 01/Jun/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: Next

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-1295] Improve doc for instance Created: 01/Jun/15  Updated: 01/Jun/15

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

Type: Enhancement Priority: Trivial
Reporter: Julien Eluard Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None

Attachments: Text File CLJS-1295.patch    

 Description   

Doc for instance? does not reflect argument names.






[CLJS-1294] Macroexpand only accept quoted lists Created: 01/Jun/15  Updated: 01/Jun/15

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

Type: Enhancement Priority: Minor
Reporter: Julien Eluard Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None

Attachments: Text File CLJS-1294.patch    

 Description   

In Clojure macroexpand and macroexpand-1 accept any quoted argument while in ClojureScript anything but quoted seq will throw an exception.



 Comments   
Comment by Julien Eluard [ 01/Jun/15 2:16 PM ]

In Clojure some special forms are handled specifically i.e. (macroexpand '(Boolean true)) => (new Boolean true).

I am not sure if/how it applies to ClojureScript.





[CLJS-1200] compare behaves differently from Clojure Created: 13/Apr/15  Updated: 01/Jun/15  Resolved: 01/Jun/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: 0.0-3308

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


 Description   

compare behaves differently from Clojure. In ClojureScript we have a type check but rather than deferring to implementations to determine whether they are comparable. In Clojure exceptions from compare only arise from type coercion. These means that types belonging to the same logical category (say two implementations of UUID, or different implementations of ISequential) cannot be compared.



 Comments   
Comment by David Nolen [ 01/Jun/15 8:18 AM ]

This means dropping the same type restriction and verifying that implementations don't assume the type of their other argument and that they throw when comparison cannot proceed.

Comment by David Nolen [ 01/Jun/15 1:04 PM ]

fixed https://github.com/clojure/clojurescript/commit/b803b3d7b922bcd68fec598be910350a4a13eb11





[CLJS-1293] Warning settings not conveyed via REPL Created: 31/May/15  Updated: 01/Jun/15  Resolved: 01/Jun/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: 0.0-3308

Type: Defect Priority: Major
Reporter: Mike Fikes Assignee: David Nolen
Resolution: Completed Votes: 0
Labels: None
Environment:

QuickStart node


Attachments: Text File CLJS-1293.patch    

 Description   

Create a node_repl.clj file with contents:

(require 'cljs.repl)
(require 'cljs.repl.node)

(cljs.repl/repl (cljs.repl.node/repl-env)
  :output-dir "out"
  :warnings {:fn-arity false})

Note the :warnings setting above.

With cljs.jar in the same directory, start up Node REPL with rlwrap java -cp cljs.jar:src clojure.main node_repl.clj. Then observe that the warnings map doesn't appear to have any effect:

ClojureScript Node.js REPL server listening on 50469
To quit, type: :cljs/quit
cljs.user=> (defn x [])
#<function cljs$user$x(){
return null;
}>
cljs.user=> (x 3)
WARNING: Wrong number of args (1) passed to cljs.user/x at line 1 <cljs repl>
nil
cljs.user=>

(I suspect that this is a defect in that ana/cljs-warnings binding is not modified to merge in :warnings.)



 Comments   
Comment by David Nolen [ 01/Jun/15 12:28 PM ]

fixed https://github.com/clojure/clojurescript/commit/dfad0d2c08f83c176602b89ad7e79e251c5f3d05





[CLJS-1292] Add IPrintWithWriter implementation for TaggedLiteral Created: 28/May/15  Updated: 29/May/15  Resolved: 29/May/15

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

Type: Enhancement Priority: Major
Reporter: Nicola Mometto Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: None

Attachments: Text File 0001-CLJS-1292-Add-IPrintWithWriter-implementation-for-Ta.patch    

 Comments   
Comment by David Nolen [ 29/May/15 12:07 PM ]

fixed https://github.com/clojure/clojurescript/commit/8537ef4d7682ce29066c48e49062bd57c8d4ee92





[CLJS-1291] pprint whitespace/letter checks are incomplete Created: 28/May/15  Updated: 28/May/15  Resolved: 28/May/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Jonathan Boston Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: None

Attachments: Text File CLJS-1291.patch    

 Description   

pprint uses a simple is-whitespace? and is-letter? check that doesn't cover all cases (e.g. unicode chars). Using Google Closure fns are a better choice.



 Comments   
Comment by Jonathan Boston [ 28/May/15 9:36 AM ]

Patch added.

Comment by David Nolen [ 28/May/15 10:17 AM ]

fixed https://github.com/clojure/clojurescript/commit/25e4945cb5c7f0ed4322a377d0e12a62ffea3087





[CLJS-1288] compiler doesn't emit "goog.require" for foreign library when optimization level is not set Created: 25/May/15  Updated: 28/May/15  Resolved: 28/May/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Maria Neise Assignee: Maria Neise
Resolution: Completed Votes: 0
Labels: bug, foreign-libs

Attachments: Text File CLJS-1288-2.patch     Text File CLJS-1288.patch    
Patch: Code

 Description   

When the optimization level is not set explicitly, meaning that :none will be used as a default, the compiler doesn't emit a goog.require for foreign libraries. An example project reproducing the problem can be found here: https://github.com/MNeise/hello_world.

From my understanding of the code, the compiler environment gets created with the initial options and doesn't get updated with the default optimization level when the options don't include an optimization level. The following check in the load-libs function in the compiler.cljc file then fails, because optimizations is nil.

compiler.cljc
(cond
        (ana/foreign-dep? lib)
        (let [{:keys [target optimizations]} (get @env/*compiler* :options)]
          ;; we only load foreign libraries under optimizations :none
          (when (= :none optimizations)
            (if (= :nodejs target)
              ;; under node.js we load foreign libs globally
              (let [{:keys [js-dependency-index options]} @env/*compiler*
                    ijs-url (get-in js-dependency-index [(name lib) :url])]
                (emitln "cljs.core.load_file(\""
                  (str (io/file (util/output-directory options) (util/get-name ijs-url)))
                  "\");"))
              (emitln "goog.require('" (munge lib) "');"))))


 Comments   
Comment by Maria Neise [ 25/May/15 11:23 PM ]

I've attached a possible patch for this.

Comment by David Nolen [ 26/May/15 5:16 PM ]

The patch looks OK but I think we should just merge all-opts with :options in the compiler-env otherwise later there will be some other case missed

Comment by Maria Neise [ 26/May/15 6:43 PM ]

That makes sense I've update the patch (CLJS-1288.patch).

I was also wondering, if it would make sense to pull emit-constants into add-implicit-options, maybe similar to CLJS-1288-2.patch?

Comment by David Nolen [ 28/May/15 10:09 AM ]

fixed https://github.com/clojure/clojurescript/commit/f75da4ec93add6030ab57d4e2b3e1ad4a1cf9d4d





[CLJS-1289] Revert clj->cljc file conversion Created: 26/May/15  Updated: 26/May/15  Resolved: 26/May/15

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

Type: Defect Priority: Critical
Reporter: Thomas Heller Assignee: Unassigned
Resolution: Declined Votes: 0
Labels: None


 Description   

Commit [1] changed some .clj files over to .cljc files but no other changes were made to actually make these "common" files. Most of the files are not actually compatible (and probably never will be, eg. assuming sync streaming IO) and some even cause conflicts src/clj/cljs/repl.cljc vs. src/main/cljs/cljs/repl.cljs both trying to provide cljs.repl namespaces.

Any objections to changing these back as they provide no gain as of now?

I know other build tools are not a concern but these "faulty" files cause "issues" in shadow-build.

[1] https://github.com/clojure/clojurescript/commit/11113cea2f599d685b60f8fbdcb56d944240ea25



 Comments   
Comment by David Nolen [ 26/May/15 1:13 PM ]

The change was intentionally made now that Clojure has reader conditionals. The intent is for portions of these ClojureScript files to be made so that we can compile to Node.js gradually over time.





[CLJS-1283] (long \7) produces different result on Clojure/ClojureScript Created: 22/May/15  Updated: 25/May/15

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

Type: Defect Priority: Minor
Reporter: Sean Corfield Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

In Clojure (long \7) produces 55 which is the ASCII code value for the character 7.

In ClojureScript, it seems this just converts the single character string "7" to a number and you get 7 as the answer. This might make writing portable string manipulation code rather hazardous?

(reported by irctc_ on IRC)



 Comments   
Comment by David Nolen [ 22/May/15 11:23 PM ]

Coercions like long only exist to simplify porting code. In general such things should be replaced.

Comment by Sean Corfield [ 25/May/15 4:24 PM ]

What would be your recommended, portable, way to turn characters into ASCII then? (that would work in both CLJS and CLJ)

Comment by David Nolen [ 25/May/15 10:27 PM ]

I don't have any recommendation. It seems intractable to me.





[CLJS-1284] IndexedSeq -seq implementation incorrect for i >= alength internal array Created: 23/May/15  Updated: 23/May/15  Resolved: 23/May/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: 0.0-3308

Type: Defect Priority: Major
Reporter: Daniel Skarda Assignee: David Nolen
Resolution: Completed Votes: 0
Labels: None
Environment:

ClojureScript 0.0-3291



 Description   
(defn foo-ok
  ([x0 & xs] [x0 xs]))

(defn foo-fail
  ([] nil)
  ([x0 & xs] [x0 xs]))


(foo-ok 0) => [0 nil]     ;; OK
(foo-ok 0 1) => [0 (1)]   ;; OK

(foo-fail) => nil         ;; OK
(foo-fail 0) => [0 (nil)] ;; INCORRECT
(foo-fail 0 1) => [0 (1)] ;; OK


 Comments   
Comment by David Nolen [ 23/May/15 1:53 PM ]

This is a bug with IndexedSeq, not fn arities.

Comment by David Nolen [ 23/May/15 2:10 PM ]

fixed https://github.com/clojure/clojurescript/commit/f165420d2b25008924d6655ca4e79bf9901c2125

Comment by David Nolen [ 23/May/15 2:15 PM ]

I cut a 0.0-3297 interim release with this fix.

Comment by Daniel Skarda [ 23/May/15 5:33 PM ]

David, thank you for very fast analysis, fix and release!





[CLJS-1285] load-file regression Created: 23/May/15  Updated: 23/May/15  Resolved: 23/May/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: 0.0-3308

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


 Description   

We need to make load-file more robust. Currently we don't properly check goog.dependencies.written_ for the sourcePath, we always delete the basePath + source path.



 Comments   
Comment by David Nolen [ 23/May/15 5:12 PM ]

fixed https://github.com/clojure/clojurescript/commit/22ba5a6d0b780183d21bd69a64492e2216a7b379





[CLJS-1176] Push node.js REPL output through *out* and *err* Created: 27/Mar/15  Updated: 23/May/15  Resolved: 28/Mar/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3126
Fix Version/s: 0.0-3196

Type: Enhancement Priority: Major
Reporter: Chas Emerick Assignee: David Nolen
Resolution: Completed Votes: 0
Labels: None

Attachments: File CLJS-1176.diff    
Patch: Code

 Description   

The node.js REPL environment currently lets the child node process inherit the JVM's stdout/err. This is bad for nREPL, and for any other setup where one would like to rebind *out* and/or *err* in order to redirect content print ed by ClojureScript code. Turning off the inheritance and pumping output from the process to *out* and *err* should be straightforward.

Related nREPL/piggieback issue: https://github.com/cemerick/piggieback/issues/41



 Comments   
Comment by Chas Emerick [ 28/Mar/15 5:10 AM ]

Patch attached. Node REPL now sends output to *out* and *err*.

Comment by David Nolen [ 28/Mar/15 12:07 PM ]

fixed https://github.com/clojure/clojurescript/commit/a7f2a85d9df15e912dff71a8c95529bcfe459882

Comment by Joel Wilsson [ 08/Apr/15 7:10 AM ]

This doesn't work for me, because java.lang.Process does not have an isAlive() method. Maybe you were thinking of java.lang.Thread isAlive()?

user=> (require '[cljs.repl :as repl])
nil
user=> (require '[cljs.repl.node :as node])
nil
user=> (def env (node/repl-env))
#'user/env
user=> (repl/repl env)
Exception in thread "Thread-8" Exception in thread "Thread-9" java.lang.IllegalArgumentException: No matching field found: isAlive for class java.lang.UNIXProcess
	at clojure.lang.Reflector.getInstanceField(Reflector.java:271)
	at clojure.lang.Reflector.invokeNoArgInstanceMember(Reflector.java:315)
	at cljs.repl.node$pipe.invoke(node.clj:85)
	at cljs.repl.node$setup$fn__10733.invoke(node.clj:109)
...
Comment by Chas Emerick [ 08/Apr/15 7:37 AM ]

Damn, no, looks like I was using the JDK 8 javadoc when I wrote the patch: http://docs.oracle.com/javase/8/docs/api/java/lang/Process.html#isAlive--

Looks like this would be an equivalent expression:

(try (.exitValue proc) false (catch IllegalThreadStateException _ true))

We'll see if David prefers a patch for this, or to paste it in himself…

Comment by Chas Emerick [ 08/Apr/15 8:03 AM ]

Patch attached to CLJS-1192. Sorry for the snafu! :-/

Comment by Daniel Skarda [ 23/May/15 1:03 PM ]

In 0.0-3291 there is still one call to isAlive left on src/main/clojure/cljs/repl/node.clj:92

Comment by David Nolen [ 23/May/15 1:32 PM ]

fixed https://github.com/clojure/clojurescript/commit/46af7373d88f77972eb0f030ca43724d43c6b648





[CLJS-1278] Asserts still fail while :require-ing .js file (either in :libs or in :source-paths) (same as CLJS-1196) Created: 20/May/15  Updated: 22/May/15

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

Type: Defect Priority: Minor
Reporter: Michal Till Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None

Attachments: Text File cljs_1278.patch    

 Description   

Following on CLJS-1196, I can't get it to work.

In version 0.0-3264 lein-cljsbuild crashed on weird eception `Caused by: java.lang.IllegalArgumentException: No implementation of method: :make-reader of protocol: #'clojure.java.io/IOFactory found for class: nil"` but the current version 0.0-3269 gives the same failed assertion as previously.

I've put up a sample project to illustrate the issue.

Steps to reproduce:

`git clone https://github.com/tillda/stackone`
`cd stackone`
`git checkout 537e5c69b844bc53c159e85cafc24310543cc918`
`lein clean && lein cljsbuild once temp`

Expected behaviour: cljs compiled successfully with src/vendor/client/closure.js and env/stackone/helpersjs.js being included.

Actual behaviour:

```
Compiling "resources/public/lein-cljsbuild-temp/dev-mode-deps.js" failed.
Exception in thread "main" java.lang.AssertionError: Assert failed: (or (file? x) (url? x) (string? x)), compiling/private/var/folders/ym/l2qxd7l97kzfzftrdpqsclm40000gn/T/form-init3642888309490821030.clj:1:125)
at clojure.lang.Compiler.load(Compiler.java:7249)
at clojure.lang.Compiler.loadFile(Compiler.java:7175)
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)
Caused by: java.lang.AssertionError: Assert failed: (or (file? x) (url? x) (string? x))
at cljs.util$ext.invoke(util.cljc:115)
at cljs.closure$source_on_disk.invoke(closure.clj:1206)
at cljs.closure$output_unoptimized$fn__3708.invoke(closure.clj:1235)
at clojure.core$map$fn__4551.invoke(core.clj:2622)
at clojure.lang.LazySeq.sval(LazySeq.java:40)
at clojure.lang.LazySeq.seq(LazySeq.java:49)
at clojure.lang.RT.seq(RT.java:507)
at clojure.core$seq__4126.invoke(core.clj:135)
at clojure.core$filter$fn__4578.invoke(core.clj:2677)
at clojure.lang.LazySeq.sval(LazySeq.java:40)
at clojure.lang.LazySeq.seq(LazySeq.java:49)
at clojure.lang.RT.seq(RT.java:507)
at clojure.core$seq__4126.invoke(core.clj:135)
at clojure.core$map$fn__4551.invoke(core.clj:2614)
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.next(RT.java:674)
at clojure.core$next__4110.invoke(core.clj:64)
at clojure.core$str$fn__4186.invoke(core.clj:528)
at clojure.core$str.doInvoke(core.clj:526)
at clojure.lang.RestFn.applyTo(RestFn.java:139)
at clojure.core$apply.invoke(core.clj:628)
at cljs.closure$deps_file.invoke(closure.clj:1040)
at cljs.closure$output_deps_file.invoke(closure.clj:1060)
at cljs.closure$output_unoptimized.doInvoke(closure.clj:1243)
at clojure.lang.RestFn.applyTo(RestFn.java:139)
at clojure.core$apply.invoke(core.clj:630)
at cljs.closure$build.invoke(closure.clj:1514)
at cljs.closure$build.invoke(closure.clj:1426)
at cljsbuild.compiler$compile_cljs$fn__3884.invoke(compiler.clj:81)
at cljsbuild.compiler$compile_cljs.invoke(compiler.clj:80)
at cljsbuild.compiler$run_compiler.invoke(compiler.clj:187)
at user$eval4018$iter_40544058$fn4059$fn_4077.invoke(form-init3642888309490821030.clj:1)
at user$eval4018$iter_40544058$fn_4059.invoke(form-init3642888309490821030.clj:1)
at clojure.lang.LazySeq.sval(LazySeq.java:40)
at clojure.lang.LazySeq.seq(LazySeq.java:49)
at clojure.lang.RT.seq(RT.java:507)
at clojure.core$seq__4126.invoke(core.clj:135)
at clojure.core$dorun.invoke(core.clj:3007)
at clojure.core$doall.invoke(core.clj:3023)
at user$eval4018.invoke(form-init3642888309490821030.clj:1)
at clojure.lang.Compiler.eval(Compiler.java:6792)
at clojure.lang.Compiler.eval(Compiler.java:6782)
at clojure.lang.Compiler.load(Compiler.java:7237)
... 11 more
Subprocess failed
```



 Comments   
Comment by David Nolen [ 20/May/15 10:21 AM ]

This issue is in danger of being closed. Please supply minimal steps to reproduce that do not involve anything other than the ClojureScript compiler. We no longer have time to wade through the indirection introduced by cljsbuild or any other downstream tooling. Thanks.

Comment by Michal Till [ 20/May/15 11:14 AM ]

@David Nolen: I have created a failing minimal testcase based on the Quick Start document. Here it is: https://github.com/tillda/cljs-testcase/

Comment by David Nolen [ 20/May/15 11:27 AM ]

Michal the failing example is not correct. You are not supplying any :libs option.

Comment by Michal Till [ 20/May/15 11:45 AM ]

Ah! Thank you very much! This additional issue was therefore my error. Now it seems to work even in my "big" example.

However it would be cool if there was a meaningful error message stating that a file path can't be resolved. If one is not an expert in the cljs compiler this is almost impossible to figure out. After all the error message in the CLJS-1196 issue and in this wrongfully reported one are exactly the same.

You may close this issue.

Comment by David Nolen [ 20/May/15 11:55 AM ]

We'll leave it open for the improving the error message.

Comment by Sebastian Bensusan [ 22/May/15 7:16 AM ]

Added the check in cljs.closure/source-on-disk where there is info for the error message.

For the supplied case, the error message is:

java.lang.IllegalArgumentException: The file file:/home/carlos/Playground/cljs-testcase/src/hello_world/closure.js 
lacks an associated source file. If it is a JavaScript library please add it to :libs}}

If a different wording or location of the check is needed, I'll submit a new patch with corrections.

Notes:

  • Changed:(:provides js) to (-provides js) in order to be consistent with IJavaScript.
  • cljs.clojure/source-on-disk takes a js argument that should satisfy with IJavaScript and ISourceMap if :source-map is enabled but the implementation is hardcoded to maps because :source-map and :source-url are used instead of ISourceMap methods -source-map and -source-url. I propose to extend PersistentMap and PersistentArrayMap to ISourceMap to make source-on-disk compliant with both protocols.




[CLJS-1206] Images in HTML don't show up when served from localhost:9000 Created: 15/Apr/15  Updated: 20/May/15  Resolved: 20/May/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3196
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: J David Eisenberg Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: brepl, bug
Environment:

Fedora core 21, java version "1.8.0_40" Java(TM) SE Runtime Environment (build 1.8.0_40-b26) Java HotSpot(TM) 64-Bit Server VM (build 25.40-b25, mixed mode)


Attachments: Text File cljs_1206.patch     Text File cljs_1206_v2.patch     File imgtest_files.tgz    
Patch: Code

 Description   

In a project built from latest version of mies (from github), put an img element in the index.html page. When running scripts/brepl and loading http://localhost:9000, the image does not appear and the console gives a 404 error (see screenshot in attached tarball). The image shows up fine when loading the index.html as a plain file:/// in the browser, so the image definitely does exist in the correct directory.

I think the problem is in file src/clj/cljs/repl/browser.clj, the code starting server/dispatch-on; it lacks options for paths ending in .jpg and .png

I've included a diff -u file in the tarball as well with a possible patch. The patch also adds .svg as a valid type of file to serve, which was the particular thing I needed when I first saw this problem.



 Comments   
Comment by David Nolen [ 15/Apr/15 8:47 AM ]

Please attach patches directly, thanks!

Comment by J David Eisenberg [ 15/Apr/15 10:12 AM ]

Not sure what the format for a patch is, nor where it should be attached. (Add another attachment with the diff file?) Also, I think I see why the image doesn't appear -somewhere in the input or output process, the binary data is being converted to UTF-8.

Comment by Francis Avila [ 15/Apr/15 10:47 AM ]

Patch instructions. Add patch file as independent attachment to this ticket.

Before your code can be accepted you must sign a contributor's agreement.

Comment by J David Eisenberg [ 15/Apr/15 7:04 PM ]

Patch that allows server to correctly serve PNG, JPG, and SVG files. Patch uses maps to store data about MIME types and encoding, so other file extensions and types can be added easily if necessary.

Comment by Sander Dijkhuis [ 05/May/15 1:50 AM ]

Related / same issue:
http://dev.clojure.org/jira/browse/CLJS-1124

Comment by David Nolen [ 14/May/15 9:35 PM ]

fixed https://github.com/clojure/clojurescript/commit/ed5a2c928c1bcde624dbe671140e9516de54dd24

Comment by kovas boguta [ 20/May/15 2:50 PM ]

New patch.

Comment by David Nolen [ 20/May/15 3:01 PM ]

fixed https://github.com/clojure/clojurescript/commit/fee5527284c9803f2865c1c428bbd5055b52af97

Comment by J David Eisenberg [ 20/May/15 3:47 PM ]

Why no love for SVG? It's part of HTML5, and is used to a fair extent in the "real world."

Comment by David Nolen [ 20/May/15 4:24 PM ]

We just have to draw the line somewhere. browser REPL is not a replacement for a real web server.





[CLJS-1279] Node.js REPL does not flush process out and err immediately Created: 20/May/15  Updated: 20/May/15  Resolved: 20/May/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: 0.0-3308

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


 Comments   
Comment by David Nolen [ 20/May/15 2:49 PM ]

fixed https://github.com/clojure/clojurescript/commit/03529c47f9c38f3923a827166699f511f5ec0356





[CLJS-1262] Write to compiler out before :merge-opts Created: 10/May/15  Updated: 19/May/15  Resolved: 19/May/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3255
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: None


 Description   

cljs.repl/repl* supports a :merge-opts, allowing derived REPLs, for example to specify :output-dir as a result of -setup.

A recent change in with_core_cljs appears to cause output to be (prematurely) written to the default :output-dir of "out": The call to -setup is wrapped with this macro.

This did not appear to occur with previous releases (I checked the last release of ClojureScript that was still on Clojure 1.6.0, but I haven't bisected to pinpoint the change.)

I haven't yet produced a minimal reproduction. (I will try to do so with QuickStart and add a comment).

I produced this with Ambly by manually creating an empty "out", and chmod a-w on it so that it can't be written in, and then when starting Ambly, I get a trace provoking the problem, showing where the write occurs:

$ script/repl
Exception in thread "main" java.io.FileNotFoundException: out/cljs/core.cljs.cache.edn (No such file or directory), compiling:(/private/var/folders/pd/w1724j050nd445hpm7mwlxs80000gn/T/form-init5299557692903408511.clj:1:125)
	at clojure.lang.Compiler.load(Compiler.java:7249)
	at clojure.lang.Compiler.loadFile(Compiler.java:7175)
	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)
Caused by: java.io.FileNotFoundException: out/cljs/core.cljs.cache.edn (No such file or directory)
	at java.io.FileOutputStream.open0(Native Method)
	at java.io.FileOutputStream.open(FileOutputStream.java:270)
	at java.io.FileOutputStream.<init>(FileOutputStream.java:213)
	at clojure.java.io$fn__9185.invoke(io.clj:230)
	at clojure.java.io$fn__9122$G__9091__9129.invoke(io.clj:69)
	at clojure.java.io$fn__9159.invoke(io.clj:166)
	at clojure.java.io$fn__9135$G__9087__9142.invoke(io.clj:69)
	at clojure.java.io$writer.doInvoke(io.clj:119)
	at clojure.lang.RestFn.invoke(RestFn.java:410)
	at clojure.lang.AFn.applyToHelper(AFn.java:154)
	at clojure.lang.RestFn.applyTo(RestFn.java:132)
	at clojure.core$apply.invoke(core.clj:630)
	at clojure.core$spit.doInvoke(core.clj:6662)
	at clojure.lang.RestFn.invoke(RestFn.java:425)
	at cljs.analyzer$write_analysis_cache.invoke(analyzer.cljc:2186)
	at cljs.analyzer$analyze_file.invoke(analyzer.cljc:2237)
	at cljs.compiler$with_core_cljs.invoke(compiler.cljc:967)
	at cljs.repl$repl_STAR_.invoke(repl.cljc:779)
	at cljs.repl$repl.doInvoke(repl.cljc:929)
	at clojure.lang.RestFn.invoke(RestFn.java:410)
	at user$eval4493.invoke(form-init5299557692903408511.clj:3)
	at clojure.lang.Compiler.eval(Compiler.java:6792)
	at clojure.lang.Compiler.eval(Compiler.java:6755)
	at clojure.core$eval.invoke(core.clj:3079)
	at clojure.main$eval_opt.invoke(main.clj:289)
	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)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)
	at clojure.lang.Reflector.invokeMatchingMethod(Reflector.java:93)
	at clojure.lang.Reflector.invokeStaticMethod(Reflector.java:207)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)
	at clojure.lang.Reflector.invokeMatchingMethod(Reflector.java:93)
	at clojure.lang.Reflector.invokeStaticMethod(Reflector.java:207)
	at user$eval5.invoke(form-init5299557692903408511.clj:1)
	at clojure.lang.Compiler.eval(Compiler.java:6792)
	at clojure.lang.Compiler.eval(Compiler.java:6782)
	at clojure.lang.Compiler.load(Compiler.java:7237)
	... 11 more


 Comments   
Comment by Mike Fikes [ 10/May/15 9:54 AM ]

Reproduction with lein:

project.clj:

(defproject foo "0.1.0"
  :dependencies [[org.clojure/clojure "1.7.0-beta2"]
                 [org.clojure/clojurescript "0.0-3255"]])

Make out not writable. (chmod a-w out). Or, alternatively, just look for the presence of out on filesystem alongside abc.

In any case, if you don't make out not writable, then this minimal repo will subsequently fail with an unrelated java.lang.IllegalArgumentException: No matching clause: as it is simply trying to exhibit the problem with out.

lein repl

Then execute these forms:

(require 'cljs.repl)

(defrecord FooEnv []
    cljs.repl/IJavaScriptEnv
  (-setup [repl-env opts]
    {:merge-opts {:output-dir "abc"}})
  (-evaluate [_ _ _ _])
  (-load [_ _ _])
  (-tear-down [_]))

(defn repl-env 
  [& {:as options}]
  (FooEnv.))

(cljs.repl/repl (repl-env))

With this older version, the out directory is not created:

(defproject foo "0.1.0"
  :dependencies [[org.clojure/clojure "1.7.0-beta1"]
                 [org.clojure/clojurescript "0.0-3196"]])
Comment by David Nolen [ 10/May/15 10:17 AM ]

Right the problem is that with-core-cljs calls analyze-file which will attempt to write the analysis cache. It's just a matter of considering the best way to avoid this.

Comment by Mike Fikes [ 18/May/15 9:27 PM ]

No longer occurs with 0.0-3269 and was fixed with this commit: https://github.com/clojure/clojurescript/commit/07bb585b181c02b3c33c7d88c46ddb888279b07f





[CLJS-1229] Simplify Closure CommonJS & ES 2015 Module support Created: 30/Apr/15  Updated: 18/May/15  Resolved: 18/May/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: GSoC

Type: Task Priority: Major
Reporter: David Nolen Assignee: Maria Neise
Resolution: Completed Votes: 1
Labels: None


 Description   

Google Closure Compiler's ProcessCommonJSModules constructors are currently private. ES6ModuleLoader is a package private class with private constructors. All of these things must be made public if we are going to use them as individual passes on files. The current state of this functionality in Closure Compiler assumes being driven from the command line to produce a final build. In our case we want to use them as part of incremental compilation.



 Comments   
Comment by Maria Neise [ 18/May/15 2:44 PM ]

This has been fixed with https://github.com/google/closure-compiler/pull/952. In addition to making ProcessCommonJSModules and ES6ModuleLoader public, we also made ProcessEs6Modules public.





[CLJS-1275] lein test configuration is broken Created: 18/May/15  Updated: 18/May/15  Resolved: 18/May/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Sebastian Bensusan Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: None

Attachments: Text File cljs_1275.patch    

 Description   

When running lein test on a fresh copy of master it fails to find the tests. The :test-paths in project.clj is pointing to an old location.



 Comments   
Comment by Sebastian Bensusan [ 18/May/15 7:35 AM ]

This patch redirects :test-paths to the current directory of the tests: src/test/clojure.

Comment by David Nolen [ 18/May/15 8:39 AM ]

fixed https://github.com/clojure/clojurescript/commit/08398b25400b363ca22db885b7ed2460c92bd5fa





[CLJS-1273] clojure.lang.Symbol cannot be cast to clojure.lang.Namespace on macro expansion Created: 17/May/15  Updated: 17/May/15  Resolved: 17/May/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3211
Fix Version/s: None

Type: Defect Priority: Major
Reporter: lvh Assignee: Unassigned
Resolution: Not Reproducible Votes: 0
Labels: None


 Description   

Following macro & macro call:

{{
(defmacro defroutes
[routes]
(let [route-defs (for [{:keys [path view]} routes]
`(secretary/defroute ~path []
(session/put! :current-page ~view)))]
`(do (def ~'routes ~routes) ~@route-defs)))

(defroutes
[{:name "Home"
:path "/"
:view #'home-page}
{:name "Foo bar"
:path "/foo-bar"
:view #'foo-bar-page}
{:name "Baz quux"
:path "/baz-quux"
:view #'baz-quux-page}])
}}

... results in following compile-time exception:

{{
clojure.lang.ExceptionInfo : failed compiling file:src/cljs/shrieker/core.cljs
clojure.lang.ExceptionInfo : clojure.lang.Symbol cannot be cast to clojure.lang.Namespace
java.lang.ClassCastException : clojure.lang.Symbol cannot be cast to clojure.lang.Namespace
Error on file /Users/lvh/Projects/rackspace/shrieker/src/cljs/shrieker/core.cljs, line 106, column 60
}}

I believe this to be a bug, because replacing that macro call with its expansion works fine:

{{
(do
(def routes
[{:name "Home"
:path "/"
:view #'home-page}
{:name "Foo bar"
:path "/foo-bar"
:view #'foo-bar-page}
{:name "baz quux"
:path "/baz-quux"
:view #'baz-quux-page}])
(secretary/defroute "/" []
(session/put! :current-page #'home-page))
(secretary/defroute "/foo-bar" []
(session/put! :current-page #'foo-bar-page))
(secretary/defroute "/endpoint-quux" []
(session/put! :current-page #'baz-quux-page)))
}}

I was unable to repeat the experiment on more recent Clojurescripts, as some of my dependencies don't quite agree with it.



 Comments   
Comment by lvh [ 17/May/15 7:14 PM ]

JIRA doesn't appear to like my markup. Sorry about that

Comment by David Nolen [ 17/May/15 10:59 PM ]

You need to verify that this affects a released version of ClojureScript in a reproducible way (minimal case). Thanks.





[CLJS-1274] Allow assignment to namespace-qualified names in current namespace Created: 17/May/15  Updated: 17/May/15

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

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


 Description   

In Clojure, you can def to a namespace-qualified name as long as it's in the current namespace. You can't do that in Clojurescript. This makes writing some macros that def to a local name a bit more annoying, since the syntax-quote will automatically namespace-qualify any symbols, so you have to write the somewhat unsightly and not super obvious ~'sym.






[CLJS-1272] :include-macros description inaccurate in require Created: 17/May/15  Updated: 17/May/15  Resolved: 17/May/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: docstring

Attachments: Text File CLJS-1272.patch    

 Description   

The description for :include-macros in the docstring for require indicates

:include-macros takes a list of macro symbols to refer from the namespace.

when really the spec only takes true as an argument, where the semantics are "causes macros to be required"



 Comments   
Comment by David Nolen [ 17/May/15 6:46 PM ]

fixed https://github.com/clojure/clojurescript/commit/721ba892892d7aa000460c45a6eb1afecd33eff5





[CLJS-1267] New :end-run-tests event not present in all public cljs.test functions Created: 13/May/15  Updated: 17/May/15

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

Type: Defect Priority: Minor
Reporter: Sebastian Bensusan Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None

Attachments: Text File cljs_1267.patch    

 Description   

After CLJS-1226, cljs.test API is inconsistent since only one of its public functions (run-tests) emits the new :end-run-tests event. The event should be added to test-all-vars, test-ns, test-var, and test-vars, making sure it is only fired once.



 Comments   
Comment by Leon Grapenthin [ 13/May/15 3:13 AM ]

To my knowledge all four are not reused within cljs.test, only the -block versions are, so there should be no worries about the event fired twice.

Comment by Sebastian Bensusan [ 17/May/15 12:37 PM ]

The patch includes the :end-run-tests event to test-ns, test-all-vars, test-vars, and test-var. I didn't add the event to the block functions since those can be reused and composed.

Notes:

  • If any of those functions are used sequentially in a script the event will be fired multiple times.
  • On each function the map passed to cljs.test/report contains different information besides {:type :end-run-tests}. test-var passes :var, test-vars passes :vars, test-ns and test-all-vars pass :ns.




[CLJS-1270] Docstring for delay not printed by cljs.repl/doc Created: 16/May/15  Updated: 17/May/15  Resolved: 17/May/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: None

Attachments: Text File CLJS-1270.patch    

 Description   
cljs.user=> (doc delay)
-------------------------
cljs.core/delay
([& body])
Macro
  nil

nil
cljs.user=> (source delay)
(defmacro delay [& body]
  "Takes a body of expressions and yields a Delay object that will
  invoke the body only the first time it is forced (with force or deref/@), and
  will cache the result and return it on all subsequent force
  calls."
  `(new cljs.core/Delay (fn [] ~@body) nil))
nil


 Comments   
Comment by Mike Fikes [ 16/May/15 8:12 PM ]

Attached CLJS-1270.patch

Comment by David Nolen [ 17/May/15 10:28 AM ]

fixed https://github.com/clojure/clojurescript/commit/264eb2b5153d6d1c3b6fcf0a42aad31956297cc5





[CLJS-1269] realized? docstring refers to promise and future Created: 16/May/15  Updated: 17/May/15  Resolved: 17/May/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: None

Type: Defect Priority: Trivial
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: docstring

Attachments: Text File CLJS-1269.patch    

 Description   

The docstring for realized? refers to nonexistent promise and future.

Likely copied over verbatim from Clojure:

cljs.user=> (doc realized?)
-------------------------
cljs.core/realized?
([d])
  Returns true if a value has been produced for a promise, delay, future or lazy sequence.

nil


 Comments   
Comment by Mike Fikes [ 16/May/15 7:57 PM ]

Added CLJS-1269.patch

Comment by David Nolen [ 17/May/15 10:27 AM ]

fixed https://github.com/clojure/clojurescript/commit/27ad78bb3f7fdfe64b4041bf60532489c2847105





[CLJS-1268] cljc support for cljs.closure/compile-file Created: 13/May/15  Updated: 14/May/15  Resolved: 14/May/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: 0.0-3308

Type: Defect Priority: Major
Reporter: Robert Krahn Assignee: David Nolen
Resolution: Completed Votes: 0
Labels: None


 Description   

When calling cljs.closure/compile-file on a cljc file I get

ExceptionInfo Conditional read not allowed {:type :reader-exception, :line 5, :column 5, :file nil}
clojure.core/ex-info (core.clj:4591)
clojure.tools.reader/read* (reader.clj:896)
clojure.tools.reader/read-delimited (reader.clj:189)
clojure.tools.reader/read-list (reader.clj:202)
clojure.tools.reader/read* (reader.clj:878)
clojure.tools.reader/read (reader.clj:927)
cljs.analyzer/forms-seq*/forms-seq--124424/fn124425/fn-124426 (analyzer.cljc:24)
cljs.analyzer/forms-seq*/forms-seq--124424/fn-124425 (analyzer.cljc:18)
clojure.lang.LazySeq.sval (LazySeq.java:40)
clojure.lang.LazySeq.seq (LazySeq.java:49)
clojure.lang.Cons.next (Cons.java:39)
clojure.lang.RT.next (RT.java:674)
clojure.core/next--4109 (core.clj:64)
cljs.closure/compile-form-seq/fn-7854/fn-7855 (closure.clj:341)
cljs.closure/compile-form-seq/fn--7854 (closure.clj:340)
cljs.compiler/with-core-cljs (compiler.cljc:968)
cljs.closure/compile-form-seq (closure.clj:337)
cljs.closure/compile-file (closure.clj:376)

The issue is that forms-seq* is already called with a reader and the cljc check in there is not getting a file. Checking for ana/cljs-file is probably a solution.



 Comments   
Comment by David Nolen [ 14/May/15 9:36 PM ]

fixed https://github.com/clojure/clojurescript/commit/98ed0f4a08dfe757b7c647dbce22e235ef45b0a3





[CLJS-1124] Have cljs.repl.browser/repl-env serve more static file types Created: 16/Mar/15  Updated: 14/May/15  Resolved: 14/May/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: 0.0-3308

Type: Enhancement Priority: Minor
Reporter: Sander Dijkhuis Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: newbie
Environment:

cljs 0.0-3115


Attachments: Text File CLJS-1124-attempt001.patch     GZip Archive CLJS-1124-test.tar.gz     GZip Archive CLJS-1124-test.tar.gz    

 Description   

I'm developing a webpage using CLJS that can be served statically. To iterate quickly on the script, I'm hosting the page using

(cljs.repl/repl
(cljs.repl.browser/repl-env :static-dir ["." "out/" "img/" "fonts/"])
:watch "src")

I expect images and webfonts from the img/ and fonts/ directories to be served as well, but the server dispatch code only seems to deal with some other file types:

https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/repl/browser.clj#L104

(server/dispatch-on :get
(fn [{:keys [path]} _ _]
(or
(= path "/")
(.endsWith path ".js")
(.endsWith path ".cljs")
(.endsWith path ".map")
(.endsWith path ".html")
(.endsWith path ".css")))
send-static)

Could this be extended to support all types of files in the static directories? Or could more cases be added for .jpg, .woff and .png?

My workaround is to load index.html from a separate static server, and use the REPL server only for the REPL connection. But in this setup, somehow (require my-ns.core :reload) keeps reloading the old code. This problem doesn't occur when I load index.html from the REPL server.



 Comments   
Comment by Sander Dijkhuis [ 16/Mar/15 8:04 AM ]

Here’s a quick first attempt. It tries to serve all static files that can be found. I don’t see downsides to this approach yet.

Now images get downloaded but don’t render. I guess this is because the served files’ Content-Type is wrong: e.g. image/jpeg; charset=utf-8. If I’m not mistaken no charset should be specified, and this requires some more checking in cljs.repl.server/end-and-close.

Is it OK to stretch the experimental server’s use to support binary files, or should I look for a more specialised development server?

Comment by Sander Dijkhuis [ 18/Mar/15 3:35 AM ]

I’m giving up on my patch for now. It’s not enough to remove the charset from the Content-Type header. I guess cljs.repl.browser/send-static needs to be adjusted to deal with binary streams instead of slurping binary files into strings. It should also have a more extensive list of MIME types. But then I’m not sure if cljs wants to be a complete experimentation server.

In the attachment is a minimal test case:
1. put a cljs.jar inside the extracted directory
2. run make
3. open http://localhost:9000/

Comment by Sander Dijkhuis [ 18/Mar/15 3:47 AM ]

(Slightly friendlier version of the test case.)

Comment by David Nolen [ 14/May/15 9:36 PM ]

fixed https://github.com/clojure/clojurescript/commit/ed5a2c928c1bcde624dbe671140e9516de54dd24





[CLJS-1249] cljs$lang$type gets removed during :advanced optimization, externs is not a solution Created: 06/May/15  Updated: 14/May/15  Resolved: 07/May/15

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

Type: Defect Priority: Minor
Reporter: Antonin Hildebrand Assignee: Unassigned
Resolution: Declined Votes: 0
Labels: None

Attachments: Text File cljs_1249.patch    

 Description   

This is a follow up to https://github.com/swannodette/mori/issues/144.

The problem:
In advanced mode, Closure Compiler removes most (or all) cljs$lang$type properties from generated constructor prototypes. It probably thinks that they are not referenced anywhere so it is safe to remove them.

There are two functions in cljs.core which depend on cljs$lang$type test and are definitely broken in advanced mode compilation:
1. pr-writer-impl method does the check to write user-friendly constructor name
2. missing-protocol method does the check as well (used in very rare scenario)

This is a test to reproduce the problem with bare clojurescript checkout:
https://gist.github.com/darwin/a83ea91f2e365946f076

I spent a good chunk of my day trying to find externs declaration which is IMO not possible.

None of these worked:

var cljs$lang$type;
Object.prototype.cljs$lang$type;

Note: This problem is not only affecting cljs$lang$type, it affects all properties set on type prototypes via (set! ...). It does not affect code which directly calls getBasis or reads a property on a specific type (Closure compiler sees that and prevents removal). It affects all code accessing those properties via "unknown" object when Closure compiler has no information about the object and it could be of any type so it does not connect the dots.

A proposal for a possible solution:

1. find a way how to instruct closure compiler to not remove cljs$lang$type and friend under without changing cljs.core implementation (I failed)
2. or use aset instead of set! to prevent closure compiler to reason about those things and leave them alone
3. or some better solution?



 Comments   
Comment by David Nolen [ 06/May/15 7:09 AM ]

Your externs should look like the following:

Object.cljs$lang$type;
Comment by Antonin Hildebrand [ 07/May/15 12:22 AM ]

Negative. Object.cljs$lang$type; does not work.

I'm pretty sure I'm including those externs correctly (debugged it to the point where externs are passed to the .compile call).

I will try to prepare a patch with aset.

Comment by Antonin Hildebrand [ 07/May/15 1:42 AM ]

the patch is based on top of http://dev.clojure.org/jira/browse/CLJS-1251

Comment by Thomas Heller [ 07/May/15 3:49 AM ]

I don't quite understand your motivation for this? As far as I understand the mori issue you are trying to create an add-on for mori which is based on top of a advanced compiled mori output?

Google Closure "advanced" mode is intended to optimize the whole program not just parts of it. AFAICT you intent to optimize mori and mori.devtools separately and then combine them later. That is not a good idea as both parts would include their own version of cljs.core (and others). Using aset basically bypasses the good parts of the Closure compiler which I'd be very careful with. Closure has facilities to export certain properties/functions but I'm not totally sure this should be done at all. Basically it looks like your are trying to get into the "guts" of an advanced compiled blob without the blob being prepared for it. Which will likely cause problems in many areas.

devtools also sounds like something that I want to use in :none and removed in :advanced. Why should my users carry the extra "weight" of a debug feature they are never going to see?

Comment by Antonin Hildebrand [ 07/May/15 4:18 AM ]

I agree with your points when cljs-devtools is used by a developer in a clojurescript project. Dev mode with :none works well and the developer has full control over removing cljs-devtools in :advanced mode.

Unfortunately with mori.js the story is different. Developers consuming the library typically use precompiled .js files from :advanced mode compilation. Javascript developers are unlikely to install clojure(script) tools and compile mori in dev mode with :none (they will use 'npm install mori').

That is why I forked mori.js and added mori.devtools.js as a new module. This enables mori users to optionally include this file in the same fashion as they could or could not include other optional mori parts (mori.mutable.js, mori.extras.js). Using modules properly should not affect mori.js size. As long as the developer uses the same version of precomiled mori.js and mori.devtools.js they should be good.

But mori is not the only case for this. I can imagine some clojurescript project would like to use modules to build devtools support module as a part of their release process and use it in special cases for debugging release builds. There should be no problem to use devtools in :advanced build if someone really wants to (for whatever reason).

While jumping through the hooks of advanced compilation, I discovered bugs which are real and should be fixed on clojurescript side. The problem of missing cljs$lang$type is not huge but exists and affects existing cljs.core code.

Comment by David Nolen [ 07/May/15 7:44 AM ]

I just confirmed that externs work fine for Object.cljs$type$lang.

Comment by Antonin Hildebrand [ 13/May/15 8:49 AM ]

Can you be more specific where did you put Object.cljs$type$lang to make it work?

I tried:
1. adding it into cljs-devtools, under resources/closure-js/externs/devtools.externs.js (to use Leiningen magic to include library externs) - and it really includes it
2. adding it into clojurescript compiler itself by adding it into src/main/cljs/cljs/externs.js (no effect)
3. adding it into mori.js as an extern file (I don't want to do that in mori)

None of those worked for me.

I'm ok with declining my proposed change. But you could copy and paste my test cases and investigate them. There is a real problem and they expose it.

(pr-str SampleType) should return user-friendly type name, not function string dump

Comment by David Nolen [ 14/May/15 11:41 AM ]

Antonin I don't have time to look into this for you. But believe me externs always work, the entire ClojureScript ecosystem depends on it.

Comment by Antonin Hildebrand [ 14/May/15 11:46 AM ]

Thanks for your reply. No worries. I understand. Thank you for all your work on ClojureScript.





[CLJS-1226] Add on-testing-complete hook Created: 27/Apr/15  Updated: 13/May/15  Resolved: 12/May/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: 0.0-3308

Type: Enhancement Priority: Minor
Reporter: Sebastian Bensusan Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: cljs, enhancement, test

Attachments: Text File cljs_1226.patch     Text File cls_1226_v2.patch    
Patch: Code

 Description   

When a test runner runs async tests created with cljs.test/async there is no reliable way to return the control from the async code in the test suite to the test runner. This is problematic since the test script might need the tests results to proceed or terminate.

A function to be called after all tests are done is proposed: cljs.test/*on-testing-complete-fn* and it would take the test summary as its only argument

It can be set by the user by calling cljs.test/set-on-testing-complete! which should be callable from JS (^:export)

Notes:
In the patch, the function cljs.test/successful? also has the ^:export metadata to be called from JS test runners.
The code was tested manually with V8, Spidermonkey, Nashorn, SlimerJs, and PhantomJS but not with JavaScript Core.



 Comments   
Comment by Jenan Wise [ 01/May/15 2:40 PM ]

Rather than relying on a global, what about if run-tests took a callback? It would differentiate the API from clojure.test but they are already different due to the env arg and nil return value.

Comment by Sebastian Bensusan [ 01/May/15 2:59 PM ]

It is currently in a global to allow easy access from outside cljs (js runners). By having it to pass it to run-tests it would be harder to make reusable test runners from outside cljs/ Said runners would have to know both the ns to run (TBD in each project) and the callback (what we want to reuse, i.e. phantom.exit(0))

Comment by David Nolen [ 05/May/15 7:02 AM ]

Is there any particular reason to not invoke do-report with a suitable dispatch value instead of adding a new function here?

Comment by Sebastian Bensusan [ 05/May/15 7:29 AM ]

I'm not sure that I understand. I thought do-report and report were meant for printing out the summary as a report. This on-testing-complete hook should allow the caller to do whatever he/she wants after all tests are done. Do you want to allow the caller to specify how report works for some new dispatch value by adding:

(defmethod report [::default :on-testing-complete] [m]
..custom-code)

Comment by David Nolen [ 05/May/15 7:32 AM ]

The purpose of report is just side effects, printing is only one possibility. Note there are several testing events that aren't even really used by the standard reporter.

Comment by Leon Grapenthin [ 05/May/15 12:37 PM ]

IMHO if you want to run anything synchronously before after or between tests, you should use fixtures or if necessary compose the desired blocks yourself.

At least making the latter possible is why I made run-block and the block builder fns public.

You can easily run

(run-block (concat (run-tests-block 'a-ns-to-be-tested 'another-ns-to-be-test )
[(fn []
;; your continuation code here
)]))

This is a reliable way to pick up control after testing.

This patch only affects testing done via run-tests. E. g. on-testing-complete-fn won't be invoked if a user invoked test-ns and testing is complete. You could hack it into the block composer in test-ns, but still users composing blocks in the way mentioned above couldn't rely on it being invoked.

Comment by Sebastian Bensusan [ 11/May/15 10:25 AM ]

I followed Leon's suggestions and used run-block to make my own test-block. The only problem is that my continuation function doesn't get the summary/env as an argument. From what I understood I could pass env as an argument to run-tests but it would get cleared right before my continuation function. I don't know how to work around this yet.

If you think my solution is a correct use of the cljs.test API then this patch isn't needed. If you believe that run-tests should report on-testing-done I'd be happy to submit a new patch adding a new event to the report event system. Then I could get the summary/env from a custom report method as David suggested.

Comment by David Nolen [ 11/May/15 10:37 AM ]

I would not consider anything at the level of run-block part of the public API nor anything that anyone should be looking into. This stuff may change.

Please add a real reporting hook thanks.

Comment by Sebastian Bensusan [ 12/May/15 5:39 AM ]

Added :end-run-test event to cljs.test and a dummy event handler for it.

Comment by David Nolen [ 12/May/15 3:04 PM ]

fixed https://github.com/clojure/clojurescript/commit/31736450c6ca951c63bb685d744c11074fbfe323

Comment by Leon Grapenthin [ 12/May/15 4:09 PM ]

For API consistency this should also be in the blocks of `test-all-vars` in `test-ns`, `test-var` and `test-vars`.

Comment by David Nolen [ 12/May/15 4:24 PM ]

Happy to see a new ticket + patch that addresses the consistency issue.

Comment by Sebastian Bensusan [ 13/May/15 2:51 AM ]

Leon, I filled CLJS-1267 to address your point. Feel free to add any other API inconsistencies that :end-run-tests introduced.





[CLJS-1256] cljs.core/UUID should cache hash value Created: 08/May/15  Updated: 12/May/15  Resolved: 12/May/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: 0.0-3308

Type: Enhancement Priority: Major
Reporter: Nikita Prokopov Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: None

Attachments: Text File cljs-1256-cache-uuid-hash-3.patch    

 Description   

cljs.core/UUID calculates hash each time hash is called on it. This patch adds caching of the calculated hash value. It also avoids going through pr-str for hash calculation which involves string concatenation and couple of object allocations.

Updated patch also introduces public constructor cljs.core/uuid for creating UUID objects. All places where UUID. ctor was used will now generate a warning.



 Comments   
Comment by David Nolen [ 10/May/15 2:42 PM ]

The patch needs work. Declare __hash as a ^:mutable field on UUID. Thanks.

Comment by Nikita Prokopov [ 10/May/15 2:53 PM ]

This was the first thing I tried. Unfortunately new field breaks all the places where UUID is constructed, including user code. Suggestions how to avoid that?

Comment by David Nolen [ 10/May/15 5:18 PM ]

Raw constructors are generally considered implementation details but sadly we never provided a public fn ctor in this case. There's not much to do other than supply a uuid fn. Any users directly using the deftype ctor will get warnings about invalid arity and they will have to fix their code and rely on the new uuid ctor fn.

Comment by Nikita Prokopov [ 11/May/15 5:00 AM ]

Attaching fixed path

Comment by David Nolen [ 12/May/15 3:07 PM ]

The patch does not apply cleanly on master. Can we get a rebased patch? Thanks!

Comment by Nikita Prokopov [ 12/May/15 3:35 PM ]

Rebased onto 31736450c6ca951c63bb685d744c11074fbfe323

Comment by David Nolen [ 12/May/15 4:27 PM ]

fixed https://github.com/clojure/clojurescript/commit/bc4f3b5930c7f02f062beffa5ca1f8c8206ecb5c





[CLJS-1264] ClojureScript 0.0-3255 breaks compatibility with Clojure 1.6.0 Created: 11/May/15  Updated: 12/May/15  Resolved: 12/May/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3255, 0.0-3269
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Stephen Nelson Assignee: Unassigned
Resolution: Declined Votes: 0
Labels: None


 Description   

ClojureScript 0.0-3255 renamed several core files from clj to cljc. This breaks compatibility with Clojure 1.6.0, which is significant because Clojure 1.7.0 hasn't been released yet. This change forces any projects that bundle ClojureScript to switch to an unreleased Clojure or fall behind ClojureScript.

Falling behind ClojureScript is a significant problem as most development tools and libraries follow CLJS head, so a project that uses an old CLJS must use old libraries and build tools too, or maintain forks for pulling in bug fixes.

It would be good if this change could be reverted until CLJ 1.7 lands. If this is not possible, please consider maintaining a CLJ 1.6 branch and back porting bug fixes.



 Comments   
Comment by David Nolen [ 12/May/15 3:08 PM ]

There are stable releases of ClojureScript that work with Clojure 1.6.0. Use them if you need to. We're not going to maintain a 1.6.0 branch.





[CLJS-1265] Rename from .cljs to .cljc results in :reload failing Created: 12/May/15  Updated: 12/May/15

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

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


 Description   

Set up QuickStart browser REPL.

1. On disk, create a new file in src, say foo/bar.cljs and define a symbol in it.
2. In the REPL (require 'foo.bar) and then make use of the symbol.
3. On disk, rename the file to bar.cljc, and then edit the file to introduce a new symbol.
4. In the REPL (require 'foo.bar :reload) and then try to make use of the new symbol.

For a function defnition, at this point I get an error

TypeError: undefined is not an object (evaluating 'foo.bar.call_me.call')


 Comments   
Comment by Mike Fikes [ 12/May/15 2:05 PM ]

FWIW as a comparison, the same use case works properly with Clojure 1.7.0-beta2 (in regular lein repl).





[CLJS-1266] Node: Rename .cljs to .cljc -> old filenames in stacktrace Created: 12/May/15  Updated: 12/May/15

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

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


 Description   

Using QuickStart, set up Node REPL.

Manually add a foo/bar.cljs to filesystem with

(ns foo.bar)

(defn throw-ex [] (ffirst 1))

(defn call-me [] (throw-ex))

Check that it works:

cljs.user=> (require 'foo.bar)
nil
cljs.user=> (foo.bar/call-me)
repl:13
throw e__4210__auto__;
      ^
Error: 1 is not ISeqable
    at Object.cljs$core$seq [as seq] (/Users/mfikes/Desktop/hello_world-node/out/cljs/core.cljs:956:20)
    at Object.cljs$core$first [as first] (/Users/mfikes/Desktop/hello_world-node/out/cljs/core.cljs:965:16)
    at cljs$core$ffirst (/Users/mfikes/Desktop/hello_world-node/out/cljs/core.cljs:1398:11)
    at foo$bar$throw_ex (/Users/mfikes/Desktop/hello_world-node/out/foo/bar.cljs:3:20)
    at foo$bar$call_me (/Users/mfikes/Desktop/hello_world-node/out/foo/bar.cljs:5:19)
    at repl:1:105
    at repl:9:3
    at repl:14:4
    at Object.exports.runInThisContext (vm.js:74:17)
    at Domain.<anonymous> ([stdin]:41:34)

Then manually move bar.cljs to bar.cljc and add a new symbol so it looks like:

(ns foo.bar)

(defn throw-ex [] (ffirst 1))

(defn call-me [] (throw-ex))

(defn call-again [] (call-me))

Then reload the ns and use the new symbol:

cljs.user=> (require 'foo.bar :reload)
nil
cljs.user=> (foo.bar/call-again)
repl:13
throw e__4210__auto__;
      ^
Error: 1 is not ISeqable
    at Object.cljs$core$seq [as seq] (/Users/mfikes/Desktop/hello_world-node/out/cljs/core.cljs:956:20)
    at Object.cljs$core$first [as first] (/Users/mfikes/Desktop/hello_world-node/out/cljs/core.cljs:965:16)
    at cljs$core$ffirst (/Users/mfikes/Desktop/hello_world-node/out/cljs/core.cljs:1398:11)
    at foo$bar$throw_ex (/Users/mfikes/Desktop/hello_world-node/out/foo/bar.cljs:3:20)
    at foo$bar$call_me (/Users/mfikes/Desktop/hello_world-node/out/foo/bar.cljs:5:19)
    at foo$bar$call_again (/Users/mfikes/Desktop/hello_world-node/out/foo/bar.cljs:5:19)
    at repl:1:108
    at repl:9:3
    at repl:14:4
    at Object.exports.runInThisContext (vm.js:74:17)

This illustrates the defect. call_again and the other symbols are shown as being in the old filename.

Stop the REPL and restart it to see correct behavior:

cljs.user=> :cljs/quit
orion:hello_world-node mfikes$ rlwrap java -cp cljs.jar:src clojure.main node_repl.clj
Reading analysis cache for jar:file:/Users/mfikes/Desktop/hello_world-node/cljs.jar!/cljs/core.cljs
Compiling src/foo/bar.cljc
ClojureScript Node.js REPL server listening on 49397
Watch compilation log available at: out/watch.log
To quit, type: :cljs/quit
cljs.user=> (require 'foo.bar)
nil
cljs.user=> (foo.bar/call-again)
repl:13
throw e__4210__auto__;
      ^
Error: 1 is not ISeqable
    at Object.cljs$core$seq [as seq] (/Users/mfikes/Desktop/hello_world-node/out/cljs/core.cljs:956:20)
    at Object.cljs$core$first [as first] (/Users/mfikes/Desktop/hello_world-node/out/cljs/core.cljs:965:16)
    at cljs$core$ffirst (/Users/mfikes/Desktop/hello_world-node/out/cljs/core.cljs:1398:11)
    at foo$bar$throw_ex (/Users/mfikes/Desktop/hello_world-node/out/foo/bar.cljc:3:20)
    at foo$bar$call_me (/Users/mfikes/Desktop/hello_world-node/out/foo/bar.cljc:5:19)
    at foo$bar$call_again (/Users/mfikes/Desktop/hello_world-node/out/foo/bar.cljc:7:22)
    at repl:1:108
    at repl:9:3
    at repl:14:4
    at Object.exports.runInThisContext (vm.js:74:17)


 Comments   
Comment by Mike Fikes [ 12/May/15 2:04 PM ]

FWIW as a comparison, the same use case works properly with Clojure 1.7.0-beta2.





[CLJS-1263] :libs regression, can no longer specify specific files Created: 11/May/15  Updated: 11/May/15  Resolved: 11/May/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: 0.0-3308

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


 Description   

:libs currently works great for directories but the support for individual files specified by the user is broken.



 Comments   
Comment by David Nolen [ 11/May/15 3:43 PM ]

fixed https://github.com/clojure/clojurescript/commit/e9de8c70de99cedb67e6bde7c3a9f65a716b6e35





[CLJS-1198] cljs.test may report summary before all async tests complete Created: 12/Apr/15  Updated: 11/May/15  Resolved: 05/May/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3196
Fix Version/s: 0.0-3255

Type: Defect Priority: Major
Reporter: Jenan Wise Assignee: David Nolen
Resolution: Completed Votes: 1
Labels: None

Attachments: File cljs-1198-1    

 Description   

cljs.test may report summary before all async tests complete.

E.g, if you have an async test that looks like this:

(deftest a-test
  (async done
         (testing "a slow async test"
           (go
             (<! (timeout 1000))
             (is (= 0 1))
             (done)))))

then the report output may look like this:

Ran 1 tests containing 0 assertions.
0 failures, 0 errors.

<1 second elapses>

FAIL in () (cljs_test_with_slow_async_example/core_test.js:201:49)
expected: (= 0 1)
  actual: (not (= 0 1))

Minimal repo: https://github.com/jenanwise/cljs-test-with-slow-async-example



 Comments   
Comment by Leon Grapenthin [ 15/Apr/15 12:28 PM ]

I am quite surre that the problem has been introduced with this commit: https://github.com/clojure/clojurescript/commit/9bf486b22cebf5aba4154d07f3ad52e990ddc305

@David
I don't understand the intent of the commit message "cljs.test needs to default to sync, remove broken validation"

Why should the execution strategy default to :sync?

From my reading of the commit this would imply that, unless one provides map fixtures, tests are executed without support for async testing.

This is what happens. The problem goes away if I one adds e. g.

(use-fixtures :each {:before (fn [_])
:after (fn [_])})

I don't see why you removed the guard around async tests in the :sync execution. Its purpose was to throw when execution strategy is :sync an and async test is encountered.

If you can help with the intent of your commit, I'd be glad to provide the fix for myself. What validation was broken?

Comment by David Nolen [ 15/Apr/15 1:41 PM ]

Leon, when I changed how top-level fn emission worked for cross module code motion even though I could see good code getting generated I couldn't run the tests because of the validation bit. After poking around I couldn't make heads or tails of the invariant the code was trying to maintain and so I removed it. All the tests started working again.

Happy to see the invariants re-introduced if the code more clearly documents intent so I can understand it

Comment by Leon Grapenthin [ 15/Apr/15 2:26 PM ]

Can you specify on what you mean by the invariant?

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

Leon, I have no idea what the check was doing nor why it was done that way, only that it prevented me from successfully running more important tests. So you will have to explain the approach to me

Comment by Leon Grapenthin [ 16/Apr/15 2:51 PM ]

Here I try to give you a quick overview of what is going on in the code you have removed/altered:

It solved the problem brought up in our discussion regarding the CLJS-988: The style in which clojure.test requires fixtures to be written didn't allow one to determine when an async test is over. Hence you came up with this requirement: http://dev.clojure.org/jira/browse/CLJS-988?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#issue-tabs

This is the way I have chosen to implement it:

In test-vars-block we create a block that looks up fixtures in the current env and decides whether to support async testing via execution-strategy.

In any case except for wrapped fixtures we run with support for async testing by executing the provided test functions in a block so that they can return async tests which are then picked up by the block runner. Also, via test-var-block additional code is wrapped around and added after them for reporting purposes.

In the case where wrapped fixtures are provided, we can't just create a test-var-block in the same fashion because flow control is passed to the wrapping fixtures and they don't execute or return a block. The only way work around this is to provide them directly with a function that invokes a nested block runner. Implicitly reusing test-var-block here was a decision made for obvious DRY reasons.

Now if async tests are used in the test function, the nested block runner could return before testing is finished, continuing testing too early. This is why the execution strategy is called sync: It expects the nested block runners to finish synchronously.

Per your requirment, testing should be aborted if an async test is encountered in the latter case. We can only know whether a test is async once it has been called and returned something. I didn't see a way to find out what was returned in the :sync result-expr directly, since test-var doesn't return what the test has returned. Hence I picked to look at what the test has returned in the test-var-block and throw if an async test is returned and async tests are disabled, storing this condition in the test-env. Today I see a strong alternative to that: Directly wrap the :test fn in the var in the :sync result-expr to throw if it returns an async test. It surely seems cleaner. You'd get a true invariant because the test-env would be out of the game. Notice though that anyhting thrown there will be catched by the reporting exception handler in test-var-block and testing would continue, so it has to rethrow to truely abort testing. Directly looking up the test-env in the async macro would have been another alternative which I have discarded for its dirtiness because it requires users to invoke async during testing to work.

I hope this helped you to understand the code. To make the code more understandable one could rename execution-strategy to async-supported? and return a boolean.

In any case, the :async execution-strategy needs to be the default, otherwise returned async test objects are not expanded into the root block and this CLJS-1198 happens.

I can provide a patch with the aforementioned improvements on sunday if you like. Finally I have no idea why the check prevented your tests from running - Can you tell me which tests I can use to potentially reproduce the problem?

Comment by Leon Grapenthin [ 19/Apr/15 8:32 AM ]

Patch notes:

  • changes default execution-strategy back to :async
  • prevents async tests from running when execution-strategy is sync

@David: I had to dissect test-var-block a bit because apparently alter-meta! is broken for vars. Please see commented lines 549 and 552 - Also I couldn't check whether this resolves the issue you had with tests being prevented from running after the compiler changes.

Comment by Sebastian Bensusan [ 01/May/15 3:36 PM ]

Experience report: tested this patch with the problematic repo and some other slow async test cases including fixture variations and it seems to work as expected. It also worked with ClojureScript's own tests (tested on all platforms but JavaScriptCore).

Hope this helps.

Comment by David Nolen [ 05/May/15 6:58 AM ]

fixed https://github.com/clojure/clojurescript/commit/c9bf3f4aadf79d5042a27a6ef0e4cd5db4c26604

Comment by Jenan Wise [ 11/May/15 12:31 PM ]

Many thanks!





[CLJS-1242] Add cljs.core/pattern? predicate Created: 03/May/15  Updated: 10/May/15

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

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

Attachments: Text File CLJS-1242_v01.patch    
Patch: Code and Test

 Description   

Just like http://dev.clojure.org/jira/browse/CLJS-1241 , this helps with clj/cljs cross-platform development.



 Comments   
Comment by Brandon Bloom [ 03/May/15 2:38 PM ]

See also http://dev.clojure.org/jira/browse/CLJ-1720

Comment by Brandon Bloom [ 10/May/15 11:36 PM ]

Note that there already is a cljs.core/regexp?, since it's used in a few places by core.





[CLJS-1209] Reduce produces additional final nil when used w/ eduction Created: 16/Apr/15  Updated: 10/May/15  Resolved: 10/May/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: 0.0-3308

Type: Defect Priority: Major
Reporter: Karsten Schmidt Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: transducers


 Description   
Unable to find source-code formatter for language: clojure. Available languages are: javascript, sql, xhtml, actionscript, none, html, xml, java
(defn my-conj
  [acc x]
  (prn acc x)
  (conj acc x))

(reduce my-conj [] (eduction (map identity) [1 2 3]))
;; [] 1
;; [1] 2
;; [1 2] 3
;; [1 2 3] nil
;; [1 2 3 nil]

This seems to be a CLJS specific issue - the above works fine in CLJ1.7.0-beta1. On the other hand, reductions too doesn't suffer this behavior (in CLJS):

Unable to find source-code formatter for language: clojure. Available languages are: javascript, sql, xhtml, actionscript, none, html, xml, java
(reductions my-conj [] (eduction (map identity) [1 2 3]))
;; [] 1
;; [1] 2
;; [1 2] 3
;; ([] [1] [1 2] [1 2 3])


 Comments   
Comment by David Nolen [ 10/May/15 2:30 PM ]

I cannot reproduce with 0.0-3269. Please feel free to reopen if more information can be supplied.

Comment by Karsten Schmidt [ 10/May/15 4:44 PM ]

I don't know, David - don't understand how this can be, since I just tried the same w/ 3269 and the extra `nil` still is happening (I first did use a clean setup as described in CLJS quickstart wiki). The below is from a figwheel REPL:

cljs.user=> *clojurescript-version*
"0.0-3269"

cljs.user=> (defn my-conj [acc x] (prn acc x) (conj acc x))
#<function cljs$user$my_conj(acc,x){
cljs.core.prn.call(null,acc,x);
return cljs.core.conj.call(null,acc,x);
}>

cljs.user=> (reduce my-conj [] (eduction (map identity) [1 2 3]))
[] 1
[1] 2
[1 2] 3
[1 2 3] nil
[1 2 3 nil]
Comment by Karsten Schmidt [ 10/May/15 4:47 PM ]

verified to still occur w/ 0.0-3269

Comment by Karsten Schmidt [ 10/May/15 4:49 PM ]

I you want, I can attach a zip of my test project...

Comment by David Nolen [ 10/May/15 5:10 PM ]

I wasn't quite careful enough when trying out your failing example. I see the problem, fix coming.

Comment by David Nolen [ 10/May/15 5:14 PM ]

fixed https://github.com/clojure/clojurescript/commit/ca19a521195eee3eb38f2946157c273679d64212





[CLJS-1261] source fn fails for fns with conditional code Created: 09/May/15  Updated: 10/May/15  Resolved: 10/May/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3269
Fix Version/s: None

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

(Affects 0.0-3264)



 Description   

If you use the source ClojureScript REPL function on a function defined in a CLJC file, where the function itself contains some conditional code, then the operation will fail with "Conditional read not allowed".

To reproduce:
Set up the QuickStart Browser REPL example, but instead of core.cljs, set up a core.cljc file. In that file additionally include

(defn f 
  "Eff"
  [] 
  1)

(defn g 
  "Gee"
  []
  #?(:clj "clj" :cljs "cljs"))

Verify that you can call, get the doc for, and source for f.

But, on the other hand, while you can call and get the doc for g, you can't do (source hello-world.core/g).

This results in:

cljs.user=> (source hello-world.core/g)
clojure.lang.ExceptionInfo: Conditional read not allowed at line 1 <cljs repl> {:file "<cljs repl>", :line 1, :column 1, :tag :cljs/analysis-error}
	at clojure.core$ex_info.invoke(core.clj:4591)
	at cljs.analyzer$error.invoke(analyzer.cljc:384)
	at cljs.analyzer$macroexpand_1.invoke(analyzer.cljc:1853)
	at cljs.analyzer$analyze_seq.invoke(analyzer.cljc:1896)
	at cljs.analyzer$analyze$fn__1567.invoke(analyzer.cljc:1992)
	at cljs.analyzer$analyze.invoke(analyzer.cljc:1985)
	at cljs.repl$evaluate_form.invoke(repl.cljc:429)
	at cljs.repl$eval_cljs.invoke(repl.cljc:547)
	at cljs.repl$repl_STAR_$read_eval_print__4295.invoke(repl.cljc:814)
	at cljs.repl$repl_STAR_$fn__4301$fn__4308.invoke(repl.cljc:851)
	at cljs.repl$repl_STAR_$fn__4301.invoke(repl.cljc:850)
	at cljs.compiler$with_core_cljs.invoke(compiler.cljc:968)
	at cljs.repl$repl_STAR_.invoke(repl.cljc:816)
	at cljs.repl$repl.doInvoke(repl.cljc:932)
	at clojure.lang.RestFn.invoke(RestFn.java:439)
	at user$eval30.invoke(repl.clj:10)
	at clojure.lang.Compiler.eval(Compiler.java:6792)
	at clojure.lang.Compiler.load(Compiler.java:7237)
	at clojure.lang.Compiler.loadFile(Compiler.java:7175)
	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)
Caused by: clojure.lang.ExceptionInfo: Conditional read not allowed {:type :reader-exception, :line 19, :column 5, :file nil}
	at clojure.core$ex_info.invoke(core.clj:4591)
	at clojure.tools.reader$read_STAR_.invoke(reader.clj:896)
	at clojure.tools.reader$read_delimited.invoke(reader.clj:189)
	at clojure.tools.reader$read_list.invoke(reader.clj:202)
	at clojure.tools.reader$read_STAR_$fn__767.invoke(reader.clj:878)
	at clojure.tools.reader.reader_types$log_source_STAR_$fn__501.invoke(reader_types.clj:240)
	at clojure.lang.AFn.applyToHelper(AFn.java:152)
	at clojure.lang.AFn.applyTo(AFn.java:144)
	at clojure.core$apply.invoke(core.clj:628)
	at clojure.core$with_bindings_STAR_.doInvoke(core.clj:1866)
	at clojure.lang.RestFn.invoke(RestFn.java:425)
	at clojure.tools.reader.reader_types$log_source_STAR_.invoke(reader_types.clj:239)
	at clojure.tools.reader$read_STAR_.invoke(reader.clj:867)
	at clojure.tools.reader$read.invoke(reader.clj:928)
	at clojure.tools.reader$read.invoke(reader.clj:926)
	at cljs.repl$source_fn.invoke(repl.cljc:1133)
	at cljs.repl$source.invoke(repl.cljc:1153)
	at clojure.lang.AFn.applyToHelper(AFn.java:160)
	at clojure.lang.AFn.applyTo(AFn.java:144)
	at clojure.lang.AFunction$1.doInvoke(AFunction.java:29)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.core$apply.invoke(core.clj:632)
	at cljs.analyzer$macroexpand_1.invoke(analyzer.cljc:1859)
	... 24 more
Caused by: java.lang.RuntimeException: Conditional read not allowed
	at clojure.tools.reader$read_cond.invoke(reader.clj:490)
	at clojure.tools.reader$read_dispatch.invoke(reader.clj:66)
	at clojure.tools.reader$read_STAR_$fn__767.invoke(reader.clj:878)
	at clojure.tools.reader.reader_types$log_source_STAR_$fn__501.invoke(reader_types.clj:240)
	at clojure.lang.AFn.applyToHelper(AFn.java:152)
	at clojure.lang.AFn.applyTo(AFn.java:144)
	at clojure.core$apply.invoke(core.clj:628)
	at clojure.core$with_bindings_STAR_.doInvoke(core.clj:1866)
	at clojure.lang.RestFn.invoke(RestFn.java:425)
	at clojure.tools.reader.reader_types$log_source_STAR_.invoke(reader_types.clj:239)
	at clojure.tools.reader$read_STAR_.invoke(reader.clj:867)
	... 45 more


 Comments   
Comment by David Nolen [ 10/May/15 2:21 PM ]

fixed https://github.com/clojure/clojurescript/commit/db91a65769bb975c3da2a452dc834b8867021c8f

Comment by Mike Fikes [ 10/May/15 2:44 PM ]

Confirmed fixed.

Comment by Mike Fikes [ 10/May/15 2:53 PM ]

I created a similar ticket for Clojure: http://dev.clojure.org/jira/browse/CLJ-1728





[CLJS-1166] Browser REPL stacktraces unprocessed if explicit IP used Created: 24/Mar/15  Updated: 10/May/15  Resolved: 10/May/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3126
Fix Version/s: None

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

QuickStart Browser REPL OS X Safari (other browsers as well)



 Description   

Go through the Quick Start but change the repl/connect form to use an explicit IP instead of localhost. (In this case the IP I am trying is indeed the same host, if that matters.)

(defonce conn
  (repl/connect "http://10.96.82.207:9000/repl"))

Then connect to the REPL using the explicit IP http://10.96.82.207:9000.

The REPL will function properly but stacktraces are not properly processed. Here is an example (generated using Safari):

ClojureScript:cljs.user> (ffirst [1])
Error: 1 is not ISeqable
cljs$core$seq@http://10.96.82.207:9000/out/cljs/core.js:4667:17
cljs$core$first@http://10.96.82.207:9000/out/cljs/core.js:4697:22
cljs$core$ffirst@http://10.96.82.207:9000/out/cljs/core.js:5774:23


eval code
eval@[native code]
http://10.96.82.207:9000/out/clojure/browser/repl.js:42:271
clojure$browser$repl$evaluate_javascript@http://10.96.82.207:9000/out/clojure/browser/repl.js:45:4
http://10.96.82.207:9000/out/clojure/browser/repl.js:242:173
deliver@http://10.96.82.207:9000/out/goog/messaging/abstractchannel.js:142:21
xpcDeliver@http://10.96.82.207:9000/out/goog/net/xpc/crosspagechannel.js:733:19
messageReceived_@http://10.96.82.207:9000/out/goog/net/xpc/nativemessagingtransport.js:321:23
fireListener@http://10.96.82.207:9000/out/goog/events/events.js:741:25
handleBrowserEvent_@http://10.96.82.207:9000/out/goog/events/events.js:862:34
http://10.96.82.207:9000/out/goog/events/events.js:276:42


 Comments   
Comment by David Nolen [ 10/May/15 2:45 PM ]

as far as I can tell this was resolved with the fix for CLJS-1258 https://github.com/clojure/clojurescript/commit/d0bf12f24f3455fdc45962206580ab50ca907638





[CLJS-1234] local :foreign-libs support for REPLs Created: 01/May/15  Updated: 10/May/15  Resolved: 10/May/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3255
Fix Version/s: 0.0-3269

Type: Defect Priority: Major
Reporter: David Nolen Assignee: David Nolen
Resolution: Not Reproducible Votes: 0
Labels: None


 Description   

It appears local (not upstream) :foreign-libs will not get picked up by REPLs.



 Comments   
Comment by David Nolen [ 09/May/15 11:17 AM ]

fixed https://github.com/clojure/clojurescript/commit/d9feda128c2ded18967bebffb103e84f6b69d928

Comment by David Nolen [ 09/May/15 3:55 PM ]

The current behavior is is add with the support for Closure libraries that follow classpath conventions.

Comment by David Nolen [ 10/May/15 8:57 AM ]

There are no issues with master. :libs directories need to be on the classpath.





[CLJS-1260] >= 0.0-3265 cannot compile Closure style libraries that conform to the classpath Created: 09/May/15  Updated: 09/May/15  Resolved: 09/May/15

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

Type: Defect Priority: Blocker
Reporter: David Nolen Assignee: David Nolen
Resolution: Completed Votes: 0
Labels: None


 Comments   
Comment by David Nolen [ 09/May/15 3:48 PM ]

fixed https://github.com/clojure/clojurescript/commit/4f8d24cf5f857bf114e09535cfbb0f5db17326a9





[CLJS-1168] REPL fails to find .js files in :libs Created: 25/Mar/15  Updated: 09/May/15  Resolved: 09/May/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3255
Fix Version/s: 0.0-3269

Type: Defect Priority: Major
Reporter: Daniel Skarda Assignee: David Nolen
Resolution: Completed Votes: 0
Labels: None
Environment:

org.clojure/clojurescript 0.0-3149
Tested with both basic clojurescript REPL and new com.cemerick/piggieback 0.2.0-20150324.120715-1



 Description   

We use Google E2E library for encryption. This library is written using Google Closure.
The library is stored locally in a directory ("closure-libs/e2e") and we pass :libs ["closure-libs/e2e"] to the compiler.

Compilation of our project works fine. Compiler does find the library without problems in all optimization modes.

Recently we have problem with REPL. With same parameters, REPL fails to load the library:

java.lang.IllegalArgumentException: Namespace e2e.async.Result does not exist
at cljs.closure$source_for_namespace.invoke(closure.clj:501)
at cljs.repl$load_namespace.invoke(repl.clj:181)
at cljs.repl$load_dependencies.invoke(repl.clj:201)
at cljs.repl$evaluate_form.invoke(repl.clj:444)
at cljs.repl$eval_cljs.invoke(repl.clj:527)
at cljs.repl$repl_STAR_$read_eval_print__4890.invoke(repl.clj:783)
at cljs.repl$repl_STAR_$fn_4896$fn_4903.invoke(repl.clj:821)
at cljs.repl$repl_STAR_$fn__4896.invoke(repl.clj:820)
at cljs.compiler$with_core_cljs.invoke(compiler.clj:951)
at cljs.repl$repl_STAR_.invoke(repl.clj:785)
at cryptelo.dev.cljs.env$eval11953.invoke(02b7dffab3345931421313ec2fe5d506990ab5e5-init.clj:1)

I spent long time investigating the issue (which is not easy given jungle of compiler and repl option maps, bindings of global variables etc).

What I found:

  • compiler finds the library without problem, all our tests invoked from the command line pass
  • both basic cljs REPL and piggieback (0.2.0 experimental branch) fails to find the library
  • :libs files are not copied to :output-dir
  • at the beginning, repl calls default-compiler-env with options
  • default-compiler-options run js-dependency-index, which scans all libraries and stores it in compiler atom
  • strace proves that clojurescript finds closure-libs/e2e/deps.js and reads it
  • calling (js-dependency-index {:libs ["closure-lib/e2e"]}) proves that the e2e.async.Result was found

But:

  • library-dependencies stores file path as URL in {:url ...}
  • source-for-namespace (from error stack) finds the file, but expects relative path with key :file

This is where my investigation stops. I am sure that fix would be probably easy, but I do not know all details of information cljs stores about .js files. Moreover I do not know why it works in compiler and not in REPL. Probably compiler does not open file and passes
it as a argument to Google Closure, while REPL actually wants to load the file itself.

Hope you have all information to fix the problem.

Thank you.



 Comments   
Comment by David Nolen [ 25/Mar/15 8:49 AM ]

Please do not include piggieback information when reporting issues to JIRA. We do not consider downstream tooling here at all. Will take a look, thanks for the report!

Comment by David Nolen [ 09/May/15 1:47 PM ]

fixed https://github.com/clojure/clojurescript/commit/5858966764728393f86cdeca50a049e350c670eb