Skip to content

Commit

Permalink
Make orchard.java.parser-utils/parse-java-test more easily debuggable
Browse files Browse the repository at this point in the history
We used to return nil for invalid .java source code.

Now we throw an exception, with the parsing error diagnostics as part of the ex-data.

Note that this doesn't change user-facing behavior, since all exceptions are caught by default in `orchard.java.parser/source-info` / `orchard.java.parser-next/source-info`.

This helps debug faulty .java source code, see e.g. aws/aws-sdk-java#3045
  • Loading branch information
vemv committed Oct 30, 2023
1 parent 4d99bf7 commit 2c451a1
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 7 deletions.
1 change: 1 addition & 0 deletions project.clj
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
[nubank/matcher-combinators "3.8.8"]]
:resource-paths ["test-resources"
"not-a.jar"
"test-java-invalid"
"does-not-exist.jar"]
:java-source-paths ["test-java"]
;; Initialize the cache verbosely, as usual, so that possible issues can be more easily diagnosed:
Expand Down
22 changes: 15 additions & 7 deletions src-newer-jdks/orchard/java/parser_utils.clj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
(:import
(java.io StringWriter)
(javax.lang.model.element VariableElement)
(javax.tools ToolProvider)
(javax.tools DocumentationTool DocumentationTool$DocumentationTask ToolProvider)
(jdk.javadoc.doclet Doclet DocletEnvironment)))

(def result (atom nil))
Expand All @@ -19,7 +19,7 @@
(when-let [res (io/resource path)]
(let [tmpdir (System/getProperty "java.io.tmpdir")
tmpfile (io/file tmpdir (.getName (io/file path)))
compiler (ToolProvider/getSystemDocumentationTool)
^DocumentationTool compiler (ToolProvider/getSystemDocumentationTool)
sources (-> (.getStandardFileManager compiler nil nil nil)
(.getJavaFileObjectsFromFiles [tmpfile]))
doclet (class (reify Doclet
Expand All @@ -39,11 +39,19 @@
"--show-module-contents" "all"
"-quiet"]
(when module
["--patch-module" (str module "=" tmpdir)]))]
(spit tmpfile (slurp res))
(.call (.getTask compiler out nil nil doclet opts sources))
(.delete tmpfile)
@result)))
["--patch-module" (str module "=" tmpdir)]))
slurped (slurp res)
_ (spit tmpfile slurped)
^DocumentationTool$DocumentationTask task (.getTask compiler out nil nil doclet opts sources)]
(try
(if (false? (.call task))
(throw (ex-info "Failed to parse Java source code"
{:path path
:module module
:out (str out)}))
@result)
(finally
(.delete tmpfile))))))

;;; ## Java Parse Tree Traversal
;;
Expand Down
10 changes: 10 additions & 0 deletions test-java-invalid/orchard/java/UnderscoreClass.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package orchard.java;

public class UnderscoreClass {

public UnderscoreClass(){
// Uses an underscore as identifier, which is no longer valid Java source code:
int _ = 52;
}

}
11 changes: 11 additions & 0 deletions test-newer-jdks/orchard/java/parser_next_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,24 @@
[clojure.test :refer [deftest is testing]]
[orchard.java :as java]
[orchard.java.parser-next :as sut]
[orchard.java.parser-utils :as parser-utils]
[orchard.test.util :as util])
(:import
(orchard.java DummyClass)))

(when (System/getenv "CI")
(println "has-enriched-classpath?" (pr-str util/has-enriched-classpath?)))

(when @@java/parser-next-available?
(deftest parse-java-test
(testing "Throws an informative exception on invalid code"
(try
(parser-utils/parse-java "orchard/java/UnderscoreClass.java"
nil)
(assert false)
(catch Exception e
(is (-> e ex-data :out (string/includes? "'_' is a keyword, and may not be used as an identifier"))))))))

(when (and util/has-enriched-classpath?
@@java/parser-next-available?)
(deftest source-info-test
Expand Down

0 comments on commit 2c451a1

Please sign in to comment.