Skip to content

Instantly share code, notes, and snippets.

@ympbyc
Last active January 23, 2017 23:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ympbyc/114dc6550f7d55536b7926a7679c8c39 to your computer and use it in GitHub Desktop.
Save ympbyc/114dc6550f7d55536b7926a7679c8c39 to your computer and use it in GitHub Desktop.
Getting started with Typed Clojure's cljs checker!

Getting Started

Setup

  1. Clone this repository https://github.com/frenchy64/clojurescript/tree/tools.analyzer-ast
  2. Checkout the tools.analyzer.ast branch.
  3. lein install that branch.
  4. Now you should have [org.clojure/clojurescript "0.0-SNAPSHOT"] in your maven repo
  5. Clone typedclojure/core.typed
  6. git checkout ctyp-323-cljs

Running tests

lein test clojure.core.typed.test.cljs

;;nicer output
lein test clojure.core.typed.test.cljs 2> /dev/null | grep -A 5 "ERROR"

or in REPL

(ns clojure.core.typed.test.cljs)
(load "cljs")
(use 'clojure.test)
(run-tests)

Relevant Important Files

core.typed

  • module-cljs
    • /src/main/clojure/clojure/core/typed/
    • /src/test/clojure/clojure/core/typed/
      • cljs.clj : cljs checker test
    • /src/test/cljs/cljs/core/typed/
      • *.cljs: clojurescript sources to be checked for tests. called from cljs.clj
  • module-check
    • /src/main/clojure/clojure/core/typed/
      • check_form_common.clj
      • type-rep.clj : TCResult
      • check/
        • *.clj: check functions for individual forms e.g. check-let, check-vector, check-if ...
  • module-rt
    • /src/main/clojure/clojure/core/typed
      • current_impl.clj : (current-impl/v vsym) is used to resolve the qualified symbol into it's value
    • /src/main/clojure/cljs/core/
      • typed.clj : defines macros for cljs type checking, call to check-form-cljs/check-form-info originates from here

analyze_cljs.clj

frontend for 'cljs.analyzer/analyze.

  • analyze-cljs/ast-for-from applies to a form
  • analyze-cljs/ast-in-ns applies to a symbol

they evaluate to ASTs. The spec for the AST is here: http://clojure.github.io/tools.analyzer.jvm/spec/quickref.html

check_cljs.clj

Contains a generic function (check [expr & [expected]). check dispatches on the :op key of the given expr (AST subset). Many of the methods forwards the calls to 'clojure.core.typed.check.*

check adds the TCResult to the given AST subset.

check_form_cljs.clj

calls check_form_common.clj w/ a config map containing reference to the check-cljs/check and analyze-cljs/ast-for-form

check_form_common.clj

check-form-common/check-form-info it has a nice documentation comment below. is jus an excerpt:

;; Takes a configuration map which different implementations can customize
;; (via eg. clojure.core.typed.check-form-{clj,cljs}), a form to type check
;; and keyword arguments propagated from core.typed users

;; Default return map
;; - :ret TCResult inferred for the current form
;; - :out-form The macroexpanded result of type-checking, if successful.
;; - :result The evaluated result of :out-form, unless :no-eval is provided.
;; - :ex If an exception was thrown during evaluation, this key will be present
;; with the exception as the value.

clojurescript

  • src/main/clojure/cljs/
    • analyzer.cljc: (env, form, misc) -> AST
    • analyzer/api.cljc: Stable API for accessing analyzer cljc
    • env.cljc: *compiler* map/atom that contain "Any state needed by the compiler across multiple applications"

Typical signal path

   clojure.core.typed.test.cljs
-> cljs.core.typed/check-form-info
-> clojure.core.typed.check-form-cljs/check-form-info
-> clojure.core.typed.check-form-common/check-form-info
-> clojure.core.typed.analyze-cljs/ast-for-form | clojure.core.typed.check-cljs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment