Skip to content
This repository has been archived by the owner on Nov 9, 2017. It is now read-only.

Commit

Permalink
now that we have riddley, this is maybe ready for primetime
Browse files Browse the repository at this point in the history
  • Loading branch information
ztellman committed Sep 18, 2013
1 parent ac0b365 commit 360cf8c
Show file tree
Hide file tree
Showing 15 changed files with 130 additions and 325 deletions.
7 changes: 7 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
language: clojure
lein: lein2
script: lein2 do clean, sleight test :make-odd, test :normal
jdk:
- openjdk7
- oraclejdk7
- openjdk6
73 changes: 64 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,69 @@
Sleight allows a transform function to be applied to all forms before they're read in by Clojure's compiler. This is a work in progress, but it will enable
![](docs/sleight.jpg)

* New control flow mechanisms
* Automatic instrumentation
* Test coverage metrics
* Many other things I haven't thought of
Sleight allows pervasive transforms to Clojure code, akin to wrapping all your code and the code in the libraries you depend on in the same macro.

Stay posted for updates.
### what is this good for?

## License
Possible uses include:

Copyright (C) 2012 Zachary Tellman
* language extensions
* pervasive inversion-of-control transforms
* automatic instrumentation
* test coverage metrics
* anything else you can dream up

Distributed under the Eclipse Public License, the same as Clojure.
### is this a good idea?

Maybe!

### how do I use it?

Sleight can be used via the `lein-sleight` plugin.

To use in all projects, add `[lein-sleight "0.2.0-SNAPSHOT"]` to the `:plugins` vector of your `:user` profile in `~/.lein/profiles.clj`.

To use for a specific project, add `[lein-sleight "0.2.0-SNAPSHOT"]` to the `:plugins` vector in `project.clj`.

---

Once this is done, define a transform in your project or one of its dependencies.

```clj
(def reverse-vectors
{:pre (fn [] (println "Get ready for some confusion..."))
:transform (fn [x] (riddley.walk/walk-exprs vector? reverse x))
:post (fn [] (println "That probably didn't go very well"))})
```

A transform is defined as a map containing one or more of the keys `:pre`, `:transform`, and `:post`. The `:pre` callback is invoked before the reader is hijacked to perform the transformation, the `:transform` function is passed each form as it's read it, and returns a modified form. The `:post` callback is invoked as the process is closed.

To perform safe code transformations, use [Riddley](https://github.com/ztellman/riddley).

Then, in your `project.clj`, add something like this:

```clj
(project your-project "1.0.0"
:sleight {:default {:transforms [a.namespace/reverse-everything]}
:partial {:transforms [a.namespace/reverse-everything]
:namespaces ["another.namespace*"]}})
```

The `:transforms` key maps onto a list of transforms, which are applied left to right. The `:namespaces` key maps onto a list of namespace filters, which confines the transformation to namespaces which match one of the filters.

`lein sleight` is not a standalone task, it's meant to modify other tasks. For instance, if we want to apply our transform to code while testing, we'd run:

```
lein sleight test
```

Since we haven't given a selector before the `test` task, the `:default` transform is selected. To specify the `:partial` transform, we'd run:

```
lein sleight :partial test
```

### license

Copyright (C) 2013 Zachary Tellman

Distributed under the MIT License
14 changes: 0 additions & 14 deletions README.textile

This file was deleted.

Binary file added docs/sleight.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
48 changes: 0 additions & 48 deletions lein-sleight/README.md

This file was deleted.

4 changes: 1 addition & 3 deletions lein-sleight/project.clj
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
(defproject lein-sleight "0.2.0-SNAPSHOT"
:description "A plugin for whole-program transformations via sleight"
:url "http://example.com/FIXME"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:license {:name "MIT License"}
:eval-in-leiningen true
:dependencies [[leinjacker "0.3.3"]])
15 changes: 4 additions & 11 deletions lein-sleight/src/leiningen/sleight.clj
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
;; Copyright (c) Zachary Tellman. All rights reserved.
;; The use and distribution terms for this software are covered by the
;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
;; which can be found in the file epl-v10.html at the root of this distribution.
;; By using this software in any fashion, you are agreeing to be bound by
;; the terms of this license.
;; You must not remove this notice, or any other, from this software.

(ns leiningen.sleight
(:require [leinjacker.eval :as eval]
[leinjacker.utils :as utils]))
(:require
[leinjacker.eval :as eval]
[leinjacker.utils :as utils]))

(defn arguments [args]
(if (and (first args)
Expand All @@ -21,7 +14,7 @@
(utils/merge-projects project {:dependencies [['sleight "0.2.0-SNAPSHOT"]]}))

(defn switch-form [transforms namespaces]
`(sleight.core/switch-reader
`(sleight.core/wrap-reader
(sleight.core/merge-transforms
~transforms
~namespaces)))
Expand Down
8 changes: 7 additions & 1 deletion project.clj
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
(defproject sleight "0.2.0-SNAPSHOT"
:description "whole-program transformations for clojure"
:dependencies [[org.clojure/clojure "1.4.0"]])
:dependencies []
:profiles {:dev {:dependencies [[org.clojure/clojure "1.5.1"]
[riddley "0.1.4"]]}}
:plugins [[lein-sleight "0.2.0-SNAPSHOT"]]
:sleight {:default {:transforms [sleight.transform-test/make-odd]}}
:test-selectors {:make-odd :make-odd
:normal (complement :make-odd)})
28 changes: 13 additions & 15 deletions src/sleight/core.clj
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
;; Copyright (c) Zachary Tellman. All rights reserved.
;; The use and distribution terms for this software are covered by the
;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
;; which can be found in the file epl-v10.html at the root of this distribution.
;; By using this software in any fashion, you are agreeing to be bound by
;; the terms of this license.
;; You must not remove this notice, or any other, from this software.

(ns sleight.core
(:require
[sleight.rt :as rt]))
Expand Down Expand Up @@ -55,6 +47,10 @@
transform)))

(defn merge-transforms
"Given a list of transform descriptors and namespaces in which they should be applied,
returns a merged descriptor which will only transform code within the specified namespaces.
If `namespaces` is nil, transforms will be applied to all namespaces."
[transforms namespaces]
(->> transforms
(map #(update-in % [:transform] (partial filtered-transform namespaces)))
Expand All @@ -65,7 +61,11 @@
:transform (merge-functions comp (:transform b) (:transform a))})
{})))

(defn switch-reader
(defn wrap-reader
"Takes a descriptor of a code transform consisting of a `:pre` no-arg callback that is
invoked before the transform, a `:transform` function which takes a form and returns
a modified form, and a `:post` no-arg callback which is invoked when the process is
terminated. All values are optional."
[{:keys [pre post transform]}]

(when pre
Expand All @@ -85,13 +85,11 @@
(.addShutdownHook (Runtime/getRuntime)
(Thread. post))))

(defn unswitch-reader
(defn unwrap-reader
"Returns the reader to its original state, undoing all invocations to wrap-reader."
[]
(alter-var-root #'clojure.core/load (constantly original-load))
(alter-var-root #'clojure.core/eval (constantly original-eval)))

(defmacro def-transform [name & {:as options}]
`(def ~name ~options))

(def-transform identity-transform
:transform identity)
(def identity-transform
{:transform identity})
8 changes: 0 additions & 8 deletions src/sleight/reader.clj
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
;; Copyright (c) Zachary Tellman. All rights reserved.
;; The use and distribution terms for this software are covered by the
;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
;; which can be found in the file epl-v10.html at the root of this distribution.
;; By using this software in any fashion, you are agreeing to be bound by
;; the terms of this license.
;; You must not remove this notice, or any other, from this software.

(ns sleight.reader
(:require
[clojure.java.io :as io])
Expand Down
8 changes: 0 additions & 8 deletions src/sleight/rt.clj
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
;; Copyright (c) Zachary Tellman. All rights reserved.
;; The use and distribution terms for this software are covered by the
;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
;; which can be found in the file epl-v10.html at the root of this distribution.
;; By using this software in any fashion, you are agreeing to be bound by
;; the terms of this license.
;; You must not remove this notice, or any other, from this software.

(ns sleight.rt
(:require
[sleight.reader :as reader]
Expand Down
Loading

0 comments on commit 360cf8c

Please sign in to comment.