Clojure JIRAhttp://dev.clojure.org/jira/secure/IssueNavigator.jspa?reset=true&jqlQuery=project+%3D+TANAL+ORDER+BY+updated+DESC%2C+priority+DESC%2C+created+ASC
An XML representation of a search requesten-us4.464925-07-2011[TANAL-109] Reasonable not to warn about wrong tag for specifying class as (Class/forName "[D") in extend* ?http://dev.clojure.org/jira/browse/TANAL-109
tools.analyzer<p>Probably same issue as <a href="http://dev.clojure.org/jira/browse/TANAL-24" title="clojure.tools.analyzer.passes.jvm/validate throws an exception when :tag metadata cannot be resolved to a Class"><del>TANAL-24</del></a>, <a href="http://dev.clojure.org/jira/browse/TANAL-31" title="analyzing extend expression with non-constant type/class throws exception"><del>TANAL-31</del></a>, etc. but checking anyway, in case I am missing something.</p>
<p>Right now latest tools.analyzer(.jvm) calls the wrong-tag callback for code like this:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(defprotocol PTypeInfo
(element-type [m]))
(extend-protocol PTypeInfo
(<span class="code-object">Class</span>/forName <span class="code-quote">"[D"</span>) ;; &lt;-- because of <span class="code-keyword">this</span> class
(element-type [m] :<span class="code-object">double</span>))</pre>
</div></div>
<p>#1: Is there a way to write an extend* form for the class 'array of primitive doubles' that t.a(.j) will not call the wrong-tag handler for, as written now?</p>
<p>#2: If answer to #1 is "no", then should I write the wrong-tag callback function for this case specially somehow not to warn about it, in Eastwood? Or is it reasonable to expect the wrong-tag callback fn not to be called at all?</p>
<p>Regardless of which side of the wrong-tag callback this is handled on, it appears to be correct Clojure code, and the core.matrix library uses it quite often. I haven't run across it in any other libraries yet, but llasram on #clojure IRC said he had not found any other way to call extend on such a type, and sometimes uses that kind of code.</p>TANAL-109Reasonable not to warn about wrong tag for specifying class as (Class/forName "[D") in extend* ?EnhancementMinorClosedDeclinedNicola MomettoAndy FingerhutTue, 6 Jan 2015 10:47:08 -0600Tue, 6 Jan 2015 16:39:06 -0600Tue, 6 Jan 2015 14:32:17 -060001<p>See <a href="http://dev.clojure.org/jira/browse/CLJ-1308">http://dev.clojure.org/jira/browse/CLJ-1308</a></p>
<p>I don't know if using extend-protocol/extend-type with a runtime-determined class is actually supported or just happens to work.</p>
<p>I'm more inclined to say that both macros aren't designed to work this way and that extend should be used instead (extend, as opposed to extend-type/extend-protocol is a regular function and it doesn't do any magic to automatically tag "this")</p>
<p>Anyway, the issue here is that '(Class/forName "<span class="error">&#91;D&quot;&#93;</span>) is a nonsensical tag so I'd say the current behaviour of TANAL is correct and coherent, you'll have to find a way to work around this in Eastwood.</p><p>Thanks for the explanation &#8211; again. You should only have to remind me about 3 more times <img class="emoticon" src="http://dev.clojure.org/jira/images/icons/emoticons/smile.gif" height="20" width="20" align="absmiddle" alt="" border="0"/></p>
<p>Seriously, I am writing up some notes for Eastwood documentation on this particular case, with a pointer to <a href="http://dev.clojure.org/jira/browse/CLJ-1308" title="extend-type doesn&#39;t type-hint correctly as promised by the doc when the class is determined at run-time">CLJ-1308</a>, and examples showing why this particular (Class/forName "[D") example does not produce correct type tags when used with extend-protocol or extend-type, and how to do it correctly with extend instead. Then I ought to remember at least this case.</p><p>I just added a comment to <a href="http://dev.clojure.org/jira/browse/CLJ-1308">http://dev.clojure.org/jira/browse/CLJ-1308</a> about some new docs/examples added to Eastwood documentation about this case.</p>Global Rank[TANAL-107] Latest t.a(.j) throws exception during analyze+eval of core.matchhttp://dev.clojure.org/jira/browse/TANAL-107
tools.analyzer<p>Tag eastwood-0.2.1-alpha2 of Eastwood uses t.a(.j) of about 4 weeks ago, and does not have this crash.</p>
<p>Branch update-tanal of Eastwood, latest master as of Dec 21 2014, does have this crash.</p>
<p>Reproduce steps:</p>
<p>Go to directory crucible and run ./clone.sh if not already done, to create the directory repos/core.match-2014-03-05 beneath that.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">cd repos/core.match-2014-03-05
lein eastwood</pre>
</div></div>
<p>With version 0.2.1-alpha2 and older t.a(.j), no exception.<br/>
With latest Eastwood on branch update-tanal, an exception that begins with:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">== Linting clojure.core.match.test.date ==
src/test/clojure/clojure/core/match/test/date.clj:4:9: unlimited-use: Unlimited use of (clojure.core.match.date) in clojure.core.match.test.date
Exception thrown during phase :analyze+eval of linting namespace clojure.core.match.test.date
Got exception with extra ex-data:
msg='No such namespace: cljs.core'
(keys dat)=(:end-line :file :line :column :end-column :ns :form)
(:form dat)=
^{:line 1179} cljs.core/ILookup
ExceptionInfo No such namespace: cljs.core
clojure.core/ex-info (core.clj:4327)
eastwood.copieddeps.dep2.clojure.tools.analyzer.passes.jvm.validate/eval2044/fn--2046 (validate.clj:47)</pre>
</div></div>
<p>I may keep investigating to narrow down the cause, but I am currently wondering whether there is a Var <b>clojurescript</b> has the wrong value, or is being looked up in the wrong environment.</p>TANAL-107Latest t.a(.j) throws exception during analyze+eval of core.matchDefectMajorResolvedCompletedNicola MomettoAndy FingerhutSun, 21 Dec 2014 12:38:24 -0600Mon, 29 Dec 2014 15:19:25 -0600Mon, 29 Dec 2014 15:19:25 -060000<p>Fix for <a href="http://dev.clojure.org/jira/browse/TANAL-108" title="Latest t.a(.j) throws exception during analyze+eval of namespaces instaparse.gll"><del>TANAL-108</del></a> fixes this issue, too.</p>Global Rank[TANAL-108] Latest t.a(.j) throws exception during analyze+eval of namespaces instaparse.gllhttp://dev.clojure.org/jira/browse/TANAL-108
tools.analyzer<p>I haven't determined whether this and <a href="http://dev.clojure.org/jira/browse/TANAL-107" title="Latest t.a(.j) throws exception during analyze+eval of core.match"><del>TANAL-107</del></a> are related &#8211; they might be. This one seems to have fewer 'moving parts', i.e. fewer interdependent things causing it.</p>
<p>Reproduce steps:</p>
<p>Get latest Eastwood, checkout update-tanal branch, update to latest master, change to crucible/repos/instaparse-&lt;date&gt; directory:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">lein eastwood</pre>
</div></div>
<p>First few lines of exception message:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">== Eastwood 0.2.1-SNAPSHOT Clojure 1.5.1 JVM 1.7.0_45
== Linting instaparse.gll ==
Exception thrown during phase :analyze+eval of linting namespace instaparse.gll
Got exception with extra ex-data:
msg='No such <span class="code-keyword">var</span>: instaparse.gll'
(keys dat)=(:end-line :file :line :column :end-column :form)
(:form dat)=
instaparse.gll/pprint
ExceptionInfo No such <span class="code-keyword">var</span>: instaparse.gll
clojure.core/ex-info (core.clj:4327)
eastwood.copieddeps.dep2.clojure.tools.analyzer.passes.jvm.validate/eval2044/fn--2046 (validate.clj:43)
clojure.lang.MultiFn.invoke (MultiFn.java:227)
eastwood.copieddeps.dep2.clojure.tools.analyzer.passes.jvm.validate/validate (validate.clj:265)
clojure.lang.Var.invoke (Var.java:415)
eastwood.copieddeps.dep1.clojure.tools.analyzer.passes/compile-passes/fn--522/fn--527 (passes.clj:171)</pre>
</div></div>TANAL-108Latest t.a(.j) throws exception during analyze+eval of namespaces instaparse.gllDefectMajorClosedCompletedNicola MomettoAndy FingerhutSun, 21 Dec 2014 12:48:37 -0600Mon, 29 Dec 2014 13:41:56 -0600Mon, 29 Dec 2014 13:41:56 -060000<p>I've looked into this further, and with latest t.a(.j) I get an unbound Var when doing analyze+eval of a form like '(def a false)'. The AST is still a :def, but it has only a :meta child, no :init child.</p><p>Thanks, this was really helpful. <br/>
Fixed: <a href="https://github.com/clojure/tools.analyzer/commit/1c8693b30e8459ad3fbdb21871164ba82afb7b43">https://github.com/clojure/tools.analyzer/commit/1c8693b30e8459ad3fbdb21871164ba82afb7b43</a></p>
Global Rank[TANAL-106] wrong-tag indicated for (reify ns-alias/ProtoName ...)http://dev.clojure.org/jira/browse/TANAL-106
tools.analyzer<p>Not sure if this is a bug or not, but thought you could determine so pretty quickly. To reproduce, use Eastwood version 0.2.0 on the latest byte-streams library at <a href="https://github.com/ztellman/byte-streams">https://github.com/ztellman/byte-streams</a></p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">% lein eastwood '{:namespaces [<span class="code-object">byte</span>-streams]}'
== Eastwood 0.2.0 Clojure 1.7.0-alpha2 JVM 1.7.0_45
== Linting <span class="code-object">byte</span>-streams ==
eastwood-dbg: wrong-tag-from-analyzer: op=:reify name=<span class="code-keyword">null</span> wrong-tag-keys=#{:eastwood/o-tag :eastwood/tag} env={:end-line 305, :line 304, :column 3, :end-column 27, :file <span class="code-quote">"byte_streams.clj"</span>, :context :ctx/expr, :locals {}, :ns <span class="code-object">byte</span>-streams} ast=
{:op :reify,
:children [:methods],
:tag byte_streams$reify__9421,
[ ... many other parts of ast deleted ... ]
:o-tag byte_streams$reify__9421}</pre>
</div></div>
<p>This indicates that t.a.j's wrong-tag handler was called with first arg of :tag and :o-tag for the AST of the following reify form in byte-streams code at: <a href="https://github.com/ztellman/byte-streams/blob/master/src/byte_streams.clj#L303-L305">https://github.com/ztellman/byte-streams/blob/master/src/byte_streams.clj#L303-L305</a></p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(def ^{:doc <span class="code-quote">"Web-scale."</span>} dev-<span class="code-keyword">null</span>
(reify proto/ByteSink
(send-bytes! [_ _ _])))</pre>
</div></div>TANAL-106wrong-tag indicated for (reify ns-alias/ProtoName ...)DefectMinorClosedCompletedNicola MomettoAndy FingerhutSat, 6 Dec 2014 03:05:21 -0600Sat, 6 Dec 2014 07:11:16 -0600Sat, 6 Dec 2014 07:11:16 -060000<p>Fixed: <a href="https://github.com/clojure/tools.analyzer.jvm/commit/bc91babc6e14793742df4ca302c03acc0d0f4823">https://github.com/clojure/tools.analyzer.jvm/commit/bc91babc6e14793742df4ca302c03acc0d0f4823</a></p>Global Rank[TANAL-100] Fix method matcherhttp://dev.clojure.org/jira/browse/TANAL-100
tools.analyzer<p>places to fix:</p>
<p>jvm.utils/try-best-match<br/>
passes.jvm.annotate-methods<br/>
passes.jvm.validate/validate-call</p>TANAL-100Fix method matcherDefectBlockerOpenUnresolvedNicola MomettoNicola MomettoFri, 31 Oct 2014 10:14:06 -0500Sat, 15 Nov 2014 14:13:08 -060000<p>Some symptoms: <a href="http://dev.clojure.org/jira/browse/TANAL-105">http://dev.clojure.org/jira/browse/TANAL-105</a>, reflection warnings for Utils/equals analyzing core.rrb-vectors</p>Global Rank[TANAL-105] analyze+eval throws exception 'Ambiguous method signature for method: assoc' on data.int-maphttp://dev.clojure.org/jira/browse/TANAL-105
tools.analyzer<p>This may be a symptom of <a href="http://dev.clojure.org/jira/browse/TANAL-100" title="Fix method matcher">TANAL-100</a>, not sure. This behavior is with latest master Eastwood, and latest master data.int-map as of ticket creation time:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">== Linting clojure.data.<span class="code-object">int</span>-map ==
Exception thrown during phase :analyze+eval of linting namespace clojure.data.<span class="code-object">int</span>-map
Got exception with extra ex-data:
msg='Ambiguous method signature <span class="code-keyword">for</span> method: assoc'
(keys dat)=(:interfaces :method :file :end-column :params :matches :column :line :end-line :form)
(:form dat)=
(^{:line 269} assoc
^{:line 269} [^{:line 269} <span class="code-keyword">this</span> ^{:line 269} k ^{:line 269} v]
[ ... etc ... ]</pre>
</div></div>
<p>Eastwood latest is not quite tools.analyzer(.jvm) latest, but within about a week.</p>TANAL-105analyze+eval throws exception 'Ambiguous method signature for method: assoc' on data.int-mapDefectMinorClosedDeclinedNicola MomettoAndy FingerhutThu, 13 Nov 2014 20:23:12 -0600Sat, 15 Nov 2014 14:11:35 -0600Sat, 15 Nov 2014 14:11:35 -060000<p>Yeah I'm closing this as this will be fixed with the method matcher overhaul planned for <a href="http://dev.clojure.org/jira/browse/TANAL-100" title="Fix method matcher">TANAL-100</a></p>Global Rank[TANAL-102] catch is a legal fn namehttp://dev.clojure.org/jira/browse/TANAL-102
tools.analyzer<p>This one caught me by surprise:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(defn <span class="code-keyword">catch</span>
"Just to mess with tools.analyzer's assumptions. Not really, but
Zach Tellman seems to have a way of writing code that stretches
assumptions."
([x y]
(<span class="code-keyword">catch</span> x Throwable y))
([x y z]
[x y z]))</pre>
</div></div>
<p>Reduced test case from code in the wild from Manifold library: <a href="https://github.com/ztellman/manifold/blob/master/src/manifold/deferred.clj#L638-L651">https://github.com/ztellman/manifold/blob/master/src/manifold/deferred.clj#L638-L651</a></p>TANAL-102catch is a legal fn nameDefectMinorClosedCompletedNicola MomettoAndy FingerhutThu, 6 Nov 2014 21:19:46 -0600Tue, 11 Nov 2014 01:06:48 -0600Fri, 7 Nov 2014 06:36:51 -060000<p>Not sure if this should be considered a bug in tools.analyzer or Clojure compiler, but Clojure compiler accepts it.</p><p>Using catch as a var name is not a good idea as it's going to cause weird behaviour when interacting with "`" but I fixed this anyway.<br/>
<a href="https://github.com/clojure/tools.analyzer/commit/4df0489243254cbc5112e44907012dcf2d4bd613">https://github.com/clojure/tools.analyzer/commit/4df0489243254cbc5112e44907012dcf2d4bd613</a><br/>
<a href="https://github.com/clojure/tools.analyzer.jvm/commit/08b6a7632bd0a2bde30197b627571e7a2f8fb084">https://github.com/clojure/tools.analyzer.jvm/commit/08b6a7632bd0a2bde30197b627571e7a2f8fb084</a></p><p>Verified that I could analyze+eval forms like the one in the ticket description with the fix that was committed.</p>Global Rank[TANAL-103] tools.analyzer.jvm should always resolve `in-ns` and `ns` to the clojure.core varhttp://dev.clojure.org/jira/browse/TANAL-103
tools.analyzer<p><a href="https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L7057-L7060">https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L7057-L7060</a></p>TANAL-103tools.analyzer.jvm should always resolve `in-ns` and `ns` to the clojure.core varDefectMajorClosedCompletedNicola MomettoNicola MomettoFri, 7 Nov 2014 11:05:12 -0600Tue, 11 Nov 2014 01:05:55 -0600Mon, 10 Nov 2014 07:08:01 -060001<p>Fixed with <a href="https://github.com/clojure/tools.analyzer.jvm/compare/aa3b5c8696...629ab3461b">https://github.com/clojure/tools.analyzer.jvm/compare/aa3b5c8696...629ab3461b</a></p>
<p>With this commit t.a.jvm behaves like clojure would with the patch from <a href="http://dev.clojure.org/jira/browse/CLJ-1582">http://dev.clojure.org/jira/browse/CLJ-1582</a> applied.</p>
<p>Mimicking the current clojure behaviour would require much broader changes that I don't think it's worth doing. If <a href="http://dev.clojure.org/jira/browse/CLJ-1582" title="Overriding in-ns and ns is problematic ">CLJ-1582</a> gets declined, this will need to be reconsidered</p><p>Verified that with this change, I could analyze+eval all of the project manifold that led to this ticket being created, as reported here <a href="https://github.com/jonase/eastwood/issues/100">https://github.com/jonase/eastwood/issues/100</a></p>Global Rank[TANAL-104] analyze+eval throws exception for some test expressions in core.asynchttp://dev.clojure.org/jira/browse/TANAL-104
tools.analyzer<p>This is with latest master Eastwood, which is about 2 or 3 commits away from latest tools.analyzer(.jvm). If this is something you think you've fixed very recently, let me know and I'll update Eastwood to latest of those libs and try again.</p>
<p>Steps to reproduce:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">git clone https:<span class="code-comment">//github.com/clojure/core.async.git
</span>cd core.async
lein eastwood '{:namespaces [clojure.core.async.ioc-macros-test]}'</pre>
</div></div>
<p>Via binary search commenting-out expressions in that file, I've found that you can comment out all except either of these two expressions inside the deftest runner-tests, and the exception still occurs. I tried the second one by itself to confirm that it isn't because of the funky keywords that begin with digits.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(testing <span class="code-quote">"hash-map literals"</span>
(is (= {:1 1 :2 2 :3 3}
(runner {:1 (pause 1)
:2 (pause 2)
:3 (pause 3)}))))
(testing <span class="code-quote">"hash-set literals"</span>
(is (= #{1 2 3}
(runner #{(pause 1)
(pause 2)
(pause 3)}))))</pre>
</div></div>
<p>I haven't tried later tests by themselves, but there could be others.</p>TANAL-104analyze+eval throws exception for some test expressions in core.asyncDefectMajorClosedDeclinedNicola MomettoAndy FingerhutMon, 10 Nov 2014 14:28:38 -0600Mon, 10 Nov 2014 16:10:07 -0600Mon, 10 Nov 2014 15:10:02 -060001<p>I investigated this and it's a core.async bug, the -item-to-ssa multimethod isn't implemented for :with-meta nodes.</p>
<p>I informed tbaldridge on irc and updated the patch for <a href="http://dev.clojure.org/jira/browse/ASYNC-86">http://dev.clojure.org/jira/browse/ASYNC-86</a> to address this.</p><p>Out of curiosity, I tried running latest Eastwood on latest core.async plus your updated <a href="http://dev.clojure.org/jira/browse/ASYNC-86" title="Update tools.analyzer.jvm dep">ASYNC-86</a> patch, and there is no exception thrown any more. The results look good. Thanks.</p>Global Rank[TANAL-101] t.a.j fails to detect wrong tag on defn with destructured map arghttp://dev.clojure.org/jira/browse/TANAL-101
tools.analyzer<p>Latest t.a.j calls the wrong-tag handler (if supplied) for these functions:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(defn avlf4 ^LinkedList [coll] (java.util.LinkedList. coll))
(defn avlf4b ^LinkedList [&amp; coll] (java.util.LinkedList. coll))</pre>
</div></div>
<p>but not for this one:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(defn avlf4c ^LinkedList [&amp; {:keys [coll]}] (java.util.LinkedList. coll))</pre>
</div></div>TANAL-101t.a.j fails to detect wrong tag on defn with destructured map argDefectMinorClosedNot ReproducibleNicola MomettoAndy FingerhutFri, 31 Oct 2014 14:14:10 -0500Sat, 1 Nov 2014 21:11:46 -0500Fri, 31 Oct 2014 14:25:46 -050001<p>Now that I think about it, I haven't checked whether the last case above would trigger <a href="http://dev.clojure.org/jira/browse/CLJ-1232" title="Functions with non-qualified return type hints force import of hinted classes when called from other namespace">CLJ-1232</a> behavior or not.</p><p>I have now, and it does:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (<span class="code-keyword">import</span> '(java.util List))
java.util.List
user=&gt; (defn ll1 ^List [] (java.util.LinkedList.))
#'user/ll1
user=&gt; (.size (ll1))
0
user=&gt; (defn ll2 ^List [&amp; {:keys [coll]}] (java.util.LinkedList. coll))
#'user/ll2
user=&gt; (ll2 :coll [4 5 -1])
(4 5 -1)
user=&gt; (.size (ll2 :coll [4 5 -1]))
3
user=&gt; (in-ns 'user2)
#&lt;Namespace user2&gt;
user2=&gt; (clojure.core/refer 'user)
nil
user2=&gt; (.size (ll1))
CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: List, compiling:(/<span class="code-keyword">private</span>/<span class="code-keyword">var</span>/folders/v5/7hpqbpk51td3v351377gl6yw0000gn/T/form-init6319381494916415605.clj:1:1)
user2=&gt; (.size (ll2 :coll [4 5 -1]))
CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: List, compiling:(/<span class="code-keyword">private</span>/<span class="code-keyword">var</span>/folders/v5/7hpqbpk51td3v351377gl6yw0000gn/T/form-init6319381494916415605.clj:1:1)</pre>
</div></div><p>I've tried testing the last function with a dummy wrong-tag-handler that just prints a message when invoked and it looks like it is being invoked:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">clojure.tools.analyzer.jvm&gt; (<span class="code-keyword">do</span> (analyze '(defn avlf4 ^LinkedList [&amp; {:keys [coll]}] (java.util.LinkedList. coll))
(empty-env) {:passes-opts {:validate/wrong-tag-handler (ƒ [_ ast] (println <span class="code-quote">"invoked"</span>))}})
∅)
invoked
invoked
invoked
invoked
∅
clojure.tools.analyzer.jvm&gt;</pre>
</div></div><p>This is freaky weird, but in the latest Eastwood, which contains copies of the latest tools.analyzer and tools.analyzer.jvm, along with their dependencies, I can reproduce the bad behavior (no wrong-tag callbacks) by evaluating the same forms you did in your comment, except in the copied-and-renamed namespace eastwood.copieddeps.dep2.clojure.tools.analyzer.jvm</p>
<p>I'm still trying to determine why this difference in behavior exists. It might be because of one of the libraries on which tools.analyzer.jvm not being identical between the Eastwood project version and what you depend upon in tools.analyzer.jvm's project.clj. I'll let you know if I find out.</p><p>I can reproduce the bad behavior (no wrong-tag handler calls) by changing tools.analyzer.jvm's project.clj Clojure dependency to version 1.6.0 instead of 1.7.0-alpha3. Not sure why yet.</p><p>That makes sense, clojure 1.7.0-alpha3 has <a href="http://dev.clojure.org/jira/browse/CLJ-887">http://dev.clojure.org/jira/browse/CLJ-887</a> applied</p><p>Got it. So <a href="http://dev.clojure.org/jira/browse/CLJ-887" title="Error when calling primitive functions with destructuring in the arg vector"><del>CLJ-887</del></a> fix enables t.a.j and thus Eastwood to find more things to warn about than without that fix. Makes sense. Another example of how t.a.j is Clojure-IN-Clojure, and we depend upon the behavior of the latter Clojure.</p><p>Right.<br/>
On this regard I just want to point out that while t.a.j does depend on the clojure runtime, since the macroexpander AND the namespace system (<a href="https://github.com/clojure/tools.analyzer.jvm/commit/56848ef80183b01eefdd591c9c8bf1b3973e4bbd">https://github.com/clojure/tools.analyzer.jvm/commit/56848ef80183b01eefdd591c9c8bf1b3973e4bbd</a>) are pluggable, it is possible to shadow anything provided by default with the default runtime, if desiderable.</p>Global Rank[TANAL-99] Many new reflection warnings analyzing core.rrb-vector in latest t.a(.jvm) vs. 0.6.1http://dev.clojure.org/jira/browse/TANAL-99
tools.analyzer<p>Steps to reproduce:<br/>
pull latest Eastwood master</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">% cd crucible
% ./clone.sh (skip <span class="code-keyword">if</span> already pulled crucible repos)
% cd repos/core.rrb-vector-2014-02-14
% lein check
(no reflection warnings)
% lein eastwood '{:debug #{:compare-forms}}'
(many reflection warnings)</pre>
</div></div>
<p>The forms emitted by t.a(.jvm) version 0.6.1 did not cause Clojure 1.6.0 to produce these reflection warnings.</p>
<p>The :compare-forms debug option to Eastwood will cause forms-read.txt and forms-emitted.txt files to be written, where the latter may be helpful in determining what it is about the emitted forms that are causing Clojure to reflection-warn about them. Sorry I haven't tracked this further yet.</p>TANAL-99Many new reflection warnings analyzing core.rrb-vector in latest t.a(.jvm) vs. 0.6.1DefectMajorClosedDeclinedNicola MomettoAndy FingerhutThu, 30 Oct 2014 11:30:51 -0500Thu, 30 Oct 2014 15:27:06 -0500Thu, 30 Oct 2014 14:23:59 -050001<p>it looks like tools.reader might have a bugged implementation of syntax-quote as it's losing the metadata.</p><p>I'm closing this since it's a tools.reader bug rather than a tools.analyzer one.<br/>
I still have not decided what's the best way to solve this and TBH I'm still investigating whether this might be a clojure bug or not.<br/>
In the meantime reverting <a href="https://github.com/clojure/tools.reader/commit/bb744f4e5513cea57d85638c83bc193a2390f9b9">https://github.com/clojure/tools.reader/commit/bb744f4e5513cea57d85638c83bc193a2390f9b9</a> should fix it</p><p>Should I file a similar ticket for tools.reader ?</p><p>not necessary, I just pushed a fix </p><p>In case there is a need to refer to this in the future, the fix went in with this commit, shortly after tools.reader 0.8.10 was released: <a href="https://github.com/clojure/tools.reader/commit/7812e704ceef683970ff2e28fd099bafefe4eba0">https://github.com/clojure/tools.reader/commit/7812e704ceef683970ff2e28fd099bafefe4eba0</a></p>Global Rank[TANAL-98] Exception thrown for an extend-protocol formhttp://dev.clojure.org/jira/browse/TANAL-98
tools.analyzer<p>Steps to reproduce:</p>
<p>pull latest master of Eastwood, which now includes latest master of t.a(.jvm) as of this ticket being created.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">% cd crucible
% ./clone.sh (skip <span class="code-keyword">if</span> already pulled crucible repos)
% cd repos/cassaforte-2014-03-11
% lein eastwood '{:namespaces [clojurewerkz.cassaforte.conversion]}'
objc[5290]: <span class="code-object">Class</span> JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachines/jdk1.7.0_45.jdk/Contents/Home/bin/java and /Library/Java/JavaVirtualMachines/jdk1.7.0_45.jdk/Contents/Home/jre/lib/libinstrument.dylib. One of the two will be used. Which one is undefined.
== Eastwood 0.1.5-SNAPSHOT Clojure 1.5.1 JVM 1.7.0_45
== Linting clojurewerkz.cassaforte.conversion ==
Reflection warning, clojurewerkz/cassaforte/bytes.clj:56:3 - call to deserialize can't be resolved.
Exception thrown during phase :analyze+eval of linting namespace clojurewerkz.cassaforte.conversion
IllegalArgumentException No implementation of method: :typename of protocol: #'clojure.reflect/TypeReference found <span class="code-keyword">for</span> class: nil
clojure.core/-cache-protocol-fn (core_deftype.clj:541)
clojure.reflect/fn--9008/G--9003--9013 (reflect.clj:48)
clojure.reflect.JavaReflector (java.clj:169)
clojure.reflect/fn--8990/G--8986--8993 (reflect.clj:44)
clojure.reflect/fn--8990/G--8985--8997 (reflect.clj:44)
clojure.core/apply (core.clj:619)
clojure.core/partial/fn--4190 (core.clj:2396)
clojure.reflect/type-reflect (reflect.clj:100)
clojure.core/apply (core.clj:623)
eastwood.copieddeps.dep2.clojure.tools.analyzer.jvm.utils/type-reflect (utils.clj:22)
eastwood.copieddeps.dep2.clojure.tools.analyzer.jvm.utils/members* (utils.clj:246)
clojure.core/apply (core.clj:617)
[... most lines of stack trace omitted ...]
The following form was being processed during the exception:
(extend-protocol
DefinitionToMap
ResultSet
(to-map
[input]
(into [] (<span class="code-keyword">for</span> [row input] (into {} (<span class="code-keyword">for</span> [cd #] (let # #))))))
Host
(to-map
[host]
{:datacenter (.getDatacenter host),
:address (.getHostAddress (.getAddress host)),
:rack (.getRack host)}))
[... more lines omitted ...]</pre>
</div></div>TANAL-98Exception thrown for an extend-protocol formDefectMajorClosedCompletedNicola MomettoAndy FingerhutThu, 30 Oct 2014 11:21:48 -0500Thu, 30 Oct 2014 12:04:33 -0500Thu, 30 Oct 2014 12:04:33 -050000<p>Fixed:<br/>
<a href="https://github.com/clojure/tools.analyzer.jvm/commit/50c5d8dc83ae0254695ffd1dd86e84f64addc2b7">https://github.com/clojure/tools.analyzer.jvm/commit/50c5d8dc83ae0254695ffd1dd86e84f64addc2b7</a><br/>
<a href="https://github.com/clojure/tools.analyzer.jvm/commit/4e40ae890633c0220b3401f91eb07606099955e0">https://github.com/clojure/tools.analyzer.jvm/commit/4e40ae890633c0220b3401f91eb07606099955e0</a></p>Global Rank[TANAL-97] analyze+eval throws exception with Clojure 1.7.0-alpha3 but not 1.6.0 for project utf8http://dev.clojure.org/jira/browse/TANAL-97
tools.analyzer<p>I haven't tracked down what is going on here. I am using tools.analyzer(.jvm) 0.6.1 with the latest Eastwood where I've noticed this (but also saw it with the 0.2.x version of tools.analyzer(.jvm) used by Eastwood 0.1.4). I haven't yet checked whether the latest released tools.analyzer(.jvm) improves on this behavior.</p>
<p>This might also be a bug introduced in Clojure 1.7.0-alpha3 vs. 1.6.0.</p>
<p>To see the issue, get latest Eastwood, pull all of the crucible projects, or at least the one that gets renamed utf8-2013-11-15, and run these two commands after doing 'mvm install' on the latest Clojure master as of 1.7.0-alpha3. The last command below will use 1.7.0-master-SNAPSHOT of Clojure, so it needs to be installed in your ~/.m2 named as that, or change the project.clj file to name 1.7.0-alpha3 instead.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">% lein clean
% lein with-profile +1.6 eastwood
% lein clean
% leon with-profile +1.7 eastwood</pre>
</div></div>
<p>With the last command I see an exception like this:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">Exception thrown during phase :analyze+eval of linting namespace pjstadig.utf8
Got exception with extra ex-data:
msg='Could not resolve <span class="code-keyword">var</span>: Charset'
(keys dat)=(:end-line :line :column :end-column :file :<span class="code-keyword">var</span>)
ExceptionInfo Could not resolve <span class="code-keyword">var</span>: Charset
clojure.core/ex-info (core.clj:4566)
eastwood.copieddeps.dep2.clojure.tools.analyzer.passes.jvm.validate/eval1973/fn--1975 (validate.clj:29)
clojure.lang.MultiFn.invoke (MultiFn.java:229)</pre>
</div></div>TANAL-97analyze+eval throws exception with Clojure 1.7.0-alpha3 but not 1.6.0 for project utf8DefectMinorClosedDeclinedNicola MomettoAndy FingerhutTue, 28 Oct 2014 11:35:47 -0500Tue, 28 Oct 2014 17:18:18 -0500Tue, 28 Oct 2014 12:03:04 -050000<p>This appears to be caused because clojure 1.7.0-alpha3 fails to compile nio.core, thus the ns expression is not evaluated.</p>
<p>This is a regression introduced with clojure 1.7.0-alpha2, I'm investigating the cause and will open a CLJ ticket</p><p>turns out it's not even a clojure reggression, it's a bug in the last released version of nio that has been fixed in the SNAPSHOT version: <a href="https://github.com/pjstadig/nio/issues/4">https://github.com/pjstadig/nio/issues/4</a></p>
<p>clojure &lt;=1.7.0-alpha2 silently ignored this bug but commit <a href="https://github.com/clojure/clojure/commit/85169b785c5dd59e89c0bd12600eebe5f6172874">https://github.com/clojure/clojure/commit/85169b785c5dd59e89c0bd12600eebe5f6172874</a> had the side effect of exposing the bug</p><p>Thanks for tracking that down! (inc Bronsa) <img class="emoticon" src="http://dev.clojure.org/jira/images/icons/emoticons/smile.gif" height="20" width="20" align="absmiddle" alt="" border="0"/></p><p>And this helped me discover that although I tried to stop Eastwood's linking at the point that analyze+eval returns an AST indicating that eval threw an exception, I was only checking the top-level AST. I should have been checking all sub-ASTs of top-level do forms, and do forms nested inside those, etc. Soon Eastwood will stop earlier, closer to the real problem in this case.</p>Global Rank[TANAL-85] enhance validations in t.a.jshttp://dev.clojure.org/jira/browse/TANAL-85
tools.analyzer<p>This includes:</p>
<ul>
<li>validating :new nodes</li>
<li>validating protocol/types usage</li>
<li>better error messages on non-valid 'ns forms</li>
</ul>
TANAL-85enhance validations in t.a.jsTaskCriticalOpenUnresolvedNicola MomettoNicola MomettoSun, 10 Aug 2014 15:12:18 -0500Fri, 17 Oct 2014 12:49:40 -050000Global Rank[TANAL-96] Change munging scheme to match the one introduced with CLJ-1330http://dev.clojure.org/jira/browse/TANAL-96
tools.analyzerTANAL-96Change munging scheme to match the one introduced with CLJ-1330EnhancementMajorClosedDeclinedNicola MomettoNicola MomettoMon, 13 Oct 2014 04:48:24 -0500Mon, 13 Oct 2014 04:48:35 -0500Mon, 13 Oct 2014 04:48:35 -050000Global Rank[TANAL-95] java.lang.IllegalAccessError: butlast+last does not exist when (use 'clojure.tools.analyzer.jvm) with dependencies [org.clojure/tools.analyzer.jvm "0.6.1-SNAPSHOT"] and [org.clojure/core.typed "0.2.72"]http://dev.clojure.org/jira/browse/TANAL-95
tools.analyzer<p>With the above project.clj, lauch a REPL</p>
<p>(require 'clojure.tools.analyzer.jvm)<br/>
;-&gt; CompilerException java.lang.IllegalAccessError: butlast+last does not exist, compiling:(clojure/tools/analyzer/jvm.clj:1:1)</p>
<p>This exception does not occur if either the version of tools.analyzer.jvm is dropped back to 0.6.0 or if the dependency on core.typed is removed.</p>project.clj:
<br/>
<br/>
(defproject bug-report &quot;0.1.0-SNAPSHOT&quot;
<br/>
&nbsp;&nbsp;:repositories {&quot;sonatype-oss-public&quot; &quot;<a href="https://oss.sonatype.org/content/groups/public/">https://oss.sonatype.org/content/groups/public/</a>&quot;}
<br/>
&nbsp;&nbsp;:dependencies [[org.clojure/clojure &quot;1.6.0&quot;]
<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[org.clojure/core.typed &quot;0.2.72&quot;]
<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[org.clojure/tools.analyzer.jvm &quot;0.6.1-SNAPSHOT&quot;]])
<br/>
TANAL-95java.lang.IllegalAccessError: butlast+last does not exist when (use 'clojure.tools.analyzer.jvm) with dependencies [org.clojure/tools.analyzer.jvm "0.6.1-SNAPSHOT"] and [org.clojure/core.typed "0.2.72"]DefectMajorClosedNot ReproducibleNicola MomettoRichard DaviesSat, 11 Oct 2014 03:58:05 -0500Sat, 11 Oct 2014 05:08:44 -0500Sat, 11 Oct 2014 05:08:44 -050000<p>I could not reproduce with a clean repo and nothing between 0.6.1-SNAPSHOT and 0.6.0 hash changed wrt butlast+last.<br/>
Make sure you don't have any stale dependency by cleaning your target/ and eventually ~/.m2 directory</p>Global Rank[TANAL-87] Move some passes to the emitterhttp://dev.clojure.org/jira/browse/TANAL-87
tools.analyzer<p>Don't belong in tools.analyzer.jvm:</p>
<ul>
<li>annotate-class-id</li>
<li>annotate-internal-name</li>
</ul>
<p>Require some though</p>
<ul>
<li>classify-invoke</li>
<li>box/ensure-tag</li>
<li>collect</li>
<li>collect-closed-overs</li>
<li>clear-locals</li>
</ul>
TANAL-87Move some passes to the emitterTaskMajorClosedCompletedNicola MomettoNicola MomettoSat, 6 Sep 2014 23:28:00 -0500Fri, 10 Oct 2014 11:52:46 -0500Fri, 10 Oct 2014 11:52:46 -050000Global Rank[TANAL-94] emit-form does not qualify def symbols when using :qualified-symbols optionhttp://dev.clojure.org/jira/browse/TANAL-94
tools.analyzer<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(ns bug
(:require [clojure.tools.analyzer.jvm :as j])
(:require [clojure.tools.analyzer.passes.jvm.emit-form :as e]))
(def the-original-code '((def x 1) (def y x)))
(def the-ast (j/analyze the-original-code))
(def the-unqualified-code (e/emit-form (j/analyze the-original-code)))
(def the-qualified-code (e/emit-form (j/analyze the-original-code) #{:qualified-symbols}))</pre>
</div></div>
<p>the-unqualified-code<br/>
;((def x 1) (def y x))</p>
<p>the-qualified-code<br/>
;((def x 1) (def y bug/x))</p>
<p>In the second example, x and y are only qualified where it is used, not where they are declared.</p>
<p>Desired output:<br/>
the-qualified-code<br/>
;((def bug/x 1) (def bug/y bug/x))</p>
AllTANAL-94emit-form does not qualify def symbols when using :qualified-symbols optionDefectMinorClosedCompletedNicola MomettoRichard DaviesThu, 9 Oct 2014 18:22:43 -0500Fri, 10 Oct 2014 08:52:18 -0500Fri, 10 Oct 2014 08:52:18 -050000<p>I'm not sure about considering this a bug.<br/>
While it is true that (def foo/bar 1) is a valid form (when foo is &#42;ns&#42;), def <b>always</b> interns vars in the current ns &#42;ns&#42; so there is no ambiguity wrt what var bar in (def bar 1) will refer to.</p>
<p>Do you have a specific use case where emitting (def foo/bar 1) is ok but (def bar 1) is problematic?</p><p>Hi Nicola,</p>
<p>Here's my use case:</p>
<p>I am currently customising the "-emit-form" defmethods to give me a mapping of <span class="error">&#91;original-form -&gt; qualified-symbol&#93;</span> or <span class="error">&#91;original-form -&gt; hygenic-local&#93;</span> to build a graph data structure (which I want to visualise) of my code. (I'm also interested in tracking how the code is transformed by macros as I'd like to be able to display either the original code or the macro-transformed code.)</p>
<p>I'm not sure using the emitter is the best approach but it's easier for me to work with the emitter than to write something that parses the AST from scratch, especially as I want the all the emitted code to be regular Clojure except for the parts that give me the <span class="error">&#91;original-form -&gt; hygenic-local/qualified-symbol&#93;</span> mapping.</p>
<p>This is a quick summary of what I'm doing:</p>
<p>First I attach a unique id to the metadata of each form so that I can track forms from the original code to whatever it has been transformed to by any macros:</p>
<p>(postwalk (fn <span class="error">&#91;x&#93;</span> (if (instance? clojure.lang.IObj x) (with-meta x {:id (swap! c inc)}) x)) form)</p>
<p>Then I modify any emitter defmethods to insert special nodes where there is a form that need to be made hygenic:</p>
<p>(defrecord Out <span class="error">&#91;emit form&#93;</span>)</p>
<p>(defmethod e/-emit-form :default<br/>
<span class="error">&#91;ast opts&#93;</span><br/>
(let [e (default/-emit-form ast opts) r (first (:raw-forms ast)) f (:form ast) o (Out. e f) i (:id (meta f))<br/>
o1 (if r (assoc o :raw r) o)<br/>
o2 (if i (assoc o1 :id i) o1)]<br/>
o2<br/>
))</p>
<p>So it would be nice if this approach also worked with all var symbols. I can work around it given that it's quite easy to figure out what namespace a def'ed symbol is in as you say. However, in favour of supporting this fix, it would make the :qualified-symbols emitter option more true to its description and as a consequence, it would make the emitter easier to tweak. Last argument in favour is that if you turn the :qualified-symbols on and then pass the emitted code back, the <b>ns</b> information is lost.</p>
<p>When I've added a (defmethod e/-emit-form :def ....) it doesn't seem to descend to the symbol in the def although I can of course pull the namespace info from the AST so it's all possible but it felt like a bit of a hack to get the mapping for the def symbol working.</p>
<p>BTW, if there's a simpler/cleaner way to do what I'm trying to do, I'm open to suggestions <img class="emoticon" src="http://dev.clojure.org/jira/images/icons/emoticons/smile.gif" height="20" width="20" align="absmiddle" alt="" border="0"/></p>
<p>Thanks,<br/>
Richard</p><p>Fixed: <a href="https://github.com/clojure/tools.analyzer.jvm/commit/9315dc482cd90a6a76d3ad7e9be739ee0b16744f">https://github.com/clojure/tools.analyzer.jvm/commit/9315dc482cd90a6a76d3ad7e9be739ee0b16744f</a></p>Global Rank[TANAL-93] Incorrect earmuff warningshttp://dev.clojure.org/jira/browse/TANAL-93
tools.analyzer<p>I see non-dynamic var earmuff warnings for vars that do have :dynamic true in their metadata, like so:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(def ^:dynamic *smile-factory* nil)</pre>
</div></div>
<p>I think this might be fixable with the following change:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">diff --git a/src/eastwood/copieddeps/dep1/clojure/tools/analyzer/passes/warn_earmuff.clj b/src/eastwood/copieddeps/dep1/clojure/tools/analyzer/passes/warn_earmuff.clj
index ddb1488..ecf587d 100644
--- a/src/eastwood/copieddeps/dep1/clojure/tools/analyzer/passes/warn_earmuff.clj
+++ b/src/eastwood/copieddeps/dep1/clojure/tools/analyzer/passes/warn_earmuff.clj
@@ -19,7 +19,7 @@
(&gt; (count name) 2) ;; Allow * and ** as non-dynamic names
(.startsWith name <span class="code-quote">"*"</span>)
(.endsWith name <span class="code-quote">"*"</span>)
- (not (dynamic? (:<span class="code-keyword">var</span> ast))))
+ (not (dynamic? (:<span class="code-keyword">var</span> ast) (-&gt; ast :meta :val))))
(binding [*out* *err*]
(println <span class="code-quote">"Warning:"</span> name <span class="code-quote">"not declared dynamic and thus is not dynamically rebindable,"</span>
<span class="code-quote">"but its name suggests otherwise."</span></pre>
</div></div>TANAL-93Incorrect earmuff warningsDefectMajorClosedCompletedNicola MomettoAndy FingerhutThu, 25 Sep 2014 13:18:04 -0500Thu, 25 Sep 2014 13:24:36 -0500Thu, 25 Sep 2014 13:24:36 -050000<p>Fixed: <a href="https://github.com/clojure/tools.analyzer/commit/3af99e2a8055c22609de2d64b1e0009e949c252d">https://github.com/clojure/tools.analyzer/commit/3af99e2a8055c22609de2d64b1e0009e949c252d</a></p>Global Rank[TANAL-92] Latest t.a.j throws exception on defrecordhttp://dev.clojure.org/jira/browse/TANAL-92
tools.analyzer<p>I get an exception thrown when calling analyze+eval on the last form of this input file:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(ns testcases.tanal-9)
(defrecord RecordTest [a b])</pre>
</div></div>
<p>Stack trace (from unchecked-in working copy of Eastwood with latest t.a.j):</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">Exception in thread <span class="code-quote">"main"</span> java.lang.VerifyError: (class: testcases/tanal_9$reify__5886, method: create signature: (Lclojure/lang/IPersistentMap;)Ltestcases/tanal_9$reify__5886;) Expecting to find unitialized object on stack, compiling:(/<span class="code-keyword">private</span>/<span class="code-keyword">var</span>/folders/sf/wkqqkhmj1wb4322ttmrx8cl00000gn/T/form-init8013061043522900563.clj:1:142)
at clojure.lang.<span class="code-object">Compiler</span>.load(<span class="code-object">Compiler</span>.java:7142)
at clojure.lang.<span class="code-object">Compiler</span>.loadFile(<span class="code-object">Compiler</span>.java:7086)
at clojure.main$load_script.invoke(main.clj:274)
at clojure.main$init_opt.invoke(main.clj:279)
at clojure.main$initialize.invoke(main.clj:307)
at clojure.main$null_opt.invoke(main.clj:342)
at clojure.main$main.doInvoke(main.clj:420)
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.VerifyError: (class: testcases/tanal_9$reify__5886, method: create signature: (Lclojure/lang/IPersistentMap;)Ltestcases/tanal_9$reify__5886;) Expecting to find unitialized object on stack
at java.lang.<span class="code-object">Class</span>.forName0(Native Method)
at java.lang.<span class="code-object">Class</span>.forName(<span class="code-object">Class</span>.java:190)
at testcases.tanal_9$eval5888.invoke(form-init8013061043522900563.clj:1)
at clojure.lang.<span class="code-object">Compiler</span>.eval(<span class="code-object">Compiler</span>.java:6703)
at clojure.lang.<span class="code-object">Compiler</span>.eval(<span class="code-object">Compiler</span>.java:6666)
at clojure.core$eval.invoke(core.clj:2927)
at eastwood.copieddeps.dep2.clojure.tools.analyzer.jvm$_deftype.invoke(jvm.clj:300)
at eastwood.copieddeps.dep2.clojure.tools.analyzer.jvm$eval3902$fn__3904.invoke(jvm.clj:312)
at clojure.lang.MultiFn.invoke(MultiFn.java:231)
at eastwood.copieddeps.dep1.clojure.tools.analyzer$eval364$fn__365.invoke(analyzer.clj:285)
at clojure.lang.MultiFn.invoke(MultiFn.java:236)
at eastwood.copieddeps.dep1.clojure.tools.analyzer$eval287$fn__288.invoke(analyzer.clj:68)
at clojure.lang.MultiFn.invoke(MultiFn.java:231)
at eastwood.copieddeps.dep1.clojure.tools.analyzer$eval364$fn__365.invoke(analyzer.clj:286)
at clojure.lang.MultiFn.invoke(MultiFn.java:236)
at eastwood.copieddeps.dep1.clojure.tools.analyzer$eval287$fn__288.invoke(analyzer.clj:68)
at clojure.lang.MultiFn.invoke(MultiFn.java:231)
at eastwood.copieddeps.dep1.clojure.tools.analyzer$analyze.invoke(analyzer.clj:123)
at eastwood.copieddeps.dep2.clojure.tools.analyzer.jvm$eval3924$fn__3926$fn__3933.invoke(jvm.clj:364)
at clojure.core.protocols$fn__6074.invoke(protocols.clj:79)
at clojure.core.protocols$fn__6031$G__6026__6044.invoke(protocols.clj:13)
at clojure.core$reduce.invoke(core.clj:6289)
at eastwood.copieddeps.dep2.clojure.tools.analyzer.jvm$eval3924$fn__3926.invoke(jvm.clj:362)
at clojure.lang.MultiFn.invoke(MultiFn.java:231)
at eastwood.copieddeps.dep1.clojure.tools.analyzer$eval364$fn__365.invoke(analyzer.clj:285)
at clojure.lang.MultiFn.invoke(MultiFn.java:236)
at eastwood.copieddeps.dep1.clojure.tools.analyzer$eval287$fn__288.invoke(analyzer.clj:68)
at clojure.lang.MultiFn.invoke(MultiFn.java:231)
at eastwood.copieddeps.dep1.clojure.tools.analyzer$eval368$fn__370.invoke(analyzer.clj:297)
at clojure.lang.MultiFn.invoke(MultiFn.java:231)
at eastwood.copieddeps.dep2.clojure.tools.analyzer.jvm$eval3810$fn__3811.invoke(jvm.clj:63)
at clojure.lang.MultiFn.invoke(MultiFn.java:231)
at eastwood.copieddeps.dep1.clojure.tools.analyzer$analyze_body.invoke(analyzer.clj:368)
at eastwood.copieddeps.dep1.clojure.tools.analyzer$analyze_let.invoke(analyzer.clj:522)
at eastwood.copieddeps.dep1.clojure.tools.analyzer$eval464$fn__465.invoke(analyzer.clj:532)
at clojure.lang.MultiFn.invoke(MultiFn.java:231)
at eastwood.copieddeps.dep2.clojure.tools.analyzer.jvm$eval3810$fn__3811.invoke(jvm.clj:63)
at clojure.lang.MultiFn.invoke(MultiFn.java:231)
at eastwood.copieddeps.dep1.clojure.tools.analyzer$eval364$fn__365.invoke(analyzer.clj:285)
at clojure.lang.MultiFn.invoke(MultiFn.java:236)
at eastwood.copieddeps.dep1.clojure.tools.analyzer$eval287$fn__288.invoke(analyzer.clj:68)
at clojure.lang.MultiFn.invoke(MultiFn.java:231)
at eastwood.copieddeps.dep1.clojure.tools.analyzer$eval364$fn__365.invoke(analyzer.clj:286)
at clojure.lang.MultiFn.invoke(MultiFn.java:236)
at eastwood.copieddeps.dep1.clojure.tools.analyzer$eval287$fn__288.invoke(analyzer.clj:68)
at clojure.lang.MultiFn.invoke(MultiFn.java:231)
at eastwood.copieddeps.dep1.clojure.tools.analyzer$eval364$fn__365.invoke(analyzer.clj:286)
at clojure.lang.MultiFn.invoke(MultiFn.java:236)
at eastwood.copieddeps.dep1.clojure.tools.analyzer$eval287$fn__288.invoke(analyzer.clj:68)
at clojure.lang.MultiFn.invoke(MultiFn.java:231)
at eastwood.copieddeps.dep1.clojure.tools.analyzer$eval368$fn__370.invoke(analyzer.clj:297)
at clojure.lang.MultiFn.invoke(MultiFn.java:231)
at eastwood.copieddeps.dep2.clojure.tools.analyzer.jvm$eval3810$fn__3811.invoke(jvm.clj:63)
at clojure.lang.MultiFn.invoke(MultiFn.java:231)
at eastwood.copieddeps.dep1.clojure.tools.analyzer$analyze_body.invoke(analyzer.clj:368)
at eastwood.copieddeps.dep1.clojure.tools.analyzer$analyze_let.invoke(analyzer.clj:522)
at eastwood.copieddeps.dep1.clojure.tools.analyzer$eval464$fn__465.invoke(analyzer.clj:532)
at clojure.lang.MultiFn.invoke(MultiFn.java:231)
at eastwood.copieddeps.dep2.clojure.tools.analyzer.jvm$eval3810$fn__3811.invoke(jvm.clj:63)
at clojure.lang.MultiFn.invoke(MultiFn.java:231)
at eastwood.copieddeps.dep1.clojure.tools.analyzer$eval364$fn__365.invoke(analyzer.clj:285)
at clojure.lang.MultiFn.invoke(MultiFn.java:236)
at eastwood.copieddeps.dep1.clojure.tools.analyzer$eval287$fn__288.invoke(analyzer.clj:68)
at clojure.lang.MultiFn.invoke(MultiFn.java:231)
at eastwood.copieddeps.dep1.clojure.tools.analyzer$eval364$fn__365.invoke(analyzer.clj:286)
at clojure.lang.MultiFn.invoke(MultiFn.java:236)
at eastwood.copieddeps.dep1.clojure.tools.analyzer$eval287$fn__288.invoke(analyzer.clj:68)
at clojure.lang.MultiFn.invoke(MultiFn.java:231)
at eastwood.copieddeps.dep1.clojure.tools.analyzer$eval368$fn__370.invoke(analyzer.clj:297)
at clojure.lang.MultiFn.invoke(MultiFn.java:231)
at eastwood.copieddeps.dep2.clojure.tools.analyzer.jvm$eval3810$fn__3811.invoke(jvm.clj:63)
at clojure.lang.MultiFn.invoke(MultiFn.java:231)
at eastwood.copieddeps.dep1.clojure.tools.analyzer$analyze_body.invoke(analyzer.clj:368)
at eastwood.copieddeps.dep1.clojure.tools.analyzer$analyze_fn_method.invoke(analyzer.clj:608)
at eastwood.copieddeps.dep2.clojure.tools.analyzer.jvm$analyze_method_impls.invoke(jvm.clj:281)
at eastwood.copieddeps.dep2.clojure.tools.analyzer.jvm$eval3911$fn__3913$fn__3920.invoke(jvm.clj:342)
at clojure.core$mapv$fn__6311.invoke(core.clj:6353)
at clojure.core.protocols$fn__6086.invoke(protocols.clj:143)
at clojure.core.protocols$fn__6057$G__6052__6066.invoke(protocols.clj:19)
at clojure.core.protocols$seq_reduce.invoke(protocols.clj:31)
at clojure.core.protocols$fn__6080.invoke(protocols.clj:48)
at clojure.core.protocols$fn__6031$G__6026__6044.invoke(protocols.clj:13)
at clojure.core$reduce.invoke(core.clj:6289)
at clojure.core$mapv.invoke(core.clj:6353)
at eastwood.copieddeps.dep2.clojure.tools.analyzer.jvm$eval3911$fn__3913.invoke(jvm.clj:342)
at clojure.lang.MultiFn.invoke(MultiFn.java:231)
at eastwood.copieddeps.dep1.clojure.tools.analyzer$eval364$fn__365.invoke(analyzer.clj:285)
at clojure.lang.MultiFn.invoke(MultiFn.java:236)
at eastwood.copieddeps.dep1.clojure.tools.analyzer$eval287$fn__288.invoke(analyzer.clj:68)
at clojure.lang.MultiFn.invoke(MultiFn.java:231)
at eastwood.copieddeps.dep1.clojure.tools.analyzer$analyze_in_env$fn__322.invoke(analyzer.clj:135)
at clojure.core$mapv$fn__6311.invoke(core.clj:6353)
at clojure.lang.ArrayChunk.reduce(ArrayChunk.java:63)
at clojure.core.protocols$fn__6093.invoke(protocols.clj:98)
at clojure.core.protocols$fn__6057$G__6052__6066.invoke(protocols.clj:19)
at clojure.core.protocols$seq_reduce.invoke(protocols.clj:31)
at clojure.core.protocols$fn__6076.invoke(protocols.clj:60)
at clojure.core.protocols$fn__6031$G__6026__6044.invoke(protocols.clj:13)
at clojure.core$reduce.invoke(core.clj:6289)
at clojure.core$mapv.invoke(core.clj:6353)
at eastwood.copieddeps.dep1.clojure.tools.analyzer$eval368$fn__370.invoke(analyzer.clj:296)
at clojure.lang.MultiFn.invoke(MultiFn.java:231)
at eastwood.copieddeps.dep2.clojure.tools.analyzer.jvm$eval3810$fn__3811.invoke(jvm.clj:63)
at clojure.lang.MultiFn.invoke(MultiFn.java:231)
at eastwood.copieddeps.dep1.clojure.tools.analyzer$analyze_body.invoke(analyzer.clj:368)
at eastwood.copieddeps.dep1.clojure.tools.analyzer$analyze_let.invoke(analyzer.clj:522)
at eastwood.copieddeps.dep1.clojure.tools.analyzer$eval464$fn__465.invoke(analyzer.clj:532)
at clojure.lang.MultiFn.invoke(MultiFn.java:231)
at eastwood.copieddeps.dep2.clojure.tools.analyzer.jvm$eval3810$fn__3811.invoke(jvm.clj:63)
at clojure.lang.MultiFn.invoke(MultiFn.java:231)
at eastwood.copieddeps.dep1.clojure.tools.analyzer$eval364$fn__365.invoke(analyzer.clj:285)
at clojure.lang.MultiFn.invoke(MultiFn.java:236)
at eastwood.copieddeps.dep1.clojure.tools.analyzer$eval287$fn__288.invoke(analyzer.clj:68)
at clojure.lang.MultiFn.invoke(MultiFn.java:231)
at eastwood.copieddeps.dep1.clojure.tools.analyzer$analyze.invoke(analyzer.clj:123)
at eastwood.copieddeps.dep2.clojure.tools.analyzer.jvm$analyze$fn__3947.invoke(jvm.clj:474)
at clojure.lang.AFn.applyToHelper(AFn.java:152)
at clojure.lang.AFn.applyTo(AFn.java:144)
at clojure.core$apply.invoke(core.clj:624)
at clojure.core$with_bindings_STAR_.doInvoke(core.clj:1862)
at clojure.lang.RestFn.invoke(RestFn.java:425)
at eastwood.copieddeps.dep2.clojure.tools.analyzer.jvm$analyze.invoke(jvm.clj:470)
at eastwood.copieddeps.dep2.clojure.tools.analyzer.jvm$analyze_PLUS_eval.invoke(jvm.clj:516)
at eastwood.analyze_ns$analyze_file$fn__4284.invoke(analyze_ns.clj:260)
at eastwood.analyze_ns$analyze_file.doInvoke(analyze_ns.clj:258)
at clojure.lang.RestFn.invoke(RestFn.java:486)
at eastwood.analyze_ns$analyze_ns.doInvoke(analyze_ns.clj:302)
at clojure.lang.RestFn.invoke(RestFn.java:439)
at eastwood.core$lint_ns.invoke(core.clj:325)
at eastwood.core$run_eastwood$fn__5834.invoke(core.clj:584)
at eastwood.core$run_eastwood.invoke(core.clj:583)
at clojure.lang.Var.invoke(Var.java:379)
at eastwood.versioncheck$run_eastwood.invoke(versioncheck.clj:15)
at user$eval21.invoke(form-init8013061043522900563.clj:1)
at clojure.lang.<span class="code-object">Compiler</span>.eval(<span class="code-object">Compiler</span>.java:6703)
at clojure.lang.<span class="code-object">Compiler</span>.eval(<span class="code-object">Compiler</span>.java:6693)
at clojure.lang.<span class="code-object">Compiler</span>.load(<span class="code-object">Compiler</span>.java:7130)
... 11 more</pre>
</div></div>TANAL-92Latest t.a.j throws exception on defrecordDefectMajorClosedCompletedNicola MomettoAndy FingerhutThu, 25 Sep 2014 11:40:50 -0500Thu, 25 Sep 2014 11:50:41 -0500Thu, 25 Sep 2014 11:50:41 -050000<p>This was caused by the last commit on t.a.jvm, I had the erraneous impression that __meta should be visible from inside reifies, but it looks like I was wrong.<br/>
Reverted the commit: <a href="https://github.com/clojure/tools.analyzer.jvm/commit/2f3499280dc2bb62d6f291738ecc04f91b0d7dbb">https://github.com/clojure/tools.analyzer.jvm/commit/2f3499280dc2bb62d6f291738ecc04f91b0d7dbb</a></p>Global Rank[TANAL-91] analyze+eval throws exception about wrong tag when it should nothttp://dev.clojure.org/jira/browse/TANAL-91
tools.analyzer<p>At least, it seems to me that it does so. I'll let you decide, and decline this ticket if I'm wrong somewhere here, but I'd be curious to know how.</p>
<p>All three of the def forms in the sample REPL session below cause tools.analyzer(.jvm)'s latest versions to throw an exception with a "Wrong tag" message. The first two I agree with, but the last seems like it is correct code that should not throw such an exception. Clojure 1.6.0 (and maybe older versions) does not give any reflection warnings when the Var l4 is used as an argument in Java interop.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (clojure-version)
<span class="code-quote">"1.6.0"</span>
user=&gt; (set! *warn-on-reflection* <span class="code-keyword">true</span>)
<span class="code-keyword">true</span>
user=&gt; (def ^<span class="code-object">long</span> l2 -2)
#'user/l2
user=&gt; (<span class="code-object">Math</span>/abs l2)
CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: clojure.core$<span class="code-object">long</span>@4201beb6, compiling:(NO_SOURCE_PATH:5:1)
user=&gt; (def ^{:tag <span class="code-object">long</span>} l3 -2)
#'user/l3
user=&gt; (<span class="code-object">Math</span>/abs l3)
CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: clojure.core$<span class="code-object">long</span>@4201beb6, compiling:(NO_SOURCE_PATH:7:1)
user=&gt; (def ^{:tag '<span class="code-object">long</span>} l4 -2)
#'user/l4
user=&gt; (<span class="code-object">Math</span>/abs l4)
2</pre>
</div></div>TANAL-91analyze+eval throws exception about wrong tag when it should notDefectMinorClosedCompletedNicola MomettoAndy FingerhutWed, 24 Sep 2014 14:14:54 -0500Thu, 25 Sep 2014 02:42:10 -0500Thu, 25 Sep 2014 02:42:10 -050001<p>fixed: <a href="https://github.com/clojure/tools.analyzer.jvm/commit/be662dfa604eea1282ded033f2dab09bbaf026a8">https://github.com/clojure/tools.analyzer.jvm/commit/be662dfa604eea1282ded033f2dab09bbaf026a8</a></p>Global Rank[TANAL-90] Exception thrown attempting to analyze :arglists containing keywords or booleanshttp://dev.clojure.org/jira/browse/TANAL-90
tools.analyzer<p>Steps to reproduce:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java"># git clone/pull latest version of Eastwood as of Sep 21 2014
# It should include version 0.6.0 of both tools.analyzer(.jvm), including fix <span class="code-keyword">for</span> TANAL-88 and TANAL-89
git checkout update-tanal
lein install
# Edit ~/.lein/profiles.clj to have <span class="code-keyword">this</span> in {:user {:plugins [ ... ]}} vector: [jonase/eastwood <span class="code-quote">"0.1.5-SNAPSHOT"</span>]
cd crucible
# This step is unnecessary <span class="code-keyword">if</span> you have done it before
./clone.sh
cd repos/java.jdbc-2014-03-07
lein with-profile +1.6 eastwood</pre>
</div></div>
<p>Exception I see looks like this:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">Exception thrown during phase :analyze+eval of linting namespace clojure.java.jdbc
ClassCastException clojure.lang.Keyword cannot be <span class="code-keyword">cast</span> to clojure.lang.IObj
clojure.core/with-meta (core.clj:214)
clojure.core/vary-meta (core.clj:640)
eastwood.copieddeps.dep2.clojure.tools.analyzer.jvm/qualify-argvec/fix-tag--3837 (jvm.clj:185)
clojure.core/mapv/fn--6311 (core.clj:6353)
[ ... more stack trace lines omitted ... ]</pre>
</div></div>
<p>The exception goes away if I delete the :arglists of the function query, which is the form being analyzed when the exception occurs. It also goes away if I change the keywords and booleans in the :arglists to symbols, or remove them entirely (done not as a proposed change to java.jdbc, but to do a little bit of investigation to see what causes the exception).</p>TANAL-90Exception thrown attempting to analyze :arglists containing keywords or booleansDefectMajorClosedCompletedNicola MomettoAndy FingerhutSun, 21 Sep 2014 13:36:34 -0500Sun, 21 Sep 2014 14:26:40 -0500Sun, 21 Sep 2014 14:26:40 -050001<p>Fixed: <a href="https://github.com/clojure/tools.analyzer.jvm/commit/698096cebc271d7b5f44eefe4e5b79ebde9df8e2">https://github.com/clojure/tools.analyzer.jvm/commit/698096cebc271d7b5f44eefe4e5b79ebde9df8e2</a></p>Global Rank[TANAL-89] analyze+eval throws exception with message 'Cannot set! non-assignable target' for code that shouldn'thttp://dev.clojure.org/jira/browse/TANAL-89
tools.analyzer<p>Steps to reproduce:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java"># git clone/pull latest version of Eastwood as of Sep 20 2014
# It should include version 0.6.0 of both tools.analyzer(.jvm), including fix <span class="code-keyword">for</span> TANAL-88
git checkout update-tanal
lein install
# Edit ~/.lein/profiles.clj to have <span class="code-keyword">this</span> in {:user {:plugins [ ... ]}} vector: [jonase/eastwood <span class="code-quote">"0.1.5-SNAPSHOT"</span>]
cd crucible
# This step is unnecessary <span class="code-keyword">if</span> you have done it before
./clone.sh
cd repos/tools.reader-2014-03-05
lein with-profile +1.6 eastwood</pre>
</div></div>
<p>I get a similar exception with tools.nrepl</p>TANAL-89analyze+eval throws exception with message 'Cannot set! non-assignable target' for code that shouldn'tDefectMajorClosedCompletedNicola MomettoAndy FingerhutSat, 20 Sep 2014 19:12:57 -0500Sat, 20 Sep 2014 19:28:59 -0500Sat, 20 Sep 2014 19:28:59 -050000<p>Fixed: <a href="https://github.com/clojure/tools.analyzer.jvm/commit/e54155a3c7aeacdcd7321ff57ddba4f0788161b0">https://github.com/clojure/tools.analyzer.jvm/commit/e54155a3c7aeacdcd7321ff57ddba4f0788161b0</a></p>Global Rank[TANAL-88] analyze+eval throws NullPointerException, perhaps related to proxy expressionshttp://dev.clojure.org/jira/browse/TANAL-88
tools.analyzer<p>I haven't narrowed it down completely, and it may be a coincidence that several of the places I have seen this occur involve proxy expressions.</p>
<p>Steps to reproduce:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java"># git clone/pull latest version of Eastwood as of Sep 20 2014
# It should include version 0.6.0 of both tools.analyzer(.jvm)
git checkout update-tanal
lein install
# Edit ~/.lein/profiles.clj to have <span class="code-keyword">this</span> in {:user {:plugins [ ... ]}} vector: [jonase/eastwood <span class="code-quote">"0.1.5-SNAPSHOT"</span>]
cd crucible
# This step is unnecessary <span class="code-keyword">if</span> you have done it before
./clone.sh
cd repos/tools.reader-2014-03-05
lein with-profile +1.6 eastwood</pre>
</div></div>
<p>I get a similar exception with tools.logging and tools.nrepl, plus some other crucible projects, but those should be enough to go on.</p>TANAL-88analyze+eval throws NullPointerException, perhaps related to proxy expressionsDefectMajorClosedCompletedNicola MomettoAndy FingerhutSat, 20 Sep 2014 14:59:20 -0500Sat, 20 Sep 2014 17:37:37 -0500Sat, 20 Sep 2014 17:37:37 -050000<p>Fixed: <a href="https://github.com/clojure/tools.analyzer.jvm/commit/e0b686a33e89d7d74d5131e3f4356a0a9aea20ff">https://github.com/clojure/tools.analyzer.jvm/commit/e0b686a33e89d7d74d5131e3f4356a0a9aea20ff</a></p>Global Rank[TANAL-86] add a function to convert a cljs.analyzer namespace map to a t.a.js onehttp://dev.clojure.org/jira/browse/TANAL-86
tools.analyzerTANAL-86add a function to convert a cljs.analyzer namespace map to a t.a.js oneEnhancementTrivialClosedCompletedNicola MomettoNicola MomettoSun, 10 Aug 2014 18:21:24 -0500Fri, 5 Sep 2014 13:57:37 -0500Fri, 5 Sep 2014 13:57:37 -050000Global Rank[TANAL-82] new/catch classes should be analyzedhttp://dev.clojure.org/jira/browse/TANAL-82
tools.analyzerTANAL-82new/catch classes should be analyzedTaskMinorClosedCompletedNicola MomettoNicola MomettoThu, 17 Jul 2014 03:13:11 -0500Sun, 31 Aug 2014 10:15:31 -0500Sun, 20 Jul 2014 07:22:33 -050000Global Rank[TANAL-24] clojure.tools.analyzer.passes.jvm/validate throws an exception when :tag metadata cannot be resolved to a Classhttp://dev.clojure.org/jira/browse/TANAL-24
tools.analyzer<p>While the Clojure Compiler silently ignores :tag metadata in some forms when it cannot be resolved to a class, c.t.a.passes.jvm/validate throws an exception every time.</p>
<p>Some libraries (test.generators) use :tag metadata to store instructions for generating test input data, those can be everything, from symbols to quoted clojure expressions &#8211; the Clojure Compiler allows for this but validate throws an exception.</p>
<p>Generally however, when :tag cannot be resolved to a class it's not beacause of a design choice, but because of a Clojure bug or a user-code bug.</p>
<p>Some examples are:</p>
<ul class="alternate" type="square">
<li>tagging a defn form in the fn name with a primitive type hint:
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (defn ^<span class="code-object">long</span> x [] 1)
#'user/x
user=&gt; (:tag (meta #'x))
#&lt;core$<span class="code-object">long</span> clojure.core$<span class="code-object">long</span>@6596f6ef&gt;</pre>
</div></div></li>
</ul>
<ul class="alternate" type="square">
<li>using extend-type with a run-time resolved class <a href="http://dev.clojure.org/jira/browse/CLJ-1308">http://dev.clojure.org/jira/browse/CLJ-1308</a>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (defprotocol p (f [_]))
p
user=&gt; (binding [*print-meta* <span class="code-keyword">true</span>] (pr (macroexpand-1 '(extend-type (class 1) p (f [_])))))
(clojure.core/extend (class 1) p {:f (fn ([^(class 1) _]))})
nil</pre>
</div></div></li>
</ul>
<ul class="alternate" type="square">
<li>type hinting a form in a namespace with an imported class doesn't qualify the class in :tag <a href="http://dev.clojure.org/jira/browse/CLJ-1232">http://dev.clojure.org/jira/browse/CLJ-1232</a>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (ns foo (:<span class="code-keyword">import</span> clojure.lang.RT))
nil
foo=&gt; (defn x ^RT [])
#'foo/x
foo=&gt; (ns bar (:use foo))
nil
bar=&gt; (:tag (meta #'x))
RT
bar=&gt; (.hashCode (x))
CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: RT, compiling:(NO_SOURCE_PATH:5:1)</pre>
</div></div></li>
</ul>
<p>A clojure-dev post has been opened asking whether tools.analyzer.jvm is correct in assuming that non class-resolvible tags are an error and thus an exception could be thrown, or if the current behaviour of the Cloure implementation of throwing in some special places and silently ignoring malformed :tag values is by design. It hasn't have received an official reply yet. <a href="https://groups.google.com/d/msg/clojure-dev/hRZFuaiB_50/mzKLirgZWmUJ">https://groups.google.com/d/msg/clojure-dev/hRZFuaiB_50/mzKLirgZWmUJ</a></p>TANAL-24clojure.tools.analyzer.passes.jvm/validate throws an exception when :tag metadata cannot be resolved to a ClassDefectMinorClosedCompletedNicola MomettoAndy FingerhutWed, 4 Dec 2013 23:28:12 -0600Sat, 9 Aug 2014 10:10:23 -0500Sat, 9 Aug 2014 10:10:23 -050012<p>This is somewhat an undefined behaviour in clojure, it's not clear to me from the documentation wether tagging elements with things that cannot be resolved to a class should work or not.</p>
<p>I'll ask the clojure-dev ML about this before doing anything.</p>
<p>Thanks</p><p>clojure-dev post: <a href="https://groups.google.com/d/msg/clojure-dev/hRZFuaiB_50/mzKLirgZWmUJ">https://groups.google.com/d/msg/clojure-dev/hRZFuaiB_50/mzKLirgZWmUJ</a></p><p>Ticket <a href="http://dev.clojure.org/jira/browse/TGEN-5" title="Defspec leaks :tag from args into generated code">TGEN-5</a> was created on test.generative as a result of this issue, too, with a suggested patch so that test.generative no longer 'leaks' such tag values.</p><p>A workaround is now available in tools.analyzer.jvm master, the default behaviour is still to throw on "wrong" tags but it's now available a wrong-tag handler that allows user to customize the behaviour of the validate pass on wrong tags.<br/>
PoC: <a href="https://github.com/clojure/tools.analyzer.jvm/blob/master/src/test/clojure/clojure/tools/analyzer/jvm/passes_test.clj#L209-L216">https://github.com/clojure/tools.analyzer.jvm/blob/master/src/test/clojure/clojure/tools/analyzer/jvm/passes_test.clj#L209-L216</a></p>Global Rank[TANAL-42] Document the AST nodes && the passeshttp://dev.clojure.org/jira/browse/TANAL-42
tools.analyzerTANAL-42Document the AST nodes && the passesTaskMinorOpenUnresolvedNicola MomettoNicola MomettoFri, 3 Jan 2014 18:39:43 -0600Sat, 2 Aug 2014 07:12:01 -050001<p>I put together a quick reference to the AST node structures a few days ago when trying to identify discrepancies between the tools.analyzer AST format and the internal AST format used by the ClojureScript compiler. It's nowhere near as complete as it could be, but I figured I'd post it here just in case it winds up being useful when writing official docs.</p>
<p><a href="http://mkremins.github.io/clojure-ast-ref/">http://mkremins.github.io/clojure-ast-ref/</a></p><p>At first glance it looks really well done.<br/>
I'll take some time to review it and contribute if necessary, in the mean time if you want you can add a link pointing at your quickref in the tools.analyzer wiki.</p>
<p>Thanks </p><p>It appears incomplete, e.g. :static-call is missing. This appears to be because it's added not by tools.analyzer but by tools.analyzer.jvm; is the intention that platform-specific AST nodes are to be considered hidden implementation details?</p>
<p>If not, should a separate issue requesting documentation be filed with the "concrete" platforms, e.g. jvm.tools.analyzer?</p><p>I haven't yet had time to document the platform-specific node types added by tools.analyzer.{jvm,js}, although I do intend to add them to the quickref in the near future.</p>
<p>jvm.tools.analyzer appears to use a similar but incompatible AST format, which I currently don't plan on trying to document in the quickref. Filing a separate issue on that project might be the best way to move forward there.</p><p>jvm.tools.analyzer is probably not worth documenting at this time, except for historical purposes. tools.analyzer.{jvm,js} are far more likely to be maintained and enhanced in the future.</p><p>Oops, I think I introduced some confusion when I mistakenly referenced jvm.tools.analyzer. I did so because I didn't see a JIRA project for tools.analyzer.jvm.</p>
<p>On 29/May14 12:59 AM, I meant "... the 'concrete' platforms, e.g. tools.analyzer.{jvm,js} ...".</p>
<p>As an aside, had anyone considered a slight rewrite of the code so that AST (reference) documentation can be extracted rather than separately maintained?</p><p>This has been addressed mostly with the official AST quickrefs: <a href="http://clojure.github.io/tools.analyzer/doc/quickref.html">http://clojure.github.io/tools.analyzer/doc/quickref.html</a> and <a href="http://clojure.github.io/tools.analyzer.jvm/doc/quickref.html">http://clojure.github.io/tools.analyzer.jvm/doc/quickref.html</a></p>
<p>I'm changing the priority to minor</p>Global Rank[TANAL-84] Simplify tag handling for castings/nil insertion/value poppinghttp://dev.clojure.org/jira/browse/TANAL-84
tools.analyzer<p>Currently the compiler uses the op type, o-tag, tag and the context to figure out where to put casts, where to insert nils or where to pop a value off the stack.<br/>
This doesn't work well as it's really hard to figure out when it's actually necessary to e.g. pop a value or if it has already been removed from the stack.<br/>
Ideally the analyzer should provide more information to the emitter so that it's easier to understand when and where a casting/nil insertion/value popping is necessary</p>TANAL-84Simplify tag handling for castings/nil insertion/value poppingEnhancementMajorOpenUnresolvedNicola MomettoNicola MomettoFri, 25 Jul 2014 12:07:30 -0500Fri, 25 Jul 2014 12:07:30 -050000Global Rank[TANAL-83] Make it possible for try expression to return primitiveshttp://dev.clojure.org/jira/browse/TANAL-83
tools.analyzerTANAL-83Make it possible for try expression to return primitivesTaskMajorClosedCompletedNicola MomettoNicola MomettoThu, 24 Jul 2014 16:33:27 -0500Thu, 24 Jul 2014 17:28:07 -0500Thu, 24 Jul 2014 17:28:07 -050000Global Rank[TANAL-81] adds end-line and end-column information to source-infohttp://dev.clojure.org/jira/browse/TANAL-81
tools.analyzer<p>goal particularly is to use this info in <a href="https://github.com/clojure-emacs/clj-refactor.el">clj-refactor</a> but this additional info can be useful for other code analyzer and/or munging libraries.</p>
<p>currently we are experimenting to turn clj-refactor into a nrepl middleware based, editor agnostic clojure refactor tool, see <a href="https://github.com/clojure-emacs/clj-refactor.el/tree/cider-and-ast">cider-and-ast branch</a>. for this we use tools.analyzer and work on the AST. the feature we use in the experiment intends to remove debug functions like <tt>println</tt>, <tt>prn</tt> etc. in order to easily integrate with our client which is emacs-lisp code for now we need end-line information, please see <a href="https://github.com/clojure-emacs/clj-refactor.el/blob/f1c1992dfe8add01822d304a0d0b09db282129e8/src/refactor_middleware/analyzer.clj#L24-44">this</a> and <a href="https://github.com/clojure-emacs/clj-refactor.el/blob/f1c1992dfe8add01822d304a0d0b09db282129e8/clj-refactor.el#L499-525">this</a> snippets particularly.</p>TANAL-81adds end-line and end-column information to source-infoEnhancementMajorClosedCompletedNicola MomettoBenedek FazekasSat, 14 Jun 2014 08:08:39 -0500Mon, 16 Jun 2014 13:29:00 -0500Mon, 16 Jun 2014 13:29:00 -050000<p>I'll be more than happy to take this patch, can you please attach patch created with git format-patch?<br/>
Also since this is a contrib library you need to sign the elettronic Clojure CA, <a href="https://secure.echosign.com/public/hostedForm?formid=95YMDL576B336E">https://secure.echosign.com/public/hostedForm?formid=95YMDL576B336E</a> <br/>
Thanks</p><p>hi,</p>
<p>I just signed electronic Clojure CA 30 mins ago. Let me sort out the format patch thing too...</p><p>hope this suffices</p><p>Ok, it's going to take a couple of days until your name appears in the contributors list (<a href="http://clojure.org/contributing">http://clojure.org/contributing</a>) once it's there I'll merge this.<br/>
I was planning on releasing a new version of ta/taj today, I'll wait a couple of extra days to get this included.</p>
<p>Thanks again</p><p>sounds great, thx!</p><p>Pushed: <a href="https://github.com/clojure/tools.analyzer/commit/47841ee516b1caccbf7dcfc10de17119a5b4593c">https://github.com/clojure/tools.analyzer/commit/47841ee516b1caccbf7dcfc10de17119a5b4593c</a></p>Global RankPatchCode and Test[TANAL-80] Update the namespace in the env on each recursive all to analyze+evalhttp://dev.clojure.org/jira/browse/TANAL-80
tools.analyzer<p>Without a change similar to the one in the attached patch, I do not see how to get the correct namespace associated with some warnings in Eastwood, particularly the ones for :unlimited-use. The value bound to <b>ns</b> does change as soon as an in-ns form is evaluated, which is in the middle of handling the Gilardi scenario.</p>TANAL-80Update the namespace in the env on each recursive all to analyze+evalEnhancementMajorClosedCompletedNicola MomettoAndy FingerhutThu, 12 Jun 2014 05:58:12 -0500Thu, 12 Jun 2014 06:40:43 -0500Thu, 12 Jun 2014 06:40:43 -050000<p>Patch tanal-80-v1.diff is one modification I have tested, and it seems to do the job. With this, Eastwood passes its few unit tests, and the crucible test results, while not 100% identical to what they were before using ana.jvm/analyze+eval, are very very close.</p>
<p>The introduction of butlast+last is not a functional change, but merely giving name to some code inside analyze+eval and defining it separately. Certainly not a necessary part of the desired change, but I thought I'd suggest it.</p><p>Is there any reason why you replaced the mapv with a loop/recur? I don't think there's any behavioural difference and if so can you update the patch to switch back to mapv?</p>
<p>Otherwise the patch looks reasonable and I'm eager to apply it.</p><p>tanal-80-v2.diff is same as -v1, but switches loop back to mapv.</p><p>Fixed, thanks: <a href="https://github.com/clojure/tools.analyzer.jvm/commit/cbc5ef209bebe29f814993dfc022bd5fd74be05c">https://github.com/clojure/tools.analyzer.jvm/commit/cbc5ef209bebe29f814993dfc022bd5fd74be05c</a></p>Global Rank[TANAL-79] Add changelog http://dev.clojure.org/jira/browse/TANAL-79
tools.analyzerTANAL-79Add changelog TaskMajorClosedCompletedNicola MomettoNicola MomettoSat, 12 Apr 2014 08:11:26 -0500Sat, 12 Apr 2014 12:14:47 -0500Sat, 12 Apr 2014 12:14:47 -050000Global Rank[TANAL-75] t.a(.jvm) form emitted from AST has ^{:tag Object} where original source had ^clojure.lang.IPersistentCollectionhttp://dev.clojure.org/jira/browse/TANAL-75
tools.analyzer<p>With latest t.a(.jvm) (0.1.0-beta9 for both), latest Eastwood master, and latest core.rrb-vector repo as of today, 'lein check' gives no reflection warnings, but the following command does:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">% lein with-profile +1.6 eastwood '{:namespaces [clojure.core.rrb-vector]}'
Reflection warning, clojure/data/priority_map.clj:215:19 - call to method equiv on java.lang.<span class="code-object">Object</span> can't be resolved (no such method).
Reflection warning, clojure/core/memoize.clj:72:23 - reference to field cache can't be resolved.
== Eastwood 0.1.2-SNAPSHOT Clojure 1.6.0 JVM 1.7.0_51
== Linting clojure.core.rrb-vector ==
Reflection warning, clojure/core/rrb_vector.clj:100:17 - call to method cons on java.lang.<span class="code-object">Object</span> can't be resolved (no such method).
Reflection warning, clojure/core/rrb_vector.clj:150:17 - call to method cons on java.lang.<span class="code-object">Object</span> can't be resolved (no such method).</pre>
</div></div>
<p>Ignore the first two reflection warnings. It is the two in clojure/core/rrb_vector.clj that are the reason for this ticket. Use the following command to get voluminous debug output from Eastwood, including the emitted forms just before they are eval's, to see the java.lang.Object tag in place of the clojure.lang.IPersistentCollection in the source code:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">% lein with-profile +1.6 eastwood '{:namespaces [clojure.core.rrb-vector] :debug #{:all}}' &gt; out.txt</pre>
</div></div>TANAL-75t.a(.jvm) form emitted from AST has ^{:tag Object} where original source had ^clojure.lang.IPersistentCollectionDefectMinorClosedCompletedNicola MomettoAndy FingerhutSun, 30 Mar 2014 00:52:31 -0500Mon, 31 Mar 2014 13:09:12 -0500Mon, 31 Mar 2014 12:53:54 -050001<p>Thanks for the feedback, I need to do a complete overhaul of the validate-loop-locals pass, hopefully there might be room for a small performance enhancement too.</p><p>This fixes it, <a href="https://github.com/clojure/tools.analyzer.jvm/commit/a95b72a1ce519150816d45b8fea0317d35e7ca32">https://github.com/clojure/tools.analyzer.jvm/commit/a95b72a1ce519150816d45b8fea0317d35e7ca32</a></p>
<p>Since I honestly can't figure out why I was overriding :form there, I'll let this ticket open until more testing confirms that this commit hasn't introduced some other issues.</p><p>More testing hasn't found any case where this commit caused a regression so I feel confident to close this ticket.</p><p>Agreed that after this change I have seen no new problems in the Eastwood crucible set of projects using t.a(.jvm).</p>Global Rank[TANAL-77] Different reflection warning from Clojure 1.6 for compiling interop expression directly vs. after emitting from t.a(.jvm)http://dev.clojure.org/jira/browse/TANAL-77
tools.analyzer<p>Latest t.a(.jvm) as of today (after <a href="http://dev.clojure.org/jira/browse/TANAL-75" title="t.a(.jvm) form emitted from AST has ^{:tag Object} where original source had ^clojure.lang.IPersistentCollection"><del>TANAL-75</del></a> commit), Clojure 1.6.0, latest Eastwood as of today, latest version of 'fs' project as of Jan 29 2014 (and today):</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">% lein with-profile +1.6 eastwood '{:namespaces [ me.raynes.fs ]}'
Reflection warning, clojure/data/priority_map.clj:215:19 - call to method equiv on java.lang.<span class="code-object">Object</span> can't be resolved (no such method).
Reflection warning, clojure/core/memoize.clj:72:23 - reference to field cache can't be resolved.
== Eastwood 0.1.2-SNAPSHOT Clojure 1.6.0 JVM 1.7.0_51
== Linting me.raynes.fs ==
Reflection warning, me/raynes/fs.clj:156:23 - reference to field toUrl on java.io.File can't be resolved.
Reflection warning, me/raynes/fs.clj:489:42 - reference to field getName can't be resolved.</pre>
</div></div>
<p>It is the warning about 'reference to field toUrl' that is different here than when you run 'lein check', when the corresponding warning output line is:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">Reflection warning, me/raynes/fs.clj:156:23 - call to toUrl can't be resolved.</pre>
</div></div>
<p>I think that 'lein check' is warning about the macroexpanded version (. (. this (toFile)) (toUrl)), but t.a(.jvm) is emitting the form (.toUrl (.toFile this)).</p>TANAL-77Different reflection warning from Clojure 1.6 for compiling interop expression directly vs. after emitting from t.a(.jvm)EnhancementMinorClosedDeclinedNicola MomettoAndy FingerhutMon, 31 Mar 2014 08:36:45 -0500Mon, 31 Mar 2014 12:10:09 -0500Mon, 31 Mar 2014 12:10:09 -050001<p>There's nothing much I can do for the cases where tools.analyzer.jvm avoids some reflection that clojure does.</p>
<p>It's an enhancement that tools.analyzer.jvm provides over the current Clojure and I'd frankly consider this a bug of clojure if it cannot statically figure out the types of simple expressions like (.. this (toFile) (toUrl))</p><p>Sorry for the noise. I think I see what you mean now. However, I would point out that this is a case where Clojure gives a reflection warning on the original code, and <b>also</b> on the code emitted by t.a(.jvm), but at least with Clojure 1.6.0 it is a different warning, simply because the Java interop form is different in the two cases. I think this is due to ambiguity in Java interop between whether (. symbol instance) means that symbol is a Java field, or a no-arg method.</p><p>Oh, sorry, I misread the description.<br/>
I'll look into this then</p><p>Ok so, still nothing we can do.<br/>
tools.analyzer.jvm macroexpands the . form differntly than clojure, but it's still a valid expansion.</p>
<p>Anyway, looking into why this causes a reflection warning I discovered that the fs library has a typo in there, the method is called "toURL" rather then "toUrl"</p>Global Rank[TANAL-78] Forms emitted from t.a(.jvm) produce reflection warning not present in original codehttp://dev.clojure.org/jira/browse/TANAL-78
tools.analyzer<p>Latest t.a(.jvm) as of today (after <a href="http://dev.clojure.org/jira/browse/TANAL-75" title="t.a(.jvm) form emitted from AST has ^{:tag Object} where original source had ^clojure.lang.IPersistentCollection"><del>TANAL-75</del></a> commit), Clojure 1.6.0, latest Eastwood as of today, latest version of 'tools.nrepl' lib as of Feb 28 2014 (and today):</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">% lein with-profile +1.6 eastwood '{:namespaces [ clojure.tools.nrepl.middleware.session ]}'
Reflection warning, clojure/data/priority_map.clj:215:19 - call to method equiv on java.lang.<span class="code-object">Object</span> can't be resolved (no such method).
Reflection warning, clojure/core/memoize.clj:72:23 - reference to field cache can't be resolved.
== Eastwood 0.1.2-SNAPSHOT Clojure 1.6.0 JVM 1.7.0_51
== Linting clojure.tools.nrepl.middleware.session ==
Reflection warning, clojure/tools/logging.clj:270:1 - call to method isLoggable can't be resolved (target class is unknown).
Reflection warning, clojure/tools/logging.clj:270:1 - call to method log can't be resolved (target class is unknown).
Reflection warning, clojure/tools/logging.clj:270:1 - call to method log can't be resolved (target class is unknown).
Reflection warning, clojure/tools/nrepl/middleware/session.clj:230:30 - call to method put can't be resolved (target class is unknown).
Reflection warning, clojure/tools/nrepl/middleware/session.clj:230:30 - call to method put can't be resolved (target class is unknown).</pre>
</div></div>
<p>The only lines in the output I am concerned about here are the last 2, about 'call to method put can't be resolved'. Those warnings do not appear in the output of 'lein with-profile +1.6 check' on the same library.</p>
<p>All other reflection warnings produced by Eastwood are the same set as those produced by 'lein check'</p>TANAL-78Forms emitted from t.a(.jvm) produce reflection warning not present in original codeEnhancementMinorClosedCompletedNicola MomettoAndy FingerhutMon, 31 Mar 2014 11:28:26 -0500Mon, 31 Mar 2014 11:51:32 -0500Mon, 31 Mar 2014 11:51:32 -050001<p>Fixed: <a href="https://github.com/clojure/tools.analyzer/commit/c323142cb670f54e7879a906e3b9f295c6d8b5f2">https://github.com/clojure/tools.analyzer/commit/c323142cb670f54e7879a906e3b9f295c6d8b5f2</a></p>
<p>tools.analyzer was discarding the macroexpanded form's meta, now it merges the &amp;form meta into the macroexpanded form's one</p>Global Rank[TANAL-76] Add link to Tim Baldridge's tools.analyzer talk to READMEhttp://dev.clojure.org/jira/browse/TANAL-76
tools.analyzer<p>While not official documentation, anyone interested in tools.analyzer would likely want to watch it.</p>TANAL-76Add link to Tim Baldridge's tools.analyzer talk to READMEEnhancementMinorClosedCompletedNicola MomettoAndy FingerhutSun, 30 Mar 2014 10:43:15 -0500Sun, 30 Mar 2014 10:58:22 -0500Sun, 30 Mar 2014 10:58:22 -050001<p><a href="https://github.com/clojure/tools.analyzer/commit/1eb64bba9e7e8df11076d60f7d0ddb4cc26ce1b3">https://github.com/clojure/tools.analyzer/commit/1eb64bba9e7e8df11076d60f7d0ddb4cc26ce1b3</a><br/>
Thanks</p>Global RankPatchCode[TANAL-73] add a pass to warn on reflection when *warn-on-reflection* is truehttp://dev.clojure.org/jira/browse/TANAL-73
tools.analyzerTANAL-73add a pass to warn on reflection when *warn-on-reflection* is trueEnhancementMinorClosedCompletedNicola MomettoNicola MomettoSun, 16 Feb 2014 11:18:05 -0600Thu, 6 Mar 2014 11:57:38 -0600Thu, 6 Mar 2014 11:57:38 -060000<p>Fixed: <a href="https://github.com/clojure/tools.analyzer.jvm/commit/df3ee5765195f4163c93a4f76dfba7074b04f5d2">https://github.com/clojure/tools.analyzer.jvm/commit/df3ee5765195f4163c93a4f76dfba7074b04f5d2</a></p>Global Rank[TANAL-74] locals clearing for loop closed-overs does not nesthttp://dev.clojure.org/jira/browse/TANAL-74
tools.analyzer<p>This currently returns nil, should return true</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(-&gt; (a/analyze '(loop [] (<span class="code-keyword">do</span> (let [a 1] (loop [] (<span class="code-keyword">if</span> 1 a (recur)))) (recur)) (a/empty-env)) :body :ret :statements first :body :ret :body :ret :then :to-clear?)</pre>
</div></div>
TANAL-74locals clearing for loop closed-overs does not nestDefectMajorClosedCompletedNicola MomettoNicola MomettoMon, 24 Feb 2014 05:18:52 -0600Mon, 24 Feb 2014 15:14:45 -0600Mon, 24 Feb 2014 15:14:45 -060000<p>Fixed: <a href="https://github.com/clojure/tools.analyzer.jvm/commit/683ec31723aac225b83b1c718d3c2666993d37bf">https://github.com/clojure/tools.analyzer.jvm/commit/683ec31723aac225b83b1c718d3c2666993d37bf</a></p>Global Rank[TANAL-67] Restore some data to AST that Eastwood uses for line/col numbers for some lintershttp://dev.clojure.org/jira/browse/TANAL-67
tools.analyzer<p>Warning: Treat this suggested change as the ravings of a hacker who is poking at things without understanding how they work, and isn't even looking to see if there are bad consequences that may result.</p>
<p>This commit to tools.analyzer removed some data from the resulting ASTs that Eastwood was using for printing line/col numbers for some linters: <a href="https://github.com/clojure/tools.analyzer/commit/96fff1041bdebf75f3b539c439a41f3c5f496c7c">https://github.com/clojure/tools.analyzer/commit/96fff1041bdebf75f3b539c439a41f3c5f496c7c</a></p>
<p>I did a quick experiment with the latest t.a(.jvm) and Eastwood as of Feb 10 2014, and 'lein test' passes with Eastwood again with the attached patch.</p>
<p>If there are good reasons to avoid applying this patch, I can certainly find another way to get the desired line/col numbers in Eastwood's error messages. However, if you consider keeping this data in the AST harmless, it would be nice to have.</p>TANAL-67Restore some data to AST that Eastwood uses for line/col numbers for some lintersEnhancementMinorClosedDeclinedNicola MomettoAndy FingerhutMon, 10 Feb 2014 18:53:20 -0600Mon, 17 Feb 2014 14:08:48 -0600Fri, 14 Feb 2014 12:50:58 -060001<p>This change was made for tools.emitter.jvm to generate correctly munged class-names for functions, I'm ok with accepting this patch but I'll need to fix the behaviour on tools.emitter.jvm first then.</p><p>I actually went completely on another direction with this after some thought: <a href="https://github.com/clojure/tools.analyzer/commit/ae2b7ee34a326905b332d6a77cd7229f69626fb9">https://github.com/clojure/tools.analyzer/commit/ae2b7ee34a326905b332d6a77cd7229f69626fb9</a></p>
<p>Now :name is a string and represents the munged name for a fn.<br/>
This decision was made to make :name more consistent.</p>
<p>It should be trivial to write a pass for eastwood to restore the previous functionallity though, and if you point me out to where this is needed I'll be glad to do that myself.</p><p>I created a Github issue for Eastwood at the link below with steps to reproduce, and where in the Eastwood source code it is attempting to get line/col numbers but getting nils, when it formerly got line/col numbers with older t.a(.jvm) versions.</p>
<p><a href="https://github.com/jonase/eastwood/issues/58">https://github.com/jonase/eastwood/issues/58</a></p>Global Rank[TANAL-65] Enhance clear-locals to clear loop closed-overs in return positionhttp://dev.clojure.org/jira/browse/TANAL-65
tools.analyzer<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(fn [x] (loop [a 1] (<span class="code-keyword">if</span> (zero? a) x (recur (dec a)))))</pre>
</div></div>
<p>x is safe to clear.</p>TANAL-65Enhance clear-locals to clear loop closed-overs in return positionEnhancementMinorClosedCompletedNicola MomettoNicola MomettoSun, 26 Jan 2014 21:50:58 -0600Sat, 15 Feb 2014 12:32:49 -0600Sat, 15 Feb 2014 12:32:49 -060000<p>Fixed: <a href="https://github.com/clojure/tools.analyzer.jvm/commit/6abcad1b81bdfbed6280480ac3c5129f98d3c2cf">https://github.com/clojure/tools.analyzer.jvm/commit/6abcad1b81bdfbed6280480ac3c5129f98d3c2cf</a></p>Global Rank[TANAL-71] Memoization on reflective utils breaks deftype redefinitionhttp://dev.clojure.org/jira/browse/TANAL-71
tools.analyzerTANAL-71Memoization on reflective utils breaks deftype redefinitionDefectBlockerClosedCompletedNicola MomettoNicola MomettoTue, 11 Feb 2014 10:10:43 -0600Tue, 11 Feb 2014 17:31:18 -0600Tue, 11 Feb 2014 17:31:18 -060000<p>Fixed: <a href="https://github.com/clojure/tools.analyzer.jvm/commit/dc02dc61b083913d21574a7a03c8d34666a2c122">https://github.com/clojure/tools.analyzer.jvm/commit/dc02dc61b083913d21574a7a03c8d34666a2c122</a></p>Global Rank[TANAL-72] t.a(.jvm) throw exception during analysis of namespace clojure.core.async.impl.channels due to ^int type hint on constanthttp://dev.clojure.org/jira/browse/TANAL-72
tools.analyzer<p>To reproduce with latest t.a(.jvm) and Eastwood:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">$ cd path/to/core.async
$ lein eastwood '{:namespaces [ clojure.core.async.impl.channels ]}'</pre>
</div></div>
<p>The exception is no longer thrown if you remove the int type hint from MAX-QUEUE-SIZE in the namespace where it is defined.</p>
<p>This type hint was there in core.async since August 2013, so earlier versions of t.a(.jvm) were not throwing this exception with this code, I am pretty sure.</p>TANAL-72t.a(.jvm) throw exception during analysis of namespace clojure.core.async.impl.channels due to ^int type hint on constantDefectMinorClosedDuplicateNicola MomettoAndy FingerhutTue, 11 Feb 2014 11:21:06 -0600Tue, 11 Feb 2014 11:28:11 -0600Tue, 11 Feb 2014 11:28:11 -060001<p>Duplicate of <a href="http://dev.clojure.org/jira/browse/TANAL-24">http://dev.clojure.org/jira/browse/TANAL-24</a></p>Global Rank[TANAL-70] emit-form throws exception on AST produced from clojure.java.browse-ui namespacehttp://dev.clojure.org/jira/browse/TANAL-70
tools.analyzer<p>To reproduce with latest t.a(.jvm) and Eastwood:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">$ lein eastwood '{:namespaces [ clojure.java.browse-ui ]}'
== Eastwood 0.1.1-SNAPSHOT Clojure 1.5.1 JVM 1.7.0_15
== Linting clojure.java.browse-ui ==
Exception thrown during phase :emit-form of linting namespace clojure.java.browse-ui
ClassCastException clojure.lang.Symbol cannot be <span class="code-keyword">cast</span> to java.lang.<span class="code-object">Class</span>
clojure.tools.analyzer.passes.jvm.emit-form/eval3479/fn--3481 (emit_form.clj:94)
clojure.lang.MultiFn.invoke (MultiFn.java:231)
clojure.tools.analyzer.passes.jvm.emit-form/-emit-form* (emit_form.clj:16)
clojure.tools.analyzer.passes.jvm.emit-form/eval3486/fn--3488/fn--3490 (emit_form.clj:99)
clojure.core/mapv/fn--6258 (core.clj:6241)
[... <span class="code-keyword">rest</span> of stack trace deleted <span class="code-keyword">for</span> brevity ...]</pre>
</div></div>TANAL-70emit-form throws exception on AST produced from clojure.java.browse-ui namespaceDefectMinorClosedCompletedNicola MomettoAndy FingerhutTue, 11 Feb 2014 09:34:41 -0600Tue, 11 Feb 2014 10:01:20 -0600Tue, 11 Feb 2014 10:01:20 -060001<p>Fixed: <a href="https://github.com/clojure/tools.analyzer.jvm/commit/e70bee842e943fc7d465265b2be03ee9e3e14674">https://github.com/clojure/tools.analyzer.jvm/commit/e70bee842e943fc7d465265b2be03ee9e3e14674</a></p>Global Rank[TANAL-69] t.a(.jvm) returns ASTs with method calls having arg type nil in some caseshttp://dev.clojure.org/jira/browse/TANAL-69
tools.analyzer<p>I haven't found a very short example of this, but on easy way to see such an AST is to update to the latest t.a(.jvm) and Eastwood (after 2 commits made late on Feb 10 2014 to Eastwood for extra debug info in this case), and run the following command while in the Eastwood project root directory:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">$ lein eastwood '{:namespaces [ eastwood.util ]}'
== Eastwood 0.1.1-SNAPSHOT Clojure 1.5.1 JVM 1.7.0_15
== Linting eastwood.util ==
Error: Bad arg-type nil <span class="code-keyword">for</span> method named identical <span class="code-keyword">for</span> class clojure.lang.Util, full arg type list (java.lang.<span class="code-object">Object</span>, nil). ast pprinted below <span class="code-keyword">for</span> debugging tools.analyzer:
[ ... <span class="code-keyword">rest</span> of ast deleted <span class="code-keyword">for</span> brevity ... ]</pre>
</div></div>
<p>Perhaps the type info needed for Eastwood to do its deprecation checks on Java method calls is elsewhere in the AST now, but I haven't found it yet if so.</p>TANAL-69t.a(.jvm) returns ASTs with method calls having arg type nil in some casesDefectMinorClosedDeclinedNicola MomettoAndy FingerhutMon, 10 Feb 2014 23:56:27 -0600Tue, 11 Feb 2014 05:28:29 -0600Tue, 11 Feb 2014 05:28:29 -060001<p>I fixed this on the eastwood side with <a href="https://github.com/jonase/eastwood/commit/6fa94fef3c25bc6b98fec9dc139f63d7b1db49fd">https://github.com/jonase/eastwood/commit/6fa94fef3c25bc6b98fec9dc139f63d7b1db49fd</a></p>
<p>A tag for "nil" doesn't really make any sense, to avoid this errors ensure-tag replaces all nil tags with Object.</p>Global Rank[TANAL-68] doseq form causes t.a(.jvm) emit-form to generate code that Clojure cannot compilehttp://dev.clojure.org/jira/browse/TANAL-68
tools.analyzer<p>I can reproduce this with a namespace that contains only a single function like this, with latest t.a(.jvm) and Eastwood as of Feb 10 2014:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(defn foo []
(doseq [i (range 10)]
(println i)))</pre>
</div></div>
<p>That in a namespace and 'lein eastwood '{:namespaces [ my.ns ] :debug #{:eval}}' shows the output of emit-form that causes the Clojure compiler to throw an exception.</p>TANAL-68doseq form causes t.a(.jvm) emit-form to generate code that Clojure cannot compileDefectMajorClosedCompletedNicola MomettoAndy FingerhutMon, 10 Feb 2014 19:42:40 -0600Mon, 10 Feb 2014 20:02:05 -0600Mon, 10 Feb 2014 20:02:05 -060001<p>Fixed: <a href="https://github.com/clojure/tools.analyzer.jvm/commit/1c3e1cdb823c34f7117fcc7f917163a0fa5a289f">https://github.com/clojure/tools.analyzer.jvm/commit/1c3e1cdb823c34f7117fcc7f917163a0fa5a289f</a></p>Global Rank[TANAL-66] Fix locals tag handlinghttp://dev.clojure.org/jira/browse/TANAL-66
tools.analyzerTANAL-66Fix locals tag handlingDefectMajorClosedCompletedNicola MomettoNicola MomettoMon, 27 Jan 2014 14:12:11 -0600Mon, 27 Jan 2014 17:32:59 -0600Mon, 27 Jan 2014 17:32:59 -060000<p>Handled on the tools.emitter.jvm side <a href="https://github.com/clojure/tools.emitter.jvm/commit/c08106a1d77aa8866a9392e33d707c6eeef82dbd">https://github.com/clojure/tools.emitter.jvm/commit/c08106a1d77aa8866a9392e33d707c6eeef82dbd</a></p>Global Rank[TANAL-64] Enhance infer-tag to ignore untyped nodeshttp://dev.clojure.org/jira/browse/TANAL-64
tools.analyzer<p>just as we do for :recur, ignore :throw and all the other untyped nodes</p>TANAL-64Enhance infer-tag to ignore untyped nodesEnhancementMinorClosedCompletedNicola MomettoNicola MomettoSun, 26 Jan 2014 17:43:08 -0600Mon, 27 Jan 2014 12:24:52 -0600Mon, 27 Jan 2014 12:24:52 -060000<p>Fixed for :throw: <a href="https://github.com/clojure/tools.analyzer.jvm/commit/91c76b45e84ae5bef2375b12b50a695ec2c01857">https://github.com/clojure/tools.analyzer.jvm/commit/91c76b45e84ae5bef2375b12b50a695ec2c01857</a></p>
<p>The remaining nodes :monitor-enter/:monitor-exit/:deftype should never be in return position.</p>Global Rank[TANAL-63] clear-locals is brokenhttp://dev.clojure.org/jira/browse/TANAL-63
tools.analyzer<p>needs to be rewritten.</p>TANAL-63clear-locals is brokenDefectBlockerClosedCompletedNicola MomettoNicola MomettoSun, 26 Jan 2014 14:46:53 -0600Sun, 26 Jan 2014 21:49:05 -0600Sun, 26 Jan 2014 21:49:05 -060000<p>Fixed: <a href="https://github.com/clojure/tools.analyzer.jvm/commit/8720fbc2d693dba4626ec992941f042073ae6ab6">https://github.com/clojure/tools.analyzer.jvm/commit/8720fbc2d693dba4626ec992941f042073ae6ab6</a><br/>
<a href="https://github.com/clojure/tools.analyzer.jvm/commit/d674dcb0d8d8ed1b61421e254070ee5ed6214a9a">https://github.com/clojure/tools.analyzer.jvm/commit/d674dcb0d8d8ed1b61421e254070ee5ed6214a9a</a></p>Global Rank[TANAL-62] An exception is no longer thrown while linting project pantomime namespace pantomime.mediahttp://dev.clojure.org/jira/browse/TANAL-62
tools.analyzer<p>This is not necessarily a bug, but it is a change that resulted from the most recent commits (last 1 or 2 days) to tools.analyzer(.jvm). With current latest versions of these and Eastwood, and pantomime (part of Eastwood crucible), this command causes no exception to be thrown during analysis:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">lein eastwood '{:namespaces [ pantomime.media ]}'</pre>
</div></div>
<p>Before the most recent commits to tools.analyzer(.jvm), there was an exception due to line 97 in the source file because of a ^Map type hint on a locally bound symbol in a when-let form.</p>TANAL-62An exception is no longer thrown while linting project pantomime namespace pantomime.mediaTaskMinorClosedCompletedNicola MomettoAndy FingerhutThu, 23 Jan 2014 23:56:19 -0600Sun, 26 Jan 2014 12:42:38 -0600Sun, 26 Jan 2014 12:42:38 -060001<p>Andy, I'm currently working on making tools.analyzer.jvm and tools.emitter.jvm play nice with each other again, the tag handling situation is a bit problematic and I'm working on making it simpler for t.e.j to handle casting.</p>
<p>Expect things to be broken in master for a couple of days until thing settle down.</p><p>No problem, and sorry for the noise. If you remember, let me know when you think things are settled down and I will update and test then.</p><p>Should be back to the previous behaviour now.<br/>
One thing to notice is that I removed :ret-tag and :bind-tag, now every expression has both :tag and :o-tag.<br/>
:o-tag represents the effective type of the expression, while :tag represents the "needed" tag of the expression.</p>
<p>E.g</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">^clojure.lang.IPersistentVector []</pre>
</div></div>
<p>will have clojure.lang.IPersistentVector as :tag and clojure.lang.PersistentVector as :o-tag.</p>
<p>This means that that we're not throwing any :tag-kind anymore since it all got unified. This will probably require some changes to eastwood.</p><p>OK, latest t.a(.jvm) is back to throwing an exception on that code now. I have updated Eastwood to no longer use :tag-kind for deciding what kind of error messages to print when a "Can't find class" exception is thrown. I believe nothing else in Eastwood depended upon :ret-tag or :bind-tag</p><p>Ok, I'm closing the ticket then.</p>Global Rank[TANAL-61] Exception 'Ambiguous method signature for method: cons' when Eastwood analyzes namespace clojure.core.matchhttp://dev.clojure.org/jira/browse/TANAL-61
tools.analyzer<p>With latest tools.analyzer(.jvm), Eastwood, and core.match:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">$ lein eastwood '{:namespaces [ clojure.core.match ]}'
[ ... many lines deleted ... ]
Exception thrown during phase :analyze of linting namespace clojure.core.match
Got exception with extra ex-data:
msg='Ambiguous method signature <span class="code-keyword">for</span> method: cons'
(keys dat)=(:file :method :interfaces :form :params :matches)
(:form dat)=
(^{:line 307, :column 4, :end-line 307, :end-column 8} cons
[^{:line 307, :column 10, :end-line 307, :end-column 11} _
^{:line 307, :column 12, :end-line 307, :end-column 13} x]
(^{:line 308, :column 6, :end-line 308, :end-column 17} PatternRow.
(^{:line 308, :column 19, :end-line 308, :end-column 23} conj
^{:line 308, :column 24, :end-line 308, :end-column 26} ps
^{:line 308, :column 27, :end-line 308, :end-column 28} x)
^{:line 308, :column 30, :end-line 308, :end-column 36} action
^{:line 308, :column 37, :end-line 308, :end-column 45} bindings))
ExceptionInfo Ambiguous method signature <span class="code-keyword">for</span> method: cons
clojure.core/ex-info (core.clj:4355)
clojure.tools.analyzer.passes.jvm.validate/eval2516/fn--2518 (validate.clj:289)
clojure.lang.MultiFn.invoke (MultiFn.java:227)
clojure.tools.analyzer.passes.jvm.validate/validate (validate.clj:326)
clojure.tools.analyzer.ast/cycling/fn--53 (ast.clj:19)
[ ... many lines deleted ... ]</pre>
</div></div>TANAL-61Exception 'Ambiguous method signature for method: cons' when Eastwood analyzes namespace clojure.core.matchDefectMinorClosedCompletedNicola MomettoAndy FingerhutTue, 21 Jan 2014 16:33:15 -0600Tue, 21 Jan 2014 17:29:04 -0600Tue, 21 Jan 2014 17:29:04 -060001<p><a href="https://github.com/clojure/tools.analyzer.jvm/commit/f820fe3da5e37e4532beb04de814f45eb81b7919">https://github.com/clojure/tools.analyzer.jvm/commit/f820fe3da5e37e4532beb04de814f45eb81b7919</a></p>
<p>I rewrote the logic for try-best-match, now it's much simplier and should cover all the cases.</p>Global Rank[TANAL-60] Exception 'Ambiguous method signature for method: assoc' when Eastwood analyzes code containing 'defrecord'http://dev.clojure.org/jira/browse/TANAL-60
tools.analyzer<p>I haven't narrowed it down to exactly which commit may have caused this to change, but it was probably within the last 3-4 days.</p>
<p>Example, with latest tools.analyzer(.jvm) and Eastwood, but I believe that just about any namespace with a defrecord in it will trigger this issue:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">$ lein eastwood '{:namespaces [ clojurewerkz.neocons.<span class="code-keyword">rest</span> ]}'
[ ... some lines deleted here ... ]
Exception thrown during phase :analyze of linting namespace clojurewerkz.neocons.<span class="code-keyword">rest</span>
Got exception with extra ex-data:
msg='Ambiguous method signature <span class="code-keyword">for</span> method: assoc'
(keys dat)=(:file :method :interfaces :form :params :matches)
(:form dat)=
[ ... many lines deleted here ... ]</pre>
</div></div>TANAL-60Exception 'Ambiguous method signature for method: assoc' when Eastwood analyzes code containing 'defrecord'DefectMinorClosedCompletedNicola MomettoAndy FingerhutTue, 21 Jan 2014 12:56:45 -0600Tue, 21 Jan 2014 13:00:57 -0600Tue, 21 Jan 2014 13:00:57 -060001<p>I fixed this 2 days ago but somehow forgot to commit it.</p>
<p><a href="https://github.com/clojure/tools.analyzer.jvm/commit/398dc661dc78821da8d15317b45915ad30ee62e8">https://github.com/clojure/tools.analyzer.jvm/commit/398dc661dc78821da8d15317b45915ad30ee62e8</a></p>Global Rank[TANAL-59] eval'ing emit-form result gives 2 reflection warnings that 'lein check' does not, for core.incubator namespacehttp://dev.clojure.org/jira/browse/TANAL-59
tools.analyzer<p>With latest t.a(.jvm), Eastwood, and core.incubator, here is output I see:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">% lein eastwood '{:namespaces [ clojure.core.incubator-test ]}'
Reflection warning, clojure/data/priority_map.clj:215:19 - call to equiv can't be resolved.
Reflection warning, clojure/core/memoize.clj:72:23 - reference to field cache can't be resolved.
== Eastwood 0.1.1-SNAPSHOT Clojure 1.5.1 JVM 1.7.0_15
== Linting clojure.core.incubator-test ==
Reflection warning, clojure/core/incubator.clj:90:7 - reference to field getClass can't be resolved.
Reflection warning, clojure/core/incubator.clj:90:7 - reference to field isArray can't be resolved.
Reflection warning, clojure/core/incubator_test.clj:17:39 - reference to field toString can't be resolved.
Reflection warning, clojure/core/incubator_test.clj:20:39 - reference to field toString can't be resolved.
Reflection warning, clojure/core/incubator_test.clj:21:39 - call to get can't be resolved.
Reflection warning, clojure/core/incubator_test.clj:21:39 - reference to field toString can't be resolved.
Reflection warning, clojure/core/incubator_test.clj:25:15 - reference to field toString can't be resolved.
Reflection warning, clojure/core/incubator_test.clj:31:15 - reference to field toString can't be resolved.
Reflection warning, clojure/core/incubator_test.clj:36:15 - reference to field toString can't be resolved.
Reflection warning, clojure/core/incubator_test.clj:37:15 - call to get can't be resolved.
Reflection warning, clojure/core/incubator_test.clj:37:15 - reference to field toString can't be resolved.
{:linter :unlimited-use,
:msg
<span class="code-quote">"Unlimited use of (clojure.test clojure.core.incubator) in clojure.core.incubator-test"</span>,
:line 11,
:column 5}
== Warnings: 1 (not including reflection warnings) Exceptions thrown: 0
Subprocess failed</pre>
</div></div>
<p>Most of those reflection warnings also appear in the output of 'lein check' for that namespace, but 2 do not. They are:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">Reflection warning, clojure/core/incubator_test.clj:21:39 - call to get can't be resolved.
Reflection warning, clojure/core/incubator_test.clj:37:15 - call to get can't be resolved.</pre>
</div></div>TANAL-59eval'ing emit-form result gives 2 reflection warnings that 'lein check' does not, for core.incubator namespaceDefectMinorClosedDeclinedNicola MomettoAndy FingerhutFri, 17 Jan 2014 11:58:16 -0600Sun, 19 Jan 2014 09:03:19 -0600Fri, 17 Jan 2014 18:00:01 -060001<p>This took me <b>a lot</b> to figure out.<br/>
It's not a tools.analyzer bug but a Clojure bug.</p>
<p>This will resolve the method at compile time:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(.method [..] ..)</pre>
</div></div>
<p>This will not:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(.method ^{..} [..] ..)</pre>
</div></div>
<p>In this case, lein check is not reporting any reflection warning because the only meta on <span class="error">&#91;0&#93;</span> is :line/:column that gets stripped, while in eastwood <span class="error">&#91;0&#93;</span> has :line/:column/:end-line/:end-column since it gets read by tools.reader.</p>
<p>So to see if I understand correctly, ideally Clojure should resolve the method correctly even if there is metadata like in the (.method ^{..} <span class="error">&#91;..&#93;</span> ..) case, as long as that metadata gives no :tag at all, or a correct :tag for the method resolved to?</p><p>And if the answer to my question above is "yes", is it worth filing a ticket for the Clojure compiler, with any details you have learned about the source of the issue?</p><p>Yes.<br/>
I'll definitely open a ticket for this once I fully grasp what's going on.</p>
<p>Looks like tools.analyzer/emitter is, even though in less cases (not in this for example), affected by a similar bug.</p><p>Should be fixed for tools.analyzer, here's the ticket for clojure <a href="http://dev.clojure.org/jira/browse/CLJ-1326">http://dev.clojure.org/jira/browse/CLJ-1326</a></p>Global Rank[TANAL-58] analyze gives no error for arg vector [a & &]http://dev.clojure.org/jira/browse/TANAL-58
tools.analyzer<p>Discovered during some manual testing of which arg vectors gave errors:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(defn foo [a &amp; &amp;]
(inc a))</pre>
</div></div>TANAL-58analyze gives no error for arg vector [a & &]DefectMinorClosedCompletedNicola MomettoAndy FingerhutWed, 15 Jan 2014 21:53:40 -0600Thu, 16 Jan 2014 05:17:38 -0600Thu, 16 Jan 2014 05:17:38 -060001<p>Fixed <a href="https://github.com/clojure/tools.analyzer/commit/0be70788d42917c1cea9e99d2249623d6229c70c">https://github.com/clojure/tools.analyzer/commit/0be70788d42917c1cea9e99d2249623d6229c70c</a></p>Global Rank[TANAL-57] Reflection warning from emit-form eval that Clojure compiler by itself does nothttp://dev.clojure.org/jira/browse/TANAL-57
tools.analyzer<p>OK, this one I have verified is a difference even after 'lein clean' on the project. Latest version of Eastwood and t.a(.jvm), and of tools.emitter.jvm, where the extra Eastwood warning occurs. I added a :1.6 profile to the project.clj that uses latest 1.6.0-master-SNAPSHOT, but I think this difference exists even with Clojure 1.5.1, too.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">lein with-profile 1.6 eastwood '{:namespaces [ clojure.tools.emitter.jvm.emit ] :debug #{:eval}}'
[ ... ]
Reflection warning, clojure/tools/emitter/jvm/emit.clj:39:29 - call to getMethod can't be resolved.</pre>
</div></div>TANAL-57Reflection warning from emit-form eval that Clojure compiler by itself does notDefectMinorClosedCompletedNicola MomettoAndy FingerhutWed, 15 Jan 2014 13:45:13 -0600Wed, 15 Jan 2014 16:12:06 -0600Wed, 15 Jan 2014 16:12:06 -060001<p>Fixed: <a href="https://github.com/clojure/tools.analyzer.jvm/commit/f676e1d877d2c3885e52b29ce990045db80b98c3">https://github.com/clojure/tools.analyzer.jvm/commit/f676e1d877d2c3885e52b29ce990045db80b98c3</a></p>Global Rank[TANAL-55] Another difference in reflection warnings from eval'ing emit-form vs. plain Clojurehttp://dev.clojure.org/jira/browse/TANAL-55
tools.analyzer<p>I think the list of differences between reflection warnings issues by 'lein check' and Eastwood for projects in Eastwood's crucible is getting fairly short now, but there are still a few.</p>
<p>I have switched to doing my comparison with Clojure 1.6.0-master-SNAPSHOT after realizing that a few of the differences go away when using that, I think due to the change introduced by <a href="http://dev.clojure.org/jira/browse/CLJ-1202" title="protocol fns with dashes may get compiled into property access when used higher order"><del>CLJ-1202</del></a>.</p>
<p>Get latest 'reply' project (it is one pulled by Eastwood crucible), and edit its project.clj file to add these things:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">:global-vars {*warn-on-reflection* <span class="code-keyword">true</span>}
:profiles {:dev {:dependencies ~dev-deps}
:1.6 {:dependencies [[org.clojure/clojure <span class="code-quote">"1.6.0-master-SNAPSHOT"</span>]]</pre>
</div></div>
<p>Then run the command below, assuming you have done 'mvn install' on latest Clojure 1.6.0-master-SNAPSHOT:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">lein with-profile 1.6 eastwood '{:namespaces [reply.reader.jline.JlineInputReader] :debug #{:eval}}'
[ ... ]
Reflection warning, reply/reader/jline/JlineInputReader.clj:15:10 - reference to field state can't be resolved.
Reflection warning, reply/reader/jline/JlineInputReader.clj:18:18 - reference to field readLine can't be resolved.
Reflection warning, reply/reader/jline/JlineInputReader.clj:30:10 - reference to field state can't be resolved.</pre>
</div></div>
<p>No reflection warnings appear for that namespace in the output of 'lein with-profile 1.6 check'</p>TANAL-55Another difference in reflection warnings from eval'ing emit-form vs. plain ClojureDefectMinorClosedCompletedNicola MomettoAndy FingerhutWed, 15 Jan 2014 02:36:24 -0600Wed, 15 Jan 2014 10:22:52 -0600Wed, 15 Jan 2014 05:17:47 -060001<p>Honestly I have absolutely no idea how that code doesn't trigger a reflection warning in Clojure.<br/>
There must be something going on under the wood of gen-class that I'm not aware of, I'll need some time to take a look &amp; understand.</p>
<p>Thanks for the report</p><p>Upon further investigation, I think that for some reason Clojure is not printing the reflection warning even though reflection is actually needed.</p>
<p>Empirical evidence: try to change a method call to .foo and no reflection warning will be printed.</p><p>Verified that if the (set! <b>warn-on-reflection</b> true) is put in the <b>ns</b>, I get the same reflection warnings from clojure.</p>
<p>I have no idea why it won't print when <b>warn-on-reflection</b> is set! outside the ns though.</p><p>Weird, I was trying to reproduce this again to see why 'lein check' was not producing those warnings, but now it is. I can't think what might have changed since yesterday.</p><p>Not sure, but the :gen-class may have something to do with it. If the class has already been generated, perhaps Leiningen is not recompiling that file. 'lein clean' first should make things more consistent.</p><p>Confirmed. If you do 'lein clean' then 'lein check' twice with no changes to the source files, the warnings are produced the first time, but not the second. If you edit the source file, it is newer than the target class file and so gets recompiled.</p>Global Rank[TANAL-56] Update versions in project.clj fileshttp://dev.clojure.org/jira/browse/TANAL-56
tools.analyzer<p>So they are 0.1.0-SNAPSHOT for both t.a and t.a.jvm.</p>
<p>Also nice to update the dependency on t.a.jvm in tools.emitter.jvm's project.clj</p>TANAL-56Update versions in project.clj filesDefectMinorClosedCompletedNicola MomettoAndy FingerhutWed, 15 Jan 2014 03:08:45 -0600Wed, 15 Jan 2014 04:58:05 -0600Wed, 15 Jan 2014 04:58:05 -060001<p><a href="https://github.com/clojure/tools.analyzer/commit/ce23c47a243d663e04143f2ff98a4dd86b685f60">https://github.com/clojure/tools.analyzer/commit/ce23c47a243d663e04143f2ff98a4dd86b685f60</a><br/>
<a href="https://github.com/clojure/tools.analyzer.jvm/commit/64ecab702a3a666f0a14562f0fa4c5339267bd07">https://github.com/clojure/tools.analyzer.jvm/commit/64ecab702a3a666f0a14562f0fa4c5339267bd07</a><br/>
<a href="https://github.com/clojure/tools.emitter.jvm/commit/5f230c7ae5363445812c9c3a49e1142d029b2cc3">https://github.com/clojure/tools.emitter.jvm/commit/5f230c7ae5363445812c9c3a49e1142d029b2cc3</a></p>Global Rank[TANAL-54] Reflection warnings from emitted forms, but type tags given on loop locals should prevent them?http://dev.clojure.org/jira/browse/TANAL-54
tools.analyzer<p>I'm guessing at the common denominator here. I am using latest Eastwood and tools.analyzer(.jvm) on latest core.async library code. The first two reflection warnings are normal, from Eastwood's use of core.memoize and data.priority-map, I believe. It is the 5 in clojure.core.async.impl.channels that are the concern here. None of them appear in the output of 'lein check' for core.async</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">% lein eastwood '{:namespaces [ clojure.core.async.impl.channels ]}'
Reflection warning, clojure/data/priority_map.clj:215:19 - call to equiv can't be resolved.
Reflection warning, clojure/core/memoize.clj:72:23 - reference to field cache can't be resolved.
== Eastwood 0.1.1-SNAPSHOT Clojure 1.5.1 JVM 1.7.0_15
== Linting clojure.core.async.impl.channels ==
Reflection warning, clojure/core/async/impl/channels.clj:190:15 - reference to field lock can't be resolved.
Reflection warning, clojure/core/async/impl/channels.clj:192:17 - reference to field unlock can't be resolved.
Reflection warning, clojure/core/async/impl/channels.clj:65:56 - reference to field lock can't be resolved.
Reflection warning, clojure/core/async/impl/channels.clj:66:40 - reference to field lock can't be resolved.
Reflection warning, clojure/core/async/impl/channels.clj:70:36 - reference to field unlock can't be resolved.</pre>
</div></div>TANAL-54Reflection warnings from emitted forms, but type tags given on loop locals should prevent them?DefectMinorClosedCompletedNicola MomettoAndy FingerhutTue, 14 Jan 2014 20:38:23 -0600Tue, 14 Jan 2014 21:01:38 -0600Tue, 14 Jan 2014 21:01:38 -060001<p>The issue here was that validate-loop-locals was trying to be "smarter" than clojure, by validating non-primitive values too, making it possible for</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(loop [x (<span class="code-object">Integer</span>. 1)] (<span class="code-keyword">if</span> (number? x) (recur <span class="code-quote">"foo"</span>) (.hashCode x))</pre>
</div></div>
<p>to compile (Clojure throws an exception at runtime for this code)</p>
<p>However it looks like this "enhancements" breaks the assumption of that piece of core.async code that loop args will be automatically tagged, so this has been reverted and we now match Clojure behaviour.<br/>
<a href="https://github.com/clojure/tools.analyzer.jvm/commit/8ff4ff8df01f5d0638030bc78fc7b8cad712d272">https://github.com/clojure/tools.analyzer.jvm/commit/8ff4ff8df01f5d0638030bc78fc7b8cad712d272</a></p>Global Rank[TANAL-53] Should type-hint exceptions inside catch expressions?http://dev.clojure.org/jira/browse/TANAL-53
tools.analyzer<p>Clojure 1.5.1 gives no reflection warning at all for the following source file, but eval'ing the result of emit-form gives this warning:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">Reflection warning, reflection/core4.clj:11:16 - reference to field getMessage can't be resolved.</pre>
</div></div>
<p>Here is the code:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(ns reflection.core4)
(set! *warn-on-reflection* <span class="code-keyword">true</span>)
;; copied &amp; trimmed down from namespace reply.main
(defn foo [arg]
(<span class="code-keyword">try</span>
(read-string arg)
(<span class="code-keyword">catch</span> Exception e
(println (.getMessage e)))))</pre>
</div></div>TANAL-53Should type-hint exceptions inside catch expressions?DefectMinorClosedCompletedNicola MomettoAndy FingerhutTue, 14 Jan 2014 15:43:15 -0600Tue, 14 Jan 2014 15:55:26 -0600Tue, 14 Jan 2014 15:55:26 -060001<p>Well this one is weird.<br/>
Looks like if the classname to a catch is a Class, the local will not get type hinted but the catch will work fine anyway.</p>
<p>Fixed: <a href="https://github.com/clojure/tools.analyzer.jvm/commit/c79c5f8e8cb96a323360fb75c86bf10c41b83082">https://github.com/clojure/tools.analyzer.jvm/commit/c79c5f8e8cb96a323360fb75c86bf10c41b83082</a></p>Global Rank[TANAL-52] More tags missing from emit-form resulthttp://dev.clojure.org/jira/browse/TANAL-52
tools.analyzer<p>If you don't mind, I will keep putting up one of these every time I find one, but keep at most one pending at a time. The main reason for me doing one-at-a-time is I am not taking the time to determine which of these are due to the same root cause, and which are not, so the one-at-a-time method should reduce duplication of reports.</p>
<p>In ogre project, part of Eastwood crucible, the following command with latest tools.analyzer(.jvm) and Eastwood produces a reflection warning from Eastwood, but not from the Clojure compiler (using 'lein check'):</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">lein eastwood '{:namespaces [ ogre.filter ] :debug #{:eval}}'
[ ... most output deleted ... ]
Reflection warning, ogre/filter.clj:27:12 - call to interval can't be resolved.</pre>
</div></div>TANAL-52More tags missing from emit-form resultDefectMinorClosedCompletedNicola MomettoAndy FingerhutTue, 14 Jan 2014 09:32:12 -0600Tue, 14 Jan 2014 11:45:59 -0600Tue, 14 Jan 2014 11:45:59 -060001<p>I don't mind at all, keep'em coming!<br/>
Fixed: <a href="https://github.com/clojure/tools.analyzer.jvm/commit/6371e4384ae0b6948ca1243f03690a3a9be9f669">https://github.com/clojure/tools.analyzer.jvm/commit/6371e4384ae0b6948ca1243f03690a3a9be9f669</a></p>Global Rank[TANAL-51] Another case where emit-form seems to omit a type tag leading to reflection warninghttp://dev.clojure.org/jira/browse/TANAL-51
tools.analyzer<p>To reproduce, go to latest version of core.async source tree and with latest tools.analyzer(.jvm) and latest Eastwood 0.1.1-SNAPSHOT:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">lein eastwood '{:namespaces [ clojure.core.async.impl.timers ] :debug #{:eval}}'</pre>
</div></div>
<p>I get exactly one reflection warning, but none appear when compiling the code normally:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">Reflection warning, clojure/core/async/impl/timers.clj:1:251 - reference to field channel can't be resolved.</pre>
</div></div>
<p>It is inside defn timeout</p>TANAL-51Another case where emit-form seems to omit a type tag leading to reflection warningDefectMinorClosedCompletedNicola MomettoAndy FingerhutMon, 13 Jan 2014 20:54:11 -0600Tue, 14 Jan 2014 05:20:11 -0600Mon, 13 Jan 2014 21:19:02 -060001<p>Should be fixed with <a href="https://github.com/clojure/tools.analyzer.jvm/commit/bb4c9fca086b3cbeba382df7435990f493148869">https://github.com/clojure/tools.analyzer.jvm/commit/bb4c9fca086b3cbeba382df7435990f493148869</a> and <a href="https://github.com/clojure/tools.analyzer/commit/fe76b18248a336566965ff9b235e97af65f1f1f1">https://github.com/clojure/tools.analyzer/commit/fe76b18248a336566965ff9b235e97af65f1f1f1</a> but it's possible there are still some edge-cases missing.</p>
<p>Please open a new ticket if you find any, thanks</p><p>That change to tools.analyzer causes it to fail one of its unit tests run by 'lein test'</p><p>Sorry about that. I was relying on hudson to check whether or not it break anything but the commit didn't trigger a new build and I didn't notice I was looking at an old build.</p>
<p>Should be fixed now.</p><p>Hmm. Fails more unit tests of 'lein test' now.</p><p>That was intended, I finished that minor refactor with <a href="https://github.com/clojure/tools.analyzer/commit/d52e8400b460c1475646f084d53f948d7fae5b34">https://github.com/clojure/tools.analyzer/commit/d52e8400b460c1475646f084d53f948d7fae5b34</a><br/>
Tests are now passing again.</p>Global Rank[TANAL-50] emit-form completely omits some metadata that causes reflection warning if eval'dhttp://dev.clojure.org/jira/browse/TANAL-50
tools.analyzer<p>To reproduce, do 'lein new reflection' and replace contents of src/reflection/core.clj with the following:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(ns reflection.core
(:<span class="code-keyword">import</span> [java.net URL]))
(set! *warn-on-reflection* <span class="code-keyword">true</span>)
;; copied from namespace clojurewerkz.neocons.<span class="code-keyword">rest</span>.helpers
(defn extract-id
[^<span class="code-object">String</span> location]
(let [url (URL. location)]
(<span class="code-object">Long</span>/valueOf ^<span class="code-object">String</span> (first (re-seq #<span class="code-quote">"\d+$"</span> (.getPath url))))))</pre>
</div></div>
<p>Update to the latest Eastwood master, install, make sure eastwood version 0.1.1-SNAPSHOT is in your ~/.lein/profiles.clj, and run this command:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">lein eastwood '{:debug #{:eval}}'</pre>
</div></div>
<p>It should show each form that will be eval'd, starting with the not-analyzed ns form, followed by the 2 other forms that are each analyzed and are the result of emit-form, shown with metadata.</p>
<p>When I do that, I see the arg to Long/valueOf with no metadata at all (no String tag), which causes eval in Eastwood to generate a reflection warning. There is no reflection warning with 'lein check'.</p>TANAL-50emit-form completely omits some metadata that causes reflection warning if eval'dDefectMinorClosedCompletedNicola MomettoAndy FingerhutMon, 13 Jan 2014 00:36:43 -0600Mon, 13 Jan 2014 05:05:31 -0600Mon, 13 Jan 2014 05:05:31 -060001<p>Fixed: <a href="https://github.com/clojure/tools.analyzer/commit/d9e9cd2e385a5f1354a8c5fbd26826e04ae549e4">https://github.com/clojure/tools.analyzer/commit/d9e9cd2e385a5f1354a8c5fbd26826e04ae549e4</a></p>Global Rank[TANAL-49] emit-form missing some metadata, leading to reflection warnings when eval'd?http://dev.clojure.org/jira/browse/TANAL-49
tools.analyzer<p>I will keep investigating to see if this problem exists only in Eastwood's use of tools.analyzer(.jvm), but here are the symptoms. Use 'lein new reflection' to create a new Leiningen project, and edit the file src/reflection/core.clj to contain:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(ns reflection.core)
(set! *warn-on-reflection* <span class="code-keyword">true</span>)
(defn foo [s]
(doseq [i s]
(println i)))</pre>
</div></div>
<p>Using Eastwood 0.1.0, 'lein eastwood' gives me a reflection warning like the one below, but only about half the time that I run it. The other half of the time there is no reflection warning.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">Reflection warning, reflection/core.clj:1:218 - call to nth can't be resolved.</pre>
</div></div>TANAL-49emit-form missing some metadata, leading to reflection warnings when eval'd?DefectMinorClosedCompletedNicola MomettoAndy FingerhutSun, 12 Jan 2014 12:32:58 -0600Sun, 12 Jan 2014 21:32:12 -0600Sun, 12 Jan 2014 12:53:01 -060001<p>Fixed with: <a href="https://github.com/clojure/tools.analyzer.jvm/commit/7de63ad3f81ed5a60ba0b3031383d1d63db2b51f">https://github.com/clojure/tools.analyzer.jvm/commit/7de63ad3f81ed5a60ba0b3031383d1d63db2b51f</a></p>
<p>Still need to understand if the non-deterministic behaviour of this bug is relevant.</p><p>Perhaps your later commits to tools.analyzer(.jvm) indicate areas of potential nondeterminism that you were trying to make deterministic?</p>
<p>Later testing did reveal that in the cases I was getting the reflection warnings, the tag was of type java.lang.Class, and when the tag was of type clojure.lang.Symbol there was no reflection warning. This is consistent with Compiler.java's tagOf() method ignoring any tags except those with class clojure.lang.Symbol or java.lang.String.</p>
<p>I did not determine why the results were nondeterministic.</p><p>No, my later commits are solely for performance enhancements, I was not able to reproduce the nondeterministic results at the repl unfortunately, so I'm unable to figure that out.</p>
Global Rank[TANAL-48] tools.analyzer fails Maven build with Jan 11 2014 1.6.0-master-SNAPSHOThttp://dev.clojure.org/jira/browse/TANAL-48
tools.analyzer<p>This appears to be due to the addition of clojure.core/record? which leads to the following warnings when building tools.analyzer with 1.6.0-master-SNAPSHOT:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">% lein with-profile 1.6 <span class="code-keyword">do</span> clean, test
WARNING: record? already refers to: #'clojure.core/record? in namespace: clojure.tools.analyzer.utils, being replaced by: #'clojure.tools.analyzer.utils/record?
WARNING: record? already refers to: #'clojure.core/record? in namespace: clojure.tools.analyzer, being replaced by: #'clojure.tools.analyzer.utils/record?</pre>
</div></div>
<p>These cause the Maven build to fail.</p>
<p>Similarly for tools.analyzer.jvm</p>TANAL-48tools.analyzer fails Maven build with Jan 11 2014 1.6.0-master-SNAPSHOTDefectMinorClosedCompletedNicola MomettoAndy FingerhutSat, 11 Jan 2014 15:16:15 -0600Sat, 11 Jan 2014 20:04:19 -0600Sat, 11 Jan 2014 20:04:19 -060001<p>Fixed:<br/>
<a href="https://github.com/clojure/tools.analyzer/commit/89d98b688448fe3d02bcabea240bcb2f6d2bbd70">https://github.com/clojure/tools.analyzer/commit/89d98b688448fe3d02bcabea240bcb2f6d2bbd70</a><br/>
<a href="https://github.com/clojure/tools.analyzer.jvm/commit/e8510c21f0f1e0f8af4008b9b253783c15d9cac8">https://github.com/clojure/tools.analyzer.jvm/commit/e8510c21f0f1e0f8af4008b9b253783c15d9cac8</a></p>Global Rank[TANAL-47] t.a.j recent commit causes a particular source file to no longer throw exception for non-qualified type taghttp://dev.clojure.org/jira/browse/TANAL-47
tools.analyzer<p>For all I know, this might be intended behavior, but it was a change in the output of Eastwood that looked suspicious, so wanted to report it while the changes were fresh in your mind.</p>
<p>The attached bash shell script, after a bit of editing for the location of github repo clones on your local file system, should run and cause an exception to be reported during analysis of pantomime project namespace pantomime.media.</p>
<p>If you then change the line 'git checkout ${TAJ2}' to contain TAJ3 instead of TAJ2 and run it again, there is no exception for the same pantomime source file.</p>TANAL-47t.a.j recent commit causes a particular source file to no longer throw exception for non-qualified type tagDefectMinorClosedCompletedNicola MomettoAndy FingerhutWed, 8 Jan 2014 09:56:19 -0600Wed, 8 Jan 2014 10:32:41 -0600Wed, 8 Jan 2014 10:32:41 -060001<p>Not intentional, fixed: <a href="https://github.com/clojure/tools.analyzer.jvm/commit/de666b9203bdc73ccc1c557ff2c4c3a733803d9e">https://github.com/clojure/tools.analyzer.jvm/commit/de666b9203bdc73ccc1c557ff2c4c3a733803d9e</a></p>
<p>Thanks.</p>Global Rank[TANAL-46] Case tag handling is brokenhttp://dev.clojure.org/jira/browse/TANAL-46
tools.analyzerTANAL-46Case tag handling is brokenDefectMajorClosedCompletedNicola MomettoNicola MomettoWed, 8 Jan 2014 03:08:47 -0600Wed, 8 Jan 2014 06:42:44 -0600Wed, 8 Jan 2014 06:42:44 -060000<p><a href="https://github.com/clojure/tools.analyzer.jvm/commit/06646aa023c8db6c8e61640072d07cc648c73543">https://github.com/clojure/tools.analyzer.jvm/commit/06646aa023c8db6c8e61640072d07cc648c73543</a></p>Global Rank[TANAL-45] NPE in validate-loop-locals after recent changeshttp://dev.clojure.org/jira/browse/TANAL-45
tools.analyzer<p>This NullPointerException is new after the commits made to tools.analyzer(.jvm) in the last day or two, and only for some namespaces in the Eastwood crucible. A few examples are given below, with latest checked in Eastwood. The first one causes the exception earliest in the source file, so might be easier to debug than the other two, which occur several hundred lines into the source file.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">% lein eastwood '{:namespaces [ clojurewerkz.cassaforte.conversion ]}'
% lein eastwood '{:namespaces [ criterium.core ]}'
% lein eastwood '{:namespaces [ net.cgrand.enlive-html ]}'</pre>
</div></div>TANAL-45NPE in validate-loop-locals after recent changesDefectMinorClosedCompletedNicola MomettoAndy FingerhutTue, 7 Jan 2014 12:53:30 -0600Tue, 7 Jan 2014 13:06:46 -0600Tue, 7 Jan 2014 13:06:46 -060001<p><a href="https://github.com/clojure/tools.analyzer.jvm/commit/4f67b8c70a3754796bde91becabbb0947503f6dd">https://github.com/clojure/tools.analyzer.jvm/commit/4f67b8c70a3754796bde91becabbb0947503f6dd</a></p>Global Rank[TANAL-44] potemkin has unusual macro invocation that causes tools.analyzer.jvm to throw exceptionhttp://dev.clojure.org/jira/browse/TANAL-44
tools.analyzer<p>I am not sure whether tools.analyzer(.jvm) could/should analyze this kind of code successfully or not.</p>
<p>Steps to reproduce, using latest tools.analyzer(.jvm) and Eastwood as of Jan 6 2014 12:05am PST:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">% git clone https:<span class="code-comment">//github.com/ztellman/potemkin.git
</span>% cd potemkin
# The following gives no exception <span class="code-keyword">while</span> analyzing namespace potemkin
% lein eastwood '{:namespaces [ potemkin ]}'
# The following does <span class="code-keyword">throw</span> an exception <span class="code-keyword">while</span> analyzing namespace potemkin
% lein eastwood '{:namespaces [ potemkin.namespaces potemkin ]}'</pre>
</div></div>TANAL-44potemkin has unusual macro invocation that causes tools.analyzer.jvm to throw exceptionDefectMinorClosedCompletedNicola MomettoAndy FingerhutMon, 6 Jan 2014 02:07:35 -0600Mon, 6 Jan 2014 11:57:59 -0600Mon, 6 Jan 2014 09:34:58 -060001<p>Fixed: <a href="https://github.com/clojure/tools.analyzer/commit/6227561ceb1152e9984b96e60b4735e1deb1db42">https://github.com/clojure/tools.analyzer/commit/6227561ceb1152e9984b96e60b4735e1deb1db42</a></p><p>With this change, I now get an exception on many namespaces I did not before. I believe that the common denominator is that whenever a function calls itself, there is an exception similar to the following, where this particular example is from project stencil's namespace stencil.utils:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">% git clone https:<span class="code-comment">//github.com/davidsantiago/stencil.git
</span>% cd stencil
% lein eastwood
== Linting stencil.utils ==
Exception thrown during phase :analyze of linting namespace stencil.utils
UnsupportedOperationException count not supported on <span class="code-keyword">this</span> type: Symbol
clojure.lang.RT.countFrom (RT.java:556)
clojure.lang.RT.count (RT.java:530)
clojure.core/count (core.clj:832)
clojure.core/sort-by/fn--4299 (core.clj:2769)
clojure.lang.AFunction.compare (AFunction.java:49)
java.util.TimSort.countRunAndMakeAscending (TimSort.java:324)
java.util.TimSort.sort (TimSort.java:189)
java.util.TimSort.sort (TimSort.java:173)
java.util.Arrays.sort (Arrays.java:659)
clojure.core/sort (core.clj:2754)
clojure.core/sort-by (core.clj:2769)
clojure.core/sort-by (core.clj:2767)
clojure.tools.analyzer.utils/arglist-<span class="code-keyword">for</span>-arity (utils.clj:87)
clojure.tools.analyzer.passes.jvm.infer-tag/eval1970/fn--1972 (infer_tag.clj:221)</pre>
</div></div><p>I should make a habit of running the eastwood crucible before closing a ticket.<br/>
Should be fixed with <a href="https://github.com/clojure/tools.analyzer.jvm/commit/339abfa780fdef0de96100eedd0fbe3101dc26ad">https://github.com/clojure/tools.analyzer.jvm/commit/339abfa780fdef0de96100eedd0fbe3101dc26ad</a></p><p>Looking much better after the second fix. You are welcome to use the eastwood crucible for testing, but if you don't, I will <img class="emoticon" src="http://dev.clojure.org/jira/images/icons/emoticons/smile.gif" height="20" width="20" align="absmiddle" alt="" border="0"/> The whole list of projects takes over 30 mins on a reasonably recent laptop, and does not give pass/fail results, but a lot of output. I typically only notice things when the saved output of a previous lint.sh run is significantly different than the latest one.</p>Global Rank[TANAL-29] move the type-coercion logic from the emitter to a pass in the analyzerhttp://dev.clojure.org/jira/browse/TANAL-29
tools.analyzerTANAL-29move the type-coercion logic from the emitter to a pass in the analyzerEnhancementMajorClosedDeclinedNicola MomettoNicola MomettoSat, 14 Dec 2013 12:03:21 -0600Sun, 5 Jan 2014 15:29:34 -0600Sun, 5 Jan 2014 15:29:34 -060000Global Rank[TANAL-43] Suggestion: Throw exception for (var ...) forms unless they have exactly 1 arghttp://dev.clojure.org/jira/browse/TANAL-43
tools.analyzer<p>Clojure silently allows such expressions, too, but as far as I can see it ignores all args other than the first, similarly to throw and quote.</p>TANAL-43Suggestion: Throw exception for (var ...) forms unless they have exactly 1 argEnhancementTrivialClosedCompletedNicola MomettoAndy FingerhutFri, 3 Jan 2014 19:49:48 -0600Sat, 4 Jan 2014 13:02:01 -0600Sat, 4 Jan 2014 13:02:01 -060001<p>Fixed also for import*, monitor-enter, monitor-exit: <a href="https://github.com/clojure/tools.analyzer.jvm/commit/9eb1dd8dfd8d8058897f446551b1aa17cbd14f46">https://github.com/clojure/tools.analyzer.jvm/commit/9eb1dd8dfd8d8058897f446551b1aa17cbd14f46</a></p>Global Rank[TANAL-41] throw called with 2 argshttp://dev.clojure.org/jira/browse/TANAL-41
tools.analyzer<p>Clojure silently ignores args to throw after the 1st, but tools.analyzer throws an exception for them. Yes, we are going meta again, in that Eastwood caught this. See the proposed patch.</p>TANAL-41throw called with 2 argsDefectMinorClosedCompletedNicola MomettoAndy FingerhutFri, 3 Jan 2014 18:37:50 -0600Fri, 3 Jan 2014 18:42:46 -0600Fri, 3 Jan 2014 18:42:46 -060001<p>Awesome.<br/>
Fixed: <a href="https://github.com/clojure/tools.analyzer/commit/796a89277659cb722c028d9036619f46d41ecd83">https://github.com/clojure/tools.analyzer/commit/796a89277659cb722c028d9036619f46d41ecd83</a></p>Global RankPatchCode[TANAL-40] The :loop-locals keys are not updated in the uniquify-locals passhttp://dev.clojure.org/jira/browse/TANAL-40
tools.analyzer<p>Currently, the :loop-locals keys in :env are not updated to the new names in the uniquify-locals pass leaving the environment inconsistent with the ast.</p>TANAL-40The :loop-locals keys are not updated in the uniquify-locals passEnhancementMajorClosedCompletedNicola MomettoJonas EnlundFri, 3 Jan 2014 15:35:43 -0600Fri, 3 Jan 2014 15:40:41 -0600Fri, 3 Jan 2014 15:40:41 -060000<p>Merged: <a href="https://github.com/clojure/tools.analyzer/commit/b06fd1a17c1e8b0b0fbb108aeb63fa0623bddfbe">https://github.com/clojure/tools.analyzer/commit/b06fd1a17c1e8b0b0fbb108aeb63fa0623bddfbe</a></p>Global Rank[TANAL-39] Add :ast key back into exception data for validate-tag exceptionshttp://dev.clojure.org/jira/browse/TANAL-39
tools.analyzer<p>The ast in these exceptions is used by Eastwood to provide the user with some additional context for where the bad tags occur.</p>TANAL-39Add :ast key back into exception data for validate-tag exceptionsEnhancementMinorClosedCompletedNicola MomettoAndy FingerhutThu, 2 Jan 2014 18:07:32 -0600Thu, 2 Jan 2014 19:13:13 -0600Thu, 2 Jan 2014 19:13:13 -060001<p>Patch tanal-39-v1.diff is a simple one-liner.</p><p><a href="https://github.com/clojure/tools.analyzer.jvm/commit/1b5211bf47a9cdbca8013bb1eb8c38901206063b">https://github.com/clojure/tools.analyzer.jvm/commit/1b5211bf47a9cdbca8013bb1eb8c38901206063b</a></p>Global RankPatchCode[TANAL-38] tools.analyzer(.jvm) throws "Wrong number of args" exception for (= x y)http://dev.clojure.org/jira/browse/TANAL-38
tools.analyzer<p>With the latest tools.analyzer(.jvm) and Eastwood as of Dec 30 2013 10:45PM PST, a simple namespace like the following throws an exception when attempting to analyze it:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(ns eastwood.test.testcases.f10)
(defn foo [x y]
(= x y))</pre>
</div></div>
<p>Here are some details from the exception thrown:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">Exception thrown during phase :analyze of linting namespace eastwood.test.testcases.f10
Got exception with extra ex-data:
msg='Wrong number of args to ., had: 4'
(keys dat)=(:file :line :column :form)
(:form dat)=
(.
clojure.lang.Util
clojure.core/equiv
^{:line 4, :column 6, :end-line 4, :end-column 7} x
^{:line 4, :column 8, :end-line 4, :end-column 9} y)
ExceptionInfo Wrong number of args to ., had: 4
clojure.core/ex-info (core.clj:4327)
clojure.tools.analyzer/eval1729/fn--1731 (analyzer.clj:690)
clojure.lang.MultiFn.invoke (MultiFn.java:231)
clojure.tools.analyzer.jvm/eval3179/fn--3180 (jvm.clj:51)
clojure.lang.MultiFn.invoke (MultiFn.java:231)
clojure.tools.analyzer/eval1570/fn--1571 (analyzer.clj:227)
clojure.lang.MultiFn.invoke (MultiFn.java:236)
[ ... <span class="code-keyword">rest</span> of stack trace deleted ... ]</pre>
</div></div>TANAL-38tools.analyzer(.jvm) throws "Wrong number of args" exception for (= x y)DefectMajorClosedCompletedNicola MomettoAndy FingerhutTue, 31 Dec 2013 00:48:02 -0600Tue, 31 Dec 2013 08:58:15 -0600Tue, 31 Dec 2013 08:58:15 -060001<p>Fixed: <a href="https://github.com/clojure/tools.analyzer/commit/bb3a6bd0ae2541591eb8bf9b7686bf79aca1b143#diff-ca9fdc7850490879310292f81bfbb68fL687">https://github.com/clojure/tools.analyzer/commit/bb3a6bd0ae2541591eb8bf9b7686bf79aca1b143#diff-ca9fdc7850490879310292f81bfbb68fL687</a></p>Global Rank[TANAL-37] Tests written using simple-check might be problematic for tools.analyzerhttp://dev.clojure.org/jira/browse/TANAL-37
tools.analyzer<p>Discovered when trying to use the latest version of tools.analyzer(.jvm) and Eastwood on the automat library: <a href="https://github.com/ztellman/automat">https://github.com/ztellman/automat</a></p>
<p>I do not yet know whether this will be true of any project that uses simple-check for tests. I will add more to this description if I find other examples.</p>
<p>Below is the error message I see when running 'lein eastwood' in automat's project root dir:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">== Linting automat.core-simple-check ==
Exception thrown during phase :analyze of linting namespace automat.core-simple-chec
k
Got exception with extra ex-data:
msg='No such namespace: simple-check.core'
(keys dat)=(:ns)
ExceptionInfo No such namespace: simple-check.core
clojure.core/ex-info (core.clj:4327)
clojure.tools.analyzer.passes.jvm.validate/eval1616/fn--1618 (validate.clj:3
3)</pre>
</div></div>
<p>automat requires the namespaces simple-check.clojure-test, which defines a macro defspec that contains (require 'simple-check.core) here: <a href="https://github.com/reiddraper/simple-check/blob/master/src/simple_check/clojure_test.clj#L28">https://github.com/reiddraper/simple-check/blob/master/src/simple_check/clojure_test.clj#L28</a></p>
<p>along with a comment mentioning that this is a cyclic dependency.</p>
<p>This may be beyond what is reasonable to expect tools.analyzer(.jvm) to be able to handle, but wanted to get the example to you in case not.</p>TANAL-37Tests written using simple-check might be problematic for tools.analyzerDefectMinorClosedDeclinedNicola MomettoAndy FingerhutTue, 24 Dec 2013 22:26:00 -0600Wed, 25 Dec 2013 10:15:58 -0600Wed, 25 Dec 2013 08:54:21 -060001<p>It looks like it's an instance of the Gilardi Scenario.</p>
<p>There's nothing that can be done to fix this in the analyzer as a "fix" for this requires breaking up do expression and evaluating them piece by piece instead of analyzing the entire do form and evaluating it all in a single step.</p>
<p>This is how tools.emitter.jvm does it: <a href="https://github.com/clojure/tools.emitter.jvm/blob/master/src/main/clojure/clojure/tools/emitter/jvm.clj#L19-L26">https://github.com/clojure/tools.emitter.jvm/blob/master/src/main/clojure/clojure/tools/emitter/jvm.clj#L19-L26</a></p><p>So a question: Does such a construct become illegal in a future CinC implementation? I'm not arguing that it should become illegal, or should not, but if it should, it might be a good idea to mention it to the simple-check authors, and/or more Clojure devs.</p><p>I might have explained myself badly here.<br/>
tools.analyzer's behaviour in this case is exatly the same as clojure's one, and indeed clojure will fail on that expression too if all you do is call clojure.lang.Compiler/analyze on it.</p>
<p>clojure can eval that expression because it will analyze &amp; eval all the do forms separately &#8211; this is what tools.emitter.jvm does too.</p>
<p>if we want to analyze this expression in eastwood we need to manually analyze do forms separately too.</p>Global Rank[TANAL-36] Can this code avoid reflection and be analyzed by tools.analyzer?http://dev.clojure.org/jira/browse/TANAL-36
tools.analyzer<p>This is probably another variant of <a href="http://dev.clojure.org/jira/browse/TANAL-24" title="clojure.tools.analyzer.passes.jvm/validate throws an exception when :tag metadata cannot be resolved to a Class"><del>TANAL-24</del></a>, but I wanted to get the example to you for two reasons: (1) for me to learn how to type-hint this case correctly, if there is a way and (2) in case there was something new in this example that you haven't already seen.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(ns eastwood.test.testcases.f09
(:use clojure.test)
(:<span class="code-keyword">import</span> [java.io BufferedOutputStream])
(:require [clojure.java.io :as io]))
(set! *warn-on-reflection* <span class="code-keyword">true</span>)
(defmacro ^:<span class="code-keyword">private</span> bytestring
[s] `(.getBytes ~s <span class="code-quote">"UTF-8"</span>))
(def ^bytes bs-crlf (bytestring <span class="code-quote">"\r\n"</span>))
(defmacro ^:<span class="code-keyword">private</span> send-crlf [out] `(.write ~out bs-crlf 0 2))
(defn send-request [out]
(send-crlf out))</pre>
</div></div>
<p>As the subject says, I would like to know your thoughts on whether there is a way to type-hint this code such that the .write method invocation does not use reflection, and tools.analyzer(.jvm) can analyze it with no exception.</p>
<p>This test case was boiled down from some code in the ClojureWerkz Carmine library.</p>TANAL-36Can this code avoid reflection and be analyzed by tools.analyzer?DefectMinorClosedDeclinedNicola MomettoAndy FingerhutTue, 24 Dec 2013 14:39:04 -0600Tue, 24 Dec 2013 14:50:00 -0600Tue, 24 Dec 2013 14:50:00 -060001<p>This cannot be analyzed because of the def :tag bug I talked you about, (def ^bytes ..) will attach the clojure.core/bytes function in the :tag instead of 'bytes.</p>
<p>A way to fix this is to change it to (def ^{:tag 'bytes} ..)<br/>
The same holds for every primitive type hint in def.</p>
<p>To avoid the reflection warning ^BufferedOutputStream out in either send-request or send-crlf should work</p>Global Rank[TANAL-35] Two unit tests with incorrect parentheseshttp://dev.clojure.org/jira/browse/TANAL-35
tools.analyzer<p>These two unit tests are of the form (is (= expr1) expr2), which always passes without testing anything because (= expr1) is true.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(is (= '(. b (a c))) (emit-form (ast (.a b c))))
(is (= '(. b (a c))) (emit-form (ast (.a b (c)))))</pre>
</div></div>
<p>Found using the newest Eastwood linter, :suspicious-test</p>TANAL-35Two unit tests with incorrect parenthesesDefectMinorClosedCompletedNicola MomettoAndy FingerhutMon, 23 Dec 2013 18:24:20 -0600Mon, 23 Dec 2013 18:29:55 -0600Mon, 23 Dec 2013 18:29:55 -060001<p>Patch tanal-35-v1.diff not only fixes the parenthesization, but also changes the second test to add parens around (c) in the expected value. Please verify that is correct before applying the patch.</p><p>Fixed: <a href="https://github.com/clojure/tools.analyzer/commit/50c862a02662882f7fc2351659ea67753a5f49ea">https://github.com/clojure/tools.analyzer/commit/50c862a02662882f7fc2351659ea67753a5f49ea</a></p>
<p>We're going meta on this, thanks</p>Global Rank[TANAL-31] analyzing extend expression with non-constant type/class throws exceptionhttp://dev.clojure.org/jira/browse/TANAL-31
tools.analyzer<p>Here is an example that is slightly cut down from code in namespace seesaw.widgets.log-window, where I first saw the issue. It could be cut down a little more. The main point is that the first arg to extend-type is not a constant, but a fn call that returns a class:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(defn- log-window-proxy [state]
(proxy [javax.swing.JTextArea clojure.lang.IDeref] []
; Implement IDeref
(deref [] state)
; <span class="code-keyword">this</span> is how you disable auto-scrolling :(
(scrollRectToVisible [rect]
(<span class="code-keyword">if</span> @(:auto-scroll? state)
(proxy-<span class="code-keyword">super</span> scrollRectToVisible rect)))))
(defprotocol LogWindow
(log [<span class="code-keyword">this</span> message])
(clear [<span class="code-keyword">this</span>]))
(extend-type (class (log-window-proxy nil))
LogWindow
(log [<span class="code-keyword">this</span> message]
(println <span class="code-quote">"message"</span> message))
(clear [<span class="code-keyword">this</span>]
nil))</pre>
</div></div>TANAL-31analyzing extend expression with non-constant type/class throws exceptionDefectMinorClosedCompletedNicola MomettoAndy FingerhutSun, 15 Dec 2013 15:47:13 -0600Fri, 20 Dec 2013 09:43:35 -0600Fri, 20 Dec 2013 09:43:35 -060001<p>Yet another #<a href="http://dev.clojure.org/jira/browse/TANAL-24" title="clojure.tools.analyzer.passes.jvm/validate throws an exception when :tag metadata cannot be resolved to a Class"><del>TANAL-24</del></a> related bug.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(extend-type (class 1) proto (protof [<span class="code-keyword">this</span>]))</pre>
</div></div>
<p>extends to </p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(extend (class 1) proto {:protof (fn [^{:tag '(class 1)} <span class="code-keyword">this</span>])})</pre>
</div></div>
<p>And clojure swallows that silently.<br/>
It's not clear to me whether extend-type is supposed to work that way, but since the docstring says explicitely "Propagates the class as a type hint on the first argument of all fns." and this is clearly not true, I will consider this as a Clojure bug and fill a ticket.</p>
<p>I'll keep this ticket open too until #<a href="http://dev.clojure.org/jira/browse/TANAL-24" title="clojure.tools.analyzer.passes.jvm/validate throws an exception when :tag metadata cannot be resolved to a Class"><del>TANAL-24</del></a> gets resolved.</p><p>Clojure ticket: <a href="http://dev.clojure.org/jira/browse/CLJ-1308">http://dev.clojure.org/jira/browse/CLJ-1308</a></p>Global Rank[TANAL-30] Analyzing a function call with type-hinted ret value, where ret type is a class not imported in calling namespace, throws exceptionhttp://dev.clojure.org/jira/browse/TANAL-30
tools.analyzer<p>Shortest example I can find requires a Leiningen project with 2 namespaces.</p>
<p>File project.clj:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(defproject temp <span class="code-quote">"0.1.0-SNAPSHOT"</span>
:dependencies [[org.clojure/clojure <span class="code-quote">"1.5.1"</span>]])</pre>
</div></div>
<p>File src/temp/util.clj:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(ns temp.util
(:<span class="code-keyword">import</span> [java.awt Cursor]))
(defn foo ^Cursor []
(Cursor. Cursor/HAND_CURSOR))</pre>
</div></div>
<p>File src/temp/core.clj:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(ns temp.core
(:require [temp.util :as u]))
(defn foo [x]
[x (u/foo)])</pre>
</div></div>
<p>Eastwood throws exception when analyzing namespace temp.core because of the call to (u/foo). I haven't tried to reproduce it with only calls to tools.analyzer functions.</p>
<p>This is with the latest versions of all code checked in as of the time this ticket was created.</p>TANAL-30Analyzing a function call with type-hinted ret value, where ret type is a class not imported in calling namespace, throws exceptionDefectMinorClosedDeclinedNicola MomettoAndy FingerhutSun, 15 Dec 2013 00:08:32 -0600Fri, 20 Dec 2013 09:42:35 -0600Fri, 20 Dec 2013 09:42:35 -060001<p>This is strongly related to #<a href="http://dev.clojure.org/jira/browse/TANAL-24" title="clojure.tools.analyzer.passes.jvm/validate throws an exception when :tag metadata cannot be resolved to a Class"><del>TANAL-24</del></a> in that it works in clojure simply because Clojure discards the tag.<br/>
It actually doesn't really work in clojure when the :tag info is required, try:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(defn foo [] (.hashCode (u/foo)))</pre>
</div></div>
<p>It'll throw the ClassNotFoundException too.</p>
<p>I'll let this ticket open until we close #<a href="http://dev.clojure.org/jira/browse/TANAL-24" title="clojure.tools.analyzer.passes.jvm/validate throws an exception when :tag metadata cannot be resolved to a Class"><del>TANAL-24</del></a>, and will open a Clojure ticket fixing this behaviour since this is clearly a Clojure bug.</p>
<p>Thanks</p><p>Understood. For future reference, below is a list of namespaces where tools.analyzer throws an exception of this kind, with a very similar stack trace going through the following function call:</p>
<p> clojure.tools.analyzer.passes.jvm.emit-form/emit-form</p>
<p>I have not verified if the root cause in the source code is the same for all of them. The short example in the description was cut down from a case in the Seesaw library.</p>
<p>seesaw.widgets.log-window<br/>
seesaw.test.core<br/>
seesaw.test.examples.hotpotatoes<br/>
clojurewerkz.titanium.query<br/>
clojurewerkz.titanium.edges-test<br/>
clojurewerkz.titanium.element-test<br/>
clojurewerkz.titanium.graph-test<br/>
clojurewerkz.titanium.integration-test<br/>
clojurewerkz.titanium.types-test<br/>
clojurewerkz.titanium.vertices-test<br/>
flatland.useful.datatypes-test<br/>
flatland.useful.experimental-test<br/>
cljs.core.async.impl.ioc-macros<br/>
cljs.core.async.macros<br/>
clojure.core.async-test<br/>
clojure.core.match.test.core<br/>
clojure.core.match.test.date<br/>
clojure.core.match.test.java<br/>
clojure.data.codec.test-base64<br/>
clojure.data.fressian-test<br/>
clojure.java.test-jdbc<br/>
clojure.test.array-test<br/>
clojure.test.core-test<br/>
clojure.test.math-test<br/>
clojure.tools.namespace.dependency</p><p>clojure issue: <a href="http://dev.clojure.org/jira/browse/CLJ-1307">http://dev.clojure.org/jira/browse/CLJ-1307</a></p><p>I'm closing this since it's caused by a Clojure bug and on the tools.analyzer side it's related to #<a href="http://dev.clojure.org/jira/browse/TANAL-24" title="clojure.tools.analyzer.passes.jvm/validate throws an exception when :tag metadata cannot be resolved to a Class"><del>TANAL-24</del></a></p>Global Rank[TANAL-34] Throw more informative exception when parameter list contains namespace-qualified symbolshttp://dev.clojure.org/jira/browse/TANAL-34
tools.analyzer<p>Having more details in this exception would have helped in more quickly discovering the mistake in a Clojure source file being analyzed by Eastwood, where someone had a macro that used k# in most places for a parameter, but left out the # in one instance of it.</p>TANAL-34Throw more informative exception when parameter list contains namespace-qualified symbolsEnhancementMinorClosedCompletedNicola MomettoAndy FingerhutFri, 20 Dec 2013 09:24:57 -0600Fri, 20 Dec 2013 09:33:27 -0600Fri, 20 Dec 2013 09:33:27 -060001<p>Fixed: <a href="https://github.com/clojure/tools.analyzer/commit/31a58c280a5777acab5528ec48e10eff6ae007fa">https://github.com/clojure/tools.analyzer/commit/31a58c280a5777acab5528ec48e10eff6ae007fa</a></p>Global Rank[TANAL-33] Class/method call in macro in ns1 causes 'No such namespace' when used in ns2 that does not import the classhttp://dev.clojure.org/jira/browse/TANAL-33
tools.analyzer<p>I am hoping that this one is not yet another derivative of <a href="http://dev.clojure.org/jira/browse/TANAL-24" title="clojure.tools.analyzer.passes.jvm/validate throws an exception when :tag metadata cannot be resolved to a Class"><del>TANAL-24</del></a> <img class="emoticon" src="http://dev.clojure.org/jira/images/icons/emoticons/smile.gif" height="20" width="20" align="absmiddle" alt="" border="0"/></p>
<p>I tried to create a minimal test case but it didn't work. The quickest example I can give is to pull a clone of the quartzite library and use the latest tools.analyzer(.jvm) and Eastwood to analyze it. Several namespaces throw the exception during analysis, including clojurewerkz.quartzite.test.execution-test</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">% git clone https:<span class="code-comment">//github.com/michaelklishin/quartzite.git
</span>% cd quartzite
% lein eastwood
[ ... ]
Exception thrown during phase :analyze of linting namespace clojurewerkz.quartzite.test.execution-test
Got exception with extra ex-data:
msg='No such namespace: JobBuilder'
(keys dat)=(:ns)
ExceptionInfo No such namespace: JobBuilder
clojure.core/ex-info (core.clj:4327)
clojure.tools.analyzer.passes.jvm.validate/eval1613/fn--1615 (validate.clj:33)</pre>
</div></div>
<p>The basic problem seems to be that one namespace defines a macro that invokes (Class/method args), without a package name qualifier, but imports the class so it does not need one.</p>
<p>A second namespace invokes the macro, but does not import the class.</p>
<p>However, a minimal test case based on that pattern gave no error while using Eastwood on it, so there may be more conditions required than that for the exception to occur.</p>TANAL-33Class/method call in macro in ns1 causes 'No such namespace' when used in ns2 that does not import the classDefectMinorClosedCompletedNicola MomettoAndy FingerhutThu, 19 Dec 2013 23:39:09 -0600Fri, 20 Dec 2013 08:37:13 -0600Fri, 20 Dec 2013 08:37:13 -060000<p>Oddly enough this was a.. tools.reader bug<br/>
I'm pushing a new release that fixes the typo right now.</p>Global Rank[TANAL-32] Add more ex-data to exceptions thrown when validate-tag cannot find classhttp://dev.clojure.org/jira/browse/TANAL-32
tools.analyzer<p>This is useful for lint tools like Eastwood, or any others that wish to provide more detailed error messages that help a developer learn the reason that their code cannot be analyzed.</p>TANAL-32Add more ex-data to exceptions thrown when validate-tag cannot find classEnhancementMinorClosedCompletedNicola MomettoAndy FingerhutThu, 19 Dec 2013 16:19:37 -0600Thu, 19 Dec 2013 16:53:40 -0600Thu, 19 Dec 2013 16:53:40 -060001<p>Patch tanal-32-v1.diff is one way to achieve this. The ast node containing the failed-to-validate tag is the most useful. The :tag-kind can help the caller a bit in distinguishing the cause of the exception.</p><p>Fixed: <a href="https://github.com/clojure/tools.analyzer.jvm/commit/5c87ffaec5e317deaa8457d2f6de4a321f8c226e">https://github.com/clojure/tools.analyzer.jvm/commit/5c87ffaec5e317deaa8457d2f6de4a321f8c226e</a></p>
<p>Thanks</p>Global Rank[TANAL-9] AbstractMethodError exception when trying to get metadata on literal record in codehttp://dev.clojure.org/jira/browse/TANAL-9
tools.analyzer<p>I do not know if this is a problem with the analyzer, or something in Clojure itself, because attempting to pprint the read-in form with the problem record literal also causes it to throw an AbstractMethodError.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(ns tryanalyzer.try13)
(defrecord RecordTest [a b])
(defn mytest []
(= (RecordTest. 1 2)
#tryanalyzer.try13.RecordTest{:a 1, :b 2}))</pre>
</div></div>TANAL-9AbstractMethodError exception when trying to get metadata on literal record in codeDefectMajorClosedCompletedNicola MomettoAndy FingerhutThu, 28 Nov 2013 10:57:27 -0600Mon, 16 Dec 2013 08:27:12 -0600Wed, 11 Dec 2013 10:13:52 -060001<p>I'm sorry, I don't understand what's throwing here.<br/>
This works fine for me</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">clojure.tools.analyzer.jvm&gt; (defrecord RecordTest [a b])
clojure.tools.analyzer.jvm.RecordTest
clojure.tools.analyzer.jvm&gt; (analyze ^:foo #clojure.tools.analyzer.jvm.RecordTest{} (empty-env))
{:tag clojure.tools.analyzer.jvm.RecordTest, :children [:meta], :meta {:tag clojure.lang.IPersistentMap, :op :<span class="code-keyword">const</span>, :env {:context :expr, :ns clojure.tools.analyzer.jvm}, :type :map, :literal? т, :form {:foo т}}, :op :<span class="code-keyword">const</span>, :env {:context :expr, :ns clojure.tools.analyzer.jvm}, :type :record, :literal? т, :form #clojure.tools.analyzer.jvm.RecordTest{:a ∅, :b ∅}}</pre>
</div></div><p>Ok I understood what you mean.</p>
<p>This is not a bug, you need to evaluate the defrecord in order to be able to create an instance in read-time.</p>
<p>This is IIRC different than what Compiler.java does, as it compiled the record at analysis time instead of compile time, but it's by design that tools.analyzer/emitter separate evaluation from analysis..</p><p>Nicola, I am pretty sure that I am getting this error even though I am evaluating the defrecord before creating the instance.</p>
<p>Steps to reproduce: Install latest versions of tools.analyzer and tools.analyzer.jvm in your local Maven repo with 'lein install'. Then do the following steps to install locally the latest version of Eastwood I am testing with and seeing the issue:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">git clone git:<span class="code-comment">//github.com/jafingerhut/eastwood.git
</span>cd eastwood
git checkout <span class="code-keyword">try</span>-upgrade-to-tools.analyzer.jvm
LEIN_SNAPSHOTS_IN_RELEASE=1 lein install</pre>
</div></div>
<p>Then inside of a project that contains the namespace tryanalyzer.try13 in the description, perhaps renamed to whatever namespace you like, run this command:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">lein eastwood ':namespaces [tryanalyzer.try13]}'</pre>
</div></div>
<p>I get the AbstractMethodError thrown. Here are some function calls in the call stack, down to the part where I am calling eval on each form after analyzing, before reading and analyzing the next form in the file:</p>
<p>eastwood.core/run-eastwood</p>
<p>eastwood.core/lint-ns</p>
<p>eastwood.analyze-ns/analyze-ns</p>
<p>eastwood.analyze-ns/analyze-file - This was copied from jvm.tools.analyzer's function analyze-file, and then modified significantly. It is the one that calls Clojure's eval function after calling eastwood.jvm/analyze (below) on each form read from the file. It is the most likely place I would guess for there to be mistakes in the way I am calling analyze, in particular with its current choice of argument for the env.</p>
<p>eastwood.jvm/analyze - The comment at beginning of file indicates which file from tools.analyzer.jvm this is nearly an exact copy of.</p><p>I've investigated a bit on this after being able to reproduce, it looks like it's a classloader issue but it's not clear to me whether I'm doing something I'm not supposed to do or if it's a Clojure bug.</p>
<p>It should be noted that the issue is not there when trying on the repl.</p>
<p>I'll try to find a solution but my understanding of how clojure's dynamic classloader works is really basic so this might take me a while</p><p>OK, I pushed a fix: <a href="https://github.com/clojure/tools.analyzer.jvm/commit/feecc5be7e536ca6408cd7a2a48ac178cc7e25b9">https://github.com/clojure/tools.analyzer.jvm/commit/feecc5be7e536ca6408cd7a2a48ac178cc7e25b9</a></p>
<p>I don't like this fix at all, I have a better fix for this in my local eastwood branch but unfortunately it's not reliable (it doesn't work for e.g. (do (deftype x []) 1))</p>
<p>This'll have to do.</p><p>I think this issue is in the latest release of tools.analyzer(.jvm) again. Worth reopening?</p><p>Not the same issue, we've been hitten by this <a href="http://dev.clojure.org/jira/browse/CLJ-1105">http://dev.clojure.org/jira/browse/CLJ-1105</a> bug.</p>
<p>Fixed for &lt;=clojure-1.6.0-alpha3 with <a href="https://github.com/clojure/tools.analyzer/commit/4981916afb44dcdcc9d6866f46cb55287400213b">https://github.com/clojure/tools.analyzer/commit/4981916afb44dcdcc9d6866f46cb55287400213b</a></p>Global Rank[TANAL-2] Remove assumption about fn as top-level form from collect passhttp://dev.clojure.org/jira/browse/TANAL-2
tools.analyzer<p>Currently the collect pass assumes that every expression will be wrapped in a top-level fn, this is a JVM-specific assumption and should not be the case.</p>TANAL-2Remove assumption about fn as top-level form from collect passDefectMinorClosedCompletedNicola MomettoNicola MomettoMon, 18 Nov 2013 21:17:05 -0600Thu, 12 Dec 2013 16:54:49 -0600Thu, 12 Dec 2013 16:54:49 -060000<p>This was addressed by <a href="https://github.com/clojure/tools.analyzer/commit/ace0bf3d38f31c6cf2b531b2d439d74218db3d3e">https://github.com/clojure/tools.analyzer/commit/ace0bf3d38f31c6cf2b531b2d439d74218db3d3e</a></p>Global Rank[TANAL-28] validate-loop-locals introduces exponential slowdownhttp://dev.clojure.org/jira/browse/TANAL-28
tools.analyzerTANAL-28validate-loop-locals introduces exponential slowdownDefectCriticalClosedCompletedNicola MomettoNicola MomettoMon, 9 Dec 2013 10:20:38 -0600Tue, 10 Dec 2013 00:17:04 -0600Mon, 9 Dec 2013 20:15:52 -060000<p><a href="https://github.com/clojure/tools.analyzer.jvm/commit/5301a03e78c91fb43b282c03af07e3b40b4c5c4f">https://github.com/clojure/tools.analyzer.jvm/commit/5301a03e78c91fb43b282c03af07e3b40b4c5c4f</a><br/>
and<br/>
<a href="https://github.com/clojure/tools.analyzer.jvm/commit/956ad56fc0d54270931beb54e8cbe5acd3567fe9">https://github.com/clojure/tools.analyzer.jvm/commit/956ad56fc0d54270931beb54e8cbe5acd3567fe9</a></p>
<p>should have removed unnecessary iterations.</p><p>One set of measurements for comparison:</p>
<p>I measured the total time it took Eastwood to analyze its own source files (analysis only, not counting the time to run the linters), using tools.analyzer(.jvm), before these recent commits, and after.</p>
<p>Before, the total analysis time was 4.6 minutes. After, it was 1.0 minutes.</p>
<p>Thanks!</p>Global Rank[TANAL-27] No matching arity exception thrown when attempting to call fn with varargshttp://dev.clojure.org/jira/browse/TANAL-27
tools.analyzer<p>Test case to reproduce:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(require '[clojure.tools.analyzer.jvm :as aj])
(def env (aj/empty-env))
(def form (read-string "
(defn foo [a]
(let [err (fn [&amp; msg] (apply str msg))]
(err \<span class="code-quote">"Invalid arg 'a'\"</span> a)))
"))
(def an (aj/analyze form env))
;; Exception thrown by previous line</pre>
</div></div>TANAL-27No matching arity exception thrown when attempting to call fn with varargsDefectMinorClosedCompletedNicola MomettoAndy FingerhutSun, 8 Dec 2013 00:03:33 -0600Sun, 8 Dec 2013 18:38:41 -0600Sun, 8 Dec 2013 18:38:41 -060001<p>Fixed: <a href="https://github.com/clojure/tools.analyzer.jvm/commit/54a5ba2cb58f41399900f82376e732a49e4d7662">https://github.com/clojure/tools.analyzer.jvm/commit/54a5ba2cb58f41399900f82376e732a49e4d7662</a></p>Global Rank[TANAL-26] Var not found when using 'user' as aliashttp://dev.clojure.org/jira/browse/TANAL-26
tools.analyzer<p>The following snippet of code throws "clojure.lang.ExceptionInfo: no such var: user/union"</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(require '[clojure.set :as user]
'[clojure.tools.analyzer.jvm :as jvm])
(jvm/analyze 'user/union (jvm/empty-env))</pre>
</div></div>
<p>If I change the alias to something else it works as expected.</p>TANAL-26Var not found when using 'user' as aliasDefectMajorClosedCompletedNicola MomettoJonas EnlundFri, 6 Dec 2013 07:25:32 -0600Fri, 6 Dec 2013 07:37:15 -0600Fri, 6 Dec 2013 07:37:15 -060000<p>Fixed: <a href="https://github.com/clojure/tools.analyzer/commit/cf2b0e4fa19e1ecd42d33261859348850b9f31ec">https://github.com/clojure/tools.analyzer/commit/cf2b0e4fa19e1ecd42d33261859348850b9f31ec</a></p>Global Rank[TANAL-25] Exception for no matching method with clojure.main/repl-caught, but no exception with alias m/repl-caughthttp://dev.clojure.org/jira/browse/TANAL-25
tools.analyzer<p>This does not throw any exception:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(require '[clojure.tools.analyzer.jvm :as aj])
(require '[clojure.main :as m])
(def env (aj/empty-env))
(def form (read-string "
(defn foo [e]
(m/repl-caught e))
"))
(def an (aj/analyze form env))</pre>
</div></div>
<p>This does:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(require '[clojure.tools.analyzer.jvm :as aj])
(require 'clojure.main)
(def env (aj/empty-env))
(def form (read-string "
(defn foo [e]
(clojure.main/repl-caught e))
"))
(def an (aj/analyze form env))</pre>
</div></div>
<p>The only difference is the require line for clojure.main, and the alias m or the full namespace clojure.main for repl-caught.</p>TANAL-25Exception for no matching method with clojure.main/repl-caught, but no exception with alias m/repl-caughtDefectMinorClosedCompletedNicola MomettoAndy FingerhutWed, 4 Dec 2013 23:53:57 -0600Thu, 5 Dec 2013 09:00:17 -0600Thu, 5 Dec 2013 08:23:28 -060001<p>Fixed: <a href="https://github.com/clojure/tools.analyzer.jvm/commit/7008ae75f310dfc1a6446ae1941fde088d2bb36b">https://github.com/clojure/tools.analyzer.jvm/commit/7008ae75f310dfc1a6446ae1941fde088d2bb36b</a></p>
<p>Looks like if given foo.bar/baz, if foo.bar is both a class and a namespace (that is the case for clojure.main) clojure only considers it as a namespace.</p><p>Thanks for the update. The same test case in the description still give the same exception, unless I have messed something up.</p><p>Thanks for checking it out, I forgot to include a line of diff in the commit, I pushed the additional fix: <a href="https://github.com/clojure/tools.analyzer.jvm/commit/c295e3d285a5b4ec710b649cb7c12b169d05a802">https://github.com/clojure/tools.analyzer.jvm/commit/c295e3d285a5b4ec710b649cb7c12b169d05a802</a></p>Global Rank[TANAL-23] validate-loop-locals doesn't work for fnhttp://dev.clojure.org/jira/browse/TANAL-23
tools.analyzerTANAL-23validate-loop-locals doesn't work for fnDefectCriticalClosedCompletedNicola MomettoNicola MomettoWed, 4 Dec 2013 16:30:47 -0600Wed, 4 Dec 2013 17:33:02 -0600Wed, 4 Dec 2013 17:33:02 -060000<p>Fixed: <a href="https://github.com/clojure/tools.analyzer.jvm/commit/72a52fa058739b658f8838661a2f8f11e59c4f40">https://github.com/clojure/tools.analyzer.jvm/commit/72a52fa058739b658f8838661a2f8f11e59c4f40</a></p>Global Rank[TANAL-22] analyzer throws exception if fn called with wrong number of argshttp://dev.clojure.org/jira/browse/TANAL-22
tools.analyzer<p>Just analyze a simple form like this:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(defn bad-num-args [x]
(assoc))</pre>
</div></div>
<p>Clojure/JVM will throw an exception if you call it, but it will compile it without any errors. Not sure if this is a sign that eastwood the lint tool should be avoiding use of the validate phase.</p>TANAL-22analyzer throws exception if fn called with wrong number of argsDefectMinorClosedDeclinedNicola MomettoAndy FingerhutTue, 3 Dec 2013 18:24:36 -0600Tue, 3 Dec 2013 20:16:02 -0600Tue, 3 Dec 2013 19:00:13 -060001<p>Not a tools.analyzer bug, this is by design.</p>
<p>Note that Clojure/JVM too will throw on exception at compile time for some expressions e.g. (Integer/foo)</p>
<p>If this is undesiderable for eastwood, you can wrap c.t.a.j.p.validate/validate to catch said exception and return the AST.</p>
<p>I'm thinking something like</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(fn [ast]
(<span class="code-keyword">try</span> (validate ast)
(<span class="code-keyword">catch</span> ExceptionInfo e
(<span class="code-keyword">if</span> &lt;e is thrown by validate :invoke&gt;
ast
(<span class="code-keyword">throw</span> e)))))</pre>
</div></div><p>Does c.t.a.j.p.validate/validate make any changes to the ast, or only check a set of conditions and throw exceptions if those conditions are found to be true?</p>
<p>If it makes no changes to the ast, I am wondering if it would make any sense to have a way of invoking validate where it returns a sequence of maps representing all of the conditions for which it would normally throw an exception. A lint tool like eastwood could then search through that sequence and output a selected subset of them as warnings, in its own format.</p><p>It does change the AST.</p>
<p>For example, (-analyze 'java.lang.String (empty-env)) will return {:op :maybe-class :class 'java.lang.String ..}, validate over that AST will check whether "java.lang.String" can be resolved as a class, in that case it will transform the AST to {:op :class :class java.lang.String ..} (note that :class now is a Class, not a Symbol) otherwise it will throw a class not found exception.</p>
<p>I could try to decomplect the throwing from the validation behaviour of validate but I'm worried about the interaction of the non-validated nodes with the other passes.</p>
<p>Obviously to the specific case of :invoke it woulnd't make any difference, but some passes would probably crash on other nodes, expecting a Class on the :class field and instead finding a Symbol.</p>Global Rank[TANAL-21] java.class.name/staticStringMember works in Clojure/JVM with or without parens around it, but analyzer throws exception with parens around ithttp://dev.clojure.org/jira/browse/TANAL-21
tools.analyzer<p>I found similar code in namespace clojure.data.xml, and cut it down to get a smaller example. I am not sure if this is defined behavior or not, but both foo1 and foo2 return the same string value in Clojure, with no warning or error messages.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (require '[clojure.tools.analyzer.jvm :as aj])
nil
user=&gt; (def env (aj/empty-env))
#'user/env
user=&gt; (def form (read-string "
#_=&gt; (defn foo1 []
#_=&gt; javax.xml.transform.OutputKeys/INDENT)
#_=&gt; "))
#'user/form
user=&gt; (def an (aj/analyze form env))
#'user/an
user=&gt; (def env (aj/empty-env))
#'user/env
user=&gt; (def form (read-string "
#_=&gt; (defn foo2 []
#_=&gt; (javax.xml.transform.OutputKeys/INDENT))
#_=&gt; "))
#'user/form
user=&gt; (def an (aj/analyze form env))
CompilerException clojure.lang.ExceptionInfo: No matching method: INDENT <span class="code-keyword">for</span> class: class javax.xml.transform.OutputKeys and arity: 0 {:method INDENT, :class javax.xml.transform.OutputKeys, :argc 0}, compiling:(form-init8051492816641918211.clj:1:9)</pre>
</div></div>TANAL-21java.class.name/staticStringMember works in Clojure/JVM with or without parens around it, but analyzer throws exception with parens around itDefectMinorClosedCompletedNicola MomettoAndy FingerhutTue, 3 Dec 2013 16:23:05 -0600Tue, 3 Dec 2013 16:35:19 -0600Tue, 3 Dec 2013 16:35:19 -060001<p>Fixed: <a href="https://github.com/clojure/tools.analyzer.jvm/commit/2a6c5c08e251a085b6c26964c25ce47f72b95516">https://github.com/clojure/tools.analyzer.jvm/commit/2a6c5c08e251a085b6c26964c25ce47f72b95516</a></p>Global Rank[TANAL-20] Exception that validator cannot find method browsehttp://dev.clojure.org/jira/browse/TANAL-20
tools.analyzer<p>I am probably going to get lazy on the description of some of these. I won't get lazy on describing how to reproduce the issues I see, though. This one is excerpted from clojure.java.browse, and I've verified that the trimmed-down function actually works with Clojure 1.5.1.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (<span class="code-keyword">import</span> '(java.net URI))
java.net.URI
user=&gt; (require '[clojure.tools.analyzer.jvm :as aj])
nil
user=&gt; (def env (aj/empty-env))
#'user/env
user=&gt; (def form (read-string "
#_=&gt; (defn open-url-in-browser [url]
#_=&gt; (<span class="code-keyword">try</span>
#_=&gt; (-&gt; (clojure.lang.Reflector/invokeStaticMethod \<span class="code-quote">"java.awt.Desktop\"</span>
#_=&gt; \<span class="code-quote">"getDesktop\"</span> (to-array nil))
#_=&gt; (.browse (URI. url)))
#_=&gt; url
#_=&gt; (<span class="code-keyword">catch</span> ClassNotFoundException e
#_=&gt; nil)))
#_=&gt; "))
#'user/form
user=&gt; (def an (aj/analyze form env))
CompilerException clojure.lang.ExceptionInfo: No matching method: browse <span class="code-keyword">for</span> class: class java.lang.<span class="code-object">Object</span> and arity: 1 {:method browse, :class java.lang.<span class="code-object">Object</span>, :argc 1}, compiling:(form-init155566724550622590.clj:1:9)</pre>
</div></div>TANAL-20Exception that validator cannot find method browseDefectMinorClosedCompletedNicola MomettoAndy FingerhutTue, 3 Dec 2013 12:50:02 -0600Tue, 3 Dec 2013 15:11:36 -0600Tue, 3 Dec 2013 15:11:36 -060001<p>If these start getting too far into undefined/undocumented territory, feel free to let me know. I'm just feeding eastwood + tools.analyzer(.jvm) a large fraction of Clojure (but not clojure.core) and contrib libraries to see what it can and cannot handle.</p><p>Fixed: <a href="https://github.com/clojure/tools.analyzer.jvm/compare/6e1c9e4d601896c133b4a888dd165cc132cc2ae3...master">https://github.com/clojure/tools.analyzer.jvm/compare/6e1c9e4d601896c133b4a888dd165cc132cc2ae3...master</a></p>
<p>There's no need for you to waste your time trying to debug those any further, just open a ticket and I'll take care of it <img class="emoticon" src="http://dev.clojure.org/jira/images/icons/emoticons/smile.gif" height="20" width="20" align="absmiddle" alt="" border="0"/></p>
<p>Open a ticket for everything that runs fine in clojure but tools.analyzer fails to analyze, even if the cause may be the use of a undefined behaviour in clojure, I want to tools.analyzer to be <b>useful</b> and if this means supporting weird edge cases used by clojure, so be it.</p>
<p>Hopefully those will be fixed sometime in the future but as long as they are working in clojure, I want to support those.</p>
<p>#<a href="http://dev.clojure.org/jira/browse/TANAL-17" title="clojure.tools.analyzer.jvm/analyze fails to validate defprotocol expressions containing method names that begin with a dash"><del>TANAL-17</del></a> was an exception since the expression could compile in clojure but it would actually crash after a couple of evaluations.</p>
<p>Thanks again for the valuable testing/bug reporting </p>Global Rank[TANAL-19] clojure.tools.analyzer.jvm/analyze cannot find field or no-arg method 'close' for a FileOutputStreamhttp://dev.clojure.org/jira/browse/TANAL-19
tools.analyzer<p>That subject line is very likely way to specific to this test case &#8211; I have seen it for other stream and reader/writer types, too, and it is probably a more general issue than that. Here is a way to reproduce it at the REPL. The code is excerpted from clojure.java.io, and works fine with Clojure/JVM since 1.3 or maybe earlier.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(<span class="code-keyword">import</span> '(java.io InputStream File FileOutputStream))
(require '[clojure.tools.analyzer.jvm :as aj])
(def env (aj/empty-env))
(def form (read-string "
(defmulti <span class="code-keyword">do</span>-copy
(fn [input output opts] [(type input) (type output)]))
"))
(def an (aj/analyze form env))
(def env (aj/empty-env))
(def form (read-string "
(defmethod <span class="code-keyword">do</span>-copy [InputStream File] [^InputStream input ^File output opts]
(with-open [out (FileOutputStream. output)]
(<span class="code-keyword">do</span>-copy input out opts)))
"))
(def an (aj/analyze form env))
;; Exception output begins as follows, but flies off the screen due to
;; huge size of data attached to ex-info
;; ExceptionInfo cannot find field or no-arg method call clojure.core/close <span class="code-keyword">for</span> class class java.io.FileOutputStream</pre>
</div></div>TANAL-19clojure.tools.analyzer.jvm/analyze cannot find field or no-arg method 'close' for a FileOutputStreamDefectMinorClosedCompletedNicola MomettoAndy FingerhutTue, 3 Dec 2013 12:06:48 -0600Tue, 3 Dec 2013 12:15:17 -0600Tue, 3 Dec 2013 12:15:17 -060001<p>Fixed: <a href="https://github.com/clojure/tools.analyzer/commit/6dbcc7cac0995266f1624c00c1499ea0b2b32984">https://github.com/clojure/tools.analyzer/commit/6dbcc7cac0995266f1624c00c1499ea0b2b32984</a></p>
<p>This is clojure exploiting the undocumented behaviour that makes (. class ns/method) work as (. class method) :/</p>Global Rank[TANAL-18] clojure.tools.analyzer.jvm/analyze fails to validate defprotocol expressions containing method names having a dash in the middlehttp://dev.clojure.org/jira/browse/TANAL-18
tools.analyzer<p>This might be a dup of <a href="http://dev.clojure.org/jira/browse/TANAL-17" title="clojure.tools.analyzer.jvm/analyze fails to validate defprotocol expressions containing method names that begin with a dash"><del>TANAL-17</del></a>, but note that there is no dash at the beginning of the method name, only in the middle. The error goes away if I change the method name to asfile, with no dash in the middle.</p>
<p>I get the exception shown below with 1.6.0-alpha1, alpha2, or alpha3, with these steps, using latest tools.analyzer(.jvm). I get a different exception with 1.5.1, but still an exception.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (require '[clojure.tools.analyzer.jvm :as aj])
nil
user=&gt; (def form (read-string "(defprotocol ProtocolNameNotRedefd3
#_=&gt; (as-file [x]))"))
#'user/form
user=&gt; (def env (aj/empty-env))
#'user/env
user=&gt; (def an (aj/analyze form env))
CompilerException clojure.lang.ExceptionInfo: No matching method: as-file <span class="code-keyword">for</span> class: <span class="code-keyword">interface</span> user.ProtocolNameNotRedefd3 and arity: 0 {:method as-file, :class user.ProtocolNameNotRedefd3, :argc 0}, compiling:(form-init7336696426514759785.clj:1:9)</pre>
</div></div>TANAL-18clojure.tools.analyzer.jvm/analyze fails to validate defprotocol expressions containing method names having a dash in the middleDefectMinorClosedCompletedNicola MomettoAndy FingerhutTue, 3 Dec 2013 09:57:25 -0600Tue, 3 Dec 2013 10:14:54 -0600Tue, 3 Dec 2013 10:14:54 -060001<p>It was an unrelated issue: t.a.jvm.utils/members was not munging the method/field name.</p>
<p>Fixed: <a href="https://github.com/clojure/tools.analyzer.jvm/commit/f295f1298c17af1926f2f4262b8947c4ca10daf7">https://github.com/clojure/tools.analyzer.jvm/commit/f295f1298c17af1926f2f4262b8947c4ca10daf7</a></p>Global Rank[TANAL-17] clojure.tools.analyzer.jvm/analyze fails to validate defprotocol expressions containing method names that begin with a dashhttp://dev.clojure.org/jira/browse/TANAL-17
tools.analyzer<p>Reproduction test case:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (require '[clojure.tools.analyzer.jvm :as aj])
nil
user=&gt; (def form (read-string <span class="code-quote">"(defprotocol MyProt1 (bar [a b]))"</span>))
#'user/form
user=&gt; (def env (aj/empty-env))
#'user/env
user=&gt; (def an (aj/analyze form env))
#'user/an
user=&gt; (def form (read-string <span class="code-quote">"(defprotocol MyProt2 (-bar [a b]))"</span>))
#'user/form
user=&gt; (def an (aj/analyze form env))
ExceptionInfo cannot find field bar <span class="code-keyword">for</span> class <span class="code-keyword">interface</span> user.MyProt2 clojure.core/ex-info (core.clj:4327)</pre>
</div></div>TANAL-17clojure.tools.analyzer.jvm/analyze fails to validate defprotocol expressions containing method names that begin with a dashDefectMinorClosedCompletedNicola MomettoAndy FingerhutTue, 3 Dec 2013 07:28:45 -0600Tue, 3 Dec 2013 08:26:32 -0600Tue, 3 Dec 2013 08:26:32 -060001<p>This is actually a clojure bug, see <a href="http://dev.clojure.org/jira/browse/CLJ-1202">http://dev.clojure.org/jira/browse/CLJ-1202</a></p>
<p>This works for clojure &gt;=1.6.0-alpha1</p>Global Rank[TANAL-16] clojure.tools.analyzer.jvm/analyze fails to validate defmulti expressionshttp://dev.clojure.org/jira/browse/TANAL-16
tools.analyzer<p>I haven't tracked down exactly why yet, but my guess is that it is trying to resolve the var global-hierarchy, that appears in the macroexpansion of (defmulti foo :op), in the user namespace instead of clojure.core.</p>
<p>Steps to reproduce:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (require '[clojure.tools.analyzer.jvm :as aj])
nil
user=&gt; (def form (read-string <span class="code-quote">"(defmulti foo :op)"</span>))
#'user/form
user=&gt; (def env (aj/empty-env))
#'user/env
user=&gt; (def an (aj/analyze form env))
ExceptionInfo could not resolve <span class="code-keyword">var</span>: global-hierarchy clojure.core/ex-info (core.clj:4327)</pre>
</div></div>TANAL-16clojure.tools.analyzer.jvm/analyze fails to validate defmulti expressionsDefectMinorClosedCompletedNicola MomettoAndy FingerhutTue, 3 Dec 2013 07:05:12 -0600Tue, 3 Dec 2013 08:01:51 -0600Tue, 3 Dec 2013 08:01:51 -060001<p>Fixed: <a href="https://github.com/clojure/tools.analyzer/commit/fec1c8bf4d2cee0f986854b76f99147d631fe26d">https://github.com/clojure/tools.analyzer/commit/fec1c8bf4d2cee0f986854b76f99147d631fe26d</a></p>Global Rank[TANAL-15] analyze seems to assign incorrect name to some locals used in function bodieshttp://dev.clojure.org/jira/browse/TANAL-15
tools.analyzer<p>I am using latest master version of tools.analyzer(.jvm) as of Dec 1 2013 3:30pm PDT (after <a href="http://dev.clojure.org/jira/browse/TANAL-14" title="tools.analyzer (maybe tools analyzer jvm specific) looses the IChunk type hint in the expansion of doseq"><del>TANAL-14</del></a> fix went in).</p>
<p>Here is a reproduction test case:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(require '[clojure.tools.analyzer.jvm :as aj])
(def form (read-string "
(defn fn-with-unused-args3 [x y z]
(let [foo (fn [y z]
(* y z))]
(foo x y)))
"))
(def env (aj/empty-env))
(def an (aj/analyze form env))
(def meth1 (-&gt; an :init :methods first))
(def ret-expr-args (-&gt; meth1 :body :ret :body :ret :args))
(map :name (:params meth1))
;;=&gt; (x__#0 y__#0 z__#0)
(map :name ret-expr-args)
;;=&gt; (x__#0 y__#-1)</pre>
</div></div>
<p>The "y_<em>#-1" in the last output expression should be "y</em>_#0", I think, to match the arg y.</p>TANAL-15analyze seems to assign incorrect name to some locals used in function bodiesDefectMajorClosedCompletedNicola MomettoAndy FingerhutSun, 1 Dec 2013 17:34:09 -0600Sun, 1 Dec 2013 19:52:37 -0600Sun, 1 Dec 2013 19:52:37 -060000<p>This required a long due rewrite of the uniquify pass.<br/>
The logic is now much simpler and it works as expected.</p>
<p><a href="https://github.com/clojure/tools.analyzer/commit/e7e3a1a597640df62cf1e15dd0530f3fdcce2377">https://github.com/clojure/tools.analyzer/commit/e7e3a1a597640df62cf1e15dd0530f3fdcce2377</a></p>Global Rank[TANAL-14] tools.analyzer (maybe tools analyzer jvm specific) looses the IChunk type hint in the expansion of doseqhttp://dev.clojure.org/jira/browse/TANAL-14
tools.analyzer<p>looking at the output of running the analyzer on</p>
<p>(doseq <span class="error">&#91;i (range 10)&#93;</span> (println i))</p>
<p>the chunk local in the loop in the macro expansion of doseq his a tag of object, but if you look at the source of doseq, or manually do the macro expansion, the chunk local is type hinted as IChunk</p>TANAL-14tools.analyzer (maybe tools analyzer jvm specific) looses the IChunk type hint in the expansion of doseqDefectMajorClosedCompletedNicola MomettoKevin DowneySat, 30 Nov 2013 23:52:52 -0600Sun, 1 Dec 2013 13:43:04 -0600Sun, 1 Dec 2013 13:43:04 -060000<p>diff adds a failing test</p><p>it looks like -validate-loop-locals :loop is incorrectly mutating the ast?</p>
<p>if a a symbol doesn't have :tag metadata in the body of a loop, it tags the initial binding with Object</p><p>it occurs to me I could be wrong, maybe for some reason what is being passed to recur is not getting the correct tags?</p><p>ok, I think what is happening is when there is a loop where the initial binding is type hinted, and you have N branches in the body, and one of the branches recurs with a literal nil in place for the type hinted binding, validate-loop-locals removes the type hint from the initial binding</p><p>I looked into this, there are a couple of issues here.</p>
<p>The second loop local is tagged IChunk in the loop expr and in the first two recurs, but it's nil in the third.<br/>
The validate-loop mechanism is a bit naive there and just compares the tag and casts to Object when tags don't match.</p>
<p>This obviously need to be fixed.</p>
<p>Another issue that arised is that the third&amp;fourh args are sometime tagged as long and sometimes as int, and they both get casted to Object instead being treated as longs.<br/>
I need to fix this too.</p>
<p>A question that arises though is how exactly should the pass behave?<br/>
In Compiler.java recur mismatches are considered only for primitives, so this will compile (loop <span class="error">&#91;^String x &quot;&quot;&#93;</span> (if (= "" x) (recur 1) (.hashCode x))) but will result in a "ClassCastException java.lang.Long cannot be cast to java.lang.String user/eval1 (NO_SOURCE_FILE:1)" at runtime.</p>
<p>validate-locals tries to be smarter than that and validates not only primitives but also boxed objects, so that would compile to a Object#toString</p>
<p>For now, I'll change validate-locals to behave like Compiler.java does, I'll probably move the "smarter" behaviour of the current loop-locals pass to an additional optional pass.</p><p>Fixed: <a href="https://github.com/clojure/tools.analyzer.jvm/commit/143f19d049e6dc85ca67441c7c73c5e390aa861f">https://github.com/clojure/tools.analyzer.jvm/commit/143f19d049e6dc85ca67441c7c73c5e390aa861f</a></p>
<p>It's a compromise between the current Compiler.java approach and doing the right thing in case of boxed objects tag mismatch.</p>
<p>I changed your tests to return clojure.lang.IChunk instead of 'clojure.lang.IChunk</p>Global Rank[TANAL-13] tools.analyzer* seems to cause 2nd testing expr in clojure.core.async.ioc-macros-test to macroexpand incorrectlyhttp://dev.clojure.org/jira/browse/TANAL-13
tools.analyzer<p>I haven't figured out why yet, but when I use clojure.core/macroexpand to expand the following expression (from inside all of the definitions present in the latest master version of namespace clojure.core.async.ioc-macros-test):</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(runner ((fn [] 42)))</pre>
</div></div>
<p>it includes the following subexpression:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(clojure.core/let []
(fn* ([] 42)))</pre>
</div></div>
<p>However, when I use tools.analyzer* to analyze the same expression, it seems to macroexpand into the following instead, which throws an exception because it attempts to let-bind values to keywords:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(clojure.core/let
[:loop-locals :loop-locals
:namespaces :namespaces
:ns :ns
:locals :locals
:context :context
:name :name
:once :once
:in-<span class="code-keyword">try</span> :in-<span class="code-keyword">try</span>]
(fn* ([] 42)))</pre>
</div></div>TANAL-13tools.analyzer* seems to cause 2nd testing expr in clojure.core.async.ioc-macros-test to macroexpand incorrectlyDefectMinorClosedDeclinedNicola MomettoAndy FingerhutSat, 30 Nov 2013 11:32:35 -0600Sat, 30 Nov 2013 12:02:19 -0600Sat, 30 Nov 2013 12:02:19 -060001<p>This is because `runner` uses &amp;env.</p>
<p>Clojure's &amp;env is a map of local-sym -&gt; local-binding<br/>
tools.analyzer's &amp;env is a much richer map, I'm afraid that code that depends on &amp;env will never be compatible between clojure and tools.analyzer's default macroexpander.</p>
<p>If required however it's trivial to use a custom macroexpander with tools.analyzer that passes as &amp;env a localsym-&gt;localbinding map.</p>Global Rank[TANAL-12] fn* with multiple methods do not clear :in-try while analyzing their bodieshttp://dev.clojure.org/jira/browse/TANAL-12
tools.analyzer<p>When a fn* body has 2 or more methods, its bodies are analyzed with the same value of :in-try in the env as the (fn* ...) expression itself, so if that happens in the body of a try expression, recur statements within the fn* bodies incorrectly throw an assertion exception. Example:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(<span class="code-keyword">try</span>
(fn foo
([]
nil)
([x]
(<span class="code-keyword">if</span> (&lt; x 5)
(println x)
(recur (inc x)))))
(<span class="code-keyword">catch</span> Exception e
(println <span class="code-quote">"Exception occurred"</span>)))</pre>
</div></div>
<p>When the fn has only one method, the env correctly has no :in-try key at all, so no exception is thrown if there is a recur in the fn body.</p>TANAL-12fn* with multiple methods do not clear :in-try while analyzing their bodiesDefectMinorClosedCompletedNicola MomettoAndy FingerhutSat, 30 Nov 2013 02:17:34 -0600Sat, 30 Nov 2013 06:43:29 -0600Sat, 30 Nov 2013 06:43:29 -060001<p>Fixed: <a href="https://github.com/clojure/tools.analyzer/commit/53bca4fbc26f134427f3ba2736818fe12af3cb58">https://github.com/clojure/tools.analyzer/commit/53bca4fbc26f134427f3ba2736818fe12af3cb58</a></p>Global Rank[TANAL-5] replace tools.analyzer.jvm/empty-env :namespaces with a reified IPersistentMap http://dev.clojure.org/jira/browse/TANAL-5
tools.analyzer<p>Currently it's not possible to analyze </p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(require '[clojure.pprint :as pp]) pp/pprint</pre>
</div></div>
<p>using the same env, it is required to re-generate the environment every time an analyzed form is evaluated.</p>
<p>empty-env's :namespaces should not be a map, but a reify-backed map exposing clojure.lang.Namsespace fields</p>
TANAL-5replace tools.analyzer.jvm/empty-env :namespaces with a reified IPersistentMap DefectMajorClosedDeclinedNicola MomettoNicola MomettoWed, 27 Nov 2013 18:10:42 -0600Fri, 29 Nov 2013 09:11:21 -0600Fri, 29 Nov 2013 09:11:21 -060000<p>While something like <a href="http://sprunge.us/OgNP?clj">http://sprunge.us/OgNP?clj</a> could potentially work for reads, it would complicate everything a great deal for e.g assocs, it's easier to just need the regeneration of the environment after the evaluation of every form.</p>Global Rank[TANAL-11] cloure.tools.analyzer method -parse 'def has precondition that can be violatedhttp://dev.clojure.org/jira/browse/TANAL-11
tools.analyzer<p>Sorry, I haven't tried to cut this example down further. It is excerpted from the clojure.algo.monads contrib library.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(ns tryanalyzer.try16
(:use [clojure.tools.macro
:only (with-symbol-macros defsymbolmacro name-with-attributes)]))
(defmacro defmonadfn
"Like defn, but <span class="code-keyword">for</span> functions that use monad operations and are used inside
a with-monad block."
{:arglists '([name docstring? attr-map? args expr]
[name docstring? attr-map? (args expr) ...])}
[name &amp; options]
(let [[name options] (name-with-attributes name options)
fn-name (symbol (str *ns*) (format <span class="code-quote">"m+%s+m"</span> (str name)))
make-fn-body (fn [args expr]
(list (vec (concat ['m-bind 'm-result
'm-zero 'm-plus] args))
(list `with-symbol-macros expr)))]
(<span class="code-keyword">if</span> (list? (first options))
; multiple arities
(let [arglists (map first options)
exprs (map second options)
]
`(<span class="code-keyword">do</span>
(defsymbolmacro ~name (partial ~fn-name ~'m-bind ~'m-result
~'m-zero ~'m-plus))
(defn ~fn-name ~@(map make-fn-body arglists exprs))))
; single arity
(let [[args expr] options]
`(<span class="code-keyword">do</span>
(defsymbolmacro ~name (partial ~fn-name ~'m-bind ~'m-result
~'m-zero ~'m-plus))
(defn ~fn-name ~@(make-fn-body args expr)))))))
(defsymbolmacro m-bind m-bind)
(defmonadfn m-join
"Converts a monadic value containing a monadic value into a 'simple'
monadic value."
[m]
(m-bind m identity))</pre>
</div></div>
<p>The latest tools.analyzer lib throws an exception when attempting to evaluate the precondition on method -parse 'def:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(or (not (namespace sym))
(= *ns* (the-ns (namespace sym))))]}</pre>
</div></div>
<p>If I try to replace (namespace sym) with (symbol (namespace sym)), the precondition no longer throws an exception, but soon after the create-var call in the method does.</p>TANAL-11cloure.tools.analyzer method -parse 'def has precondition that can be violatedDefectMinorClosedCompletedNicola MomettoAndy FingerhutThu, 28 Nov 2013 14:49:02 -0600Thu, 28 Nov 2013 14:59:03 -0600Thu, 28 Nov 2013 14:59:03 -060000<p>Fixed: <a href="https://github.com/clojure/tools.analyzer/commit/309c9f9dd90bd777cc17be2b0f8d0e28cdf670da">https://github.com/clojure/tools.analyzer/commit/309c9f9dd90bd777cc17be2b0f8d0e28cdf670da</a></p>Global Rank[TANAL-10] #'test-name var not found inside of (deftest test-name ...)http://dev.clojure.org/jira/browse/TANAL-10
tools.analyzer<p>Simplified case found while analyzing a tools.nrepl test file:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(ns tryanalyzer.try15
(:use clojure.test))
(deftest update2
(str #'update2))</pre>
</div></div>TANAL-10#'test-name var not found inside of (deftest test-name ...)DefectMinorClosedCompletedNicola MomettoAndy FingerhutThu, 28 Nov 2013 12:37:39 -0600Thu, 28 Nov 2013 12:52:26 -0600Thu, 28 Nov 2013 12:52:26 -060000<p>Fixed: <a href="https://github.com/clojure/tools.analyzer/commit/1b88059e0c424ce2517370169908094900ebf253">https://github.com/clojure/tools.analyzer/commit/1b88059e0c424ce2517370169908094900ebf253</a></p>
<p>Looks like clojure.test relies on the (unspecified?) behaviour of clojure to evaluate def metadata after interning the var.</p>Global Rank[TANAL-7] clojure.tools.analyzer.jvm.utils/maybe-class can incorrectly return array classhttp://dev.clojure.org/jira/browse/TANAL-7
tools.analyzer<p>I came across this when trying to analyze namespace clojure.core.logic.fd, which has a protocol named IIntervals and another named IInterval. The first, when used in a deftype, was turned by maybe-class into an array of IInterval, on which eval threw an exception when trying to eval the resulting deftype* data structure.</p>
<p>It seems safer to include in the code a list of special type names for arrays, like there are now for "short", "byte", etc.</p>TANAL-7clojure.tools.analyzer.jvm.utils/maybe-class can incorrectly return array classDefectMajorClosedCompletedNicola MomettoAndy FingerhutThu, 28 Nov 2013 00:14:27 -0600Thu, 28 Nov 2013 06:09:16 -0600Thu, 28 Nov 2013 06:09:16 -060001<p>tanal-7-v1.diff is one way that seems to work.</p><p>fixed: <a href="https://github.com/clojure/tools.analyzer.jvm/commit/7f45f362168ea2ad176e5ffe066bd442db26e3f1">https://github.com/clojure/tools.analyzer.jvm/commit/7f45f362168ea2ad176e5ffe066bd442db26e3f1</a></p>
<p>Thanks a lot for the help Andy!</p>Global RankPatchCode[TANAL-8] No earmuff warnings for vars named * or **http://dev.clojure.org/jira/browse/TANAL-8
tools.analyzer<p>I think it would be better not to issue warnings about vars named * or **, even if they are not dynamic.</p>
<p>Clojure does not warn about *, and there is a recent patch that modifies it not to warn for **, either.</p>TANAL-8No earmuff warnings for vars named * or **DefectTrivialClosedCompletedNicola MomettoAndy FingerhutThu, 28 Nov 2013 00:26:33 -0600Thu, 28 Nov 2013 06:08:36 -0600Thu, 28 Nov 2013 06:08:36 -060001<p>Patch tanal-8-v1.diff should do the job.</p><p>Fixed: <a href="https://github.com/clojure/tools.analyzer/commit/2cfa02ed7fe23f36c373c9ff0fa5eb8d77b48038">https://github.com/clojure/tools.analyzer/commit/2cfa02ed7fe23f36c373c9ff0fa5eb8d77b48038</a></p>Global RankPatchCode[TANAL-6] infer-tag :local method throws NPE when trying to deref @atom (which is null)http://dev.clojure.org/jira/browse/TANAL-6
tools.analyzer<p>I haven't analyzed what is going wrong here beyond what is stated in the summary line, but I have reduced the test case I found down to a single function that isn't terribly long. There isn't much that can be removed from this test case without causing the exception to no longer be thrown.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(require '[clojure.tools.analyzer.jvm :as analyze-jvm])
(def form '(defn pprint-matrix []
(doseq [[i row] (map (fn [i] [i 1]) [5 6 7])]
(doseq [p (take i (range))]
(print p))
(print i))))
(analyze-jvm/analyze form (analyze-jvm/empty-env))</pre>
</div></div>TANAL-6infer-tag :local method throws NPE when trying to deref @atom (which is null)DefectMinorClosedCompletedNicola MomettoAndy FingerhutWed, 27 Nov 2013 18:42:32 -0600Wed, 27 Nov 2013 20:11:28 -0600Wed, 27 Nov 2013 20:11:28 -060001<p>Sorry, you may have already fixed this in master and I was not using the latest version when I hit this issue. Will close if I cannot reproduce with latest master of tools.analyzer and .jvm.</p><p>I can reproduce on master, I'll look into this, thanks!</p><p>This was a hard one but luckly the fix was easy.<br/>
Turns out the uniquify pass was doing some unnecessary operations that messed up some locals names, fixed with <a href="https://github.com/clojure/tools.analyzer/commit/ac5ccd7856eefef657495fe185082bf7bca9343c">https://github.com/clojure/tools.analyzer/commit/ac5ccd7856eefef657495fe185082bf7bca9343c</a> and <a href="https://github.com/clojure/tools.analyzer.jvm/commit/81c76490b76bfb98665f0f61d7ccda86d3b6d287">https://github.com/clojure/tools.analyzer.jvm/commit/81c76490b76bfb98665f0f61d7ccda86d3b6d287</a></p>Global Rank[TANAL-4] resolve-ns seems to resolve aliases incorrectlyhttp://dev.clojure.org/jira/browse/TANAL-4
tools.analyzer<p>I am not very familiar with the tools.analyzer code base, so double-check this analysis very carefully.</p>
<p>I was trying to read namespace clojure.core.match.debug using tools.analyzer, and it was throwing an exception:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">ExceptionInfo <span class="code-keyword">var</span> not found: pp/*print-pprint-dispatch* clojure.core/ex-info (core.clj:4355)</pre>
</div></div>
<p>Here are the first few lines of that namespace for reference:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(ns ^{:skip-wiki <span class="code-keyword">true</span>}
clojure.core.match.debug
(:refer-clojure :exclude [compile])
(:use [clojure.core.match.protocols]
[clojure.core.match
:only [emit-matrix compile occurrences
rows action-<span class="code-keyword">for</span>-row clj-form]])
(:require [clojure.pprint :as pp]))
(defn source-pprint [source]
(binding [pp/*print-pprint-dispatch* pp/code-dispatch
pp/*print-suppress-namespaces* <span class="code-keyword">true</span>]
(pp/pprint source)))</pre>
</div></div>
<p>I think this happens because fn <div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">clojure.tools.analyzer.utils/resolve-ns</pre>
</div></div> is not resolving aliased namespaces correctly.</p>TANAL-4resolve-ns seems to resolve aliases incorrectlyDefectMinorClosedCompletedNicola MomettoAndy FingerhutWed, 27 Nov 2013 17:44:58 -0600Wed, 27 Nov 2013 17:54:56 -0600Wed, 27 Nov 2013 17:54:56 -060001<p>Take this patch with a huge grain of salt until you've verified what it is doing yourself. As mentioned above, I am not very familiar with this code base &#8211; just trying it out analyzing various contrib libraries and seeing whether it works.</p><p>The current behaviour is clearly wrong and your patch is perfectly fine, thanks!</p>
<p>Fixed: <a href="https://github.com/clojure/tools.analyzer/commit/5441e5d916f664978fbd744c2f6209acb426155a">https://github.com/clojure/tools.analyzer/commit/5441e5d916f664978fbd744c2f6209acb426155a</a></p>Global RankPatchCode[TANAL-3] Get tools.analyzer.jvm to work on IBM JDK 1.6http://dev.clojure.org/jira/browse/TANAL-3
tools.analyzer<p>Currently some tests related to method validation fail on IBM JDK 1.6 for tools.analyzer.jvm, investigate and fix the cause.</p>TANAL-3Get tools.analyzer.jvm to work on IBM JDK 1.6DefectMajorClosedCompletedNicola MomettoNicola MomettoSun, 24 Nov 2013 09:58:06 -0600Tue, 26 Nov 2013 16:25:46 -0600Tue, 26 Nov 2013 16:25:46 -060000<p><a href="https://github.com/clojure/tools.analyzer.jvm/commit/25e3a0fece1d96bb261e026df08d08e73766e45d">https://github.com/clojure/tools.analyzer.jvm/commit/25e3a0fece1d96bb261e026df08d08e73766e45d</a></p>Global Rank[TANAL-1] bug in validate loop locals generates invalide asthttp://dev.clojure.org/jira/browse/TANAL-1
tools.analyzer<p>I am seeing valid asts being generate for some recur forms, some arguments to recur in the ast are a {:env ..} map, no :op or other information</p>
<p>I think the following is the source of the problem:</p>
<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>(defmethod -validate-loop-locals :recur
[_ {:keys [exprs env] :as ast}]
(if validating?
(let [casts (:loop-locals-casts env)]
(assoc ast
:exprs (mapv (fn [e c]
(if c (assoc e :tag c) c))
exprs (vals casts))))
ast))
</pre>
</div></div>
<p>if I change it to (return e if not c in the mapv)</p>
<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>(defmethod -validate-loop-locals :recur
[_ {:keys [exprs env] :as ast}]
(if validating?
(let [casts (:loop-locals-casts env)]
(assoc ast
:exprs (mapv (fn [e c]
(if c (assoc e :tag c) e))
exprs (vals casts))))
ast))
</pre>
</div></div>
<p>I get the information I expect in the ast</p>
TANAL-1bug in validate loop locals generates invalide astDefectMajorClosedCompletedNicola MomettoKevin DowneyTue, 12 Nov 2013 16:53:02 -0600Tue, 12 Nov 2013 17:00:25 -0600Tue, 12 Nov 2013 17:00:25 -060000<p>Fixed: <a href="https://github.com/clojure/tools.analyzer.jvm/commit/64f96fd5ef34d49db3a9c6cc4d009788ee3d2889">https://github.com/clojure/tools.analyzer.jvm/commit/64f96fd5ef34d49db3a9c6cc4d009788ee3d2889</a></p>Global Rank