ekeko technology showdown at sotesola 2012

13
Ekeko Applicative logic meta-programming using core.logic against Eclipse Coen De Roover Software Languages Lab Vrije Universiteit Brussel

Upload: coen-de-roover

Post on 29-Jul-2015

946 views

Category:

Technology


0 download

TRANSCRIPT

EkekoApplicative logic meta-programming

using core.logic against Eclipse

Coen De RooverSoftware Languages LabVrije Universiteit Brussel

identify code with characteristics of interest

data flow

control flow

structural

... commonly implemented by tool buildersApplication: program querying

{syntactic

corpus miner

idiom marker

tools

e..g., method returning null  public  List<Integer>  getChildren()  {           return  null;  }

public  List<Integer>  getChildren()  {           return  Collections.emptyList();}

e..g., method returning empty collection

idiom transformer

logic meta-programming

Ekeko

Eclipse plugin

applicationsprogram querying

program transformation

corpus mining

meta-programming library for Clojure’s core.logic

causally connected

applicative meta-programming

script queries over workspace

specify code characteristics declaratively, leave search to logic engine

manipulate workspace

select programs to

query

start REPL

launch query

browse results

... against Eclipse JDT using Clojure

Applicative meta-programming

rich in information: ASTs, semantics, structure

name

SimpleName

ASTNode

Statement

BodyDeclaration

extraDimensions

int

thrownExceptions

Name

returnType2

Type

parameters

SingleVariableDeclaration

constructor

boolean

body

Block

statements

typeParameters

TypeParameter

ReturnStatement

modifiers

IExtendedModifier

expression

Expression

MethodDeclaration

javadoc

Javadoc

Object

node

property

value kind

(spit  "jdt_docu_graph.dot"      (dot/dot  (graph  [MethodDeclaration                                      Block                                        ReturnStatement])))

... against Eclipse JDT using Clojure Applicative meta-programming

Lisp on JVM(defn      reduce-­‐projects!    "Clojure  reduce  over  all  projects  in  the  workspace.      Destructive  as  it  opens  and  closes  each  project  sequentially."    [f  initval  projects]    (reduce          (fn  [sofar  p]            (workspace-­‐project-­‐open!  p)            (workspace-­‐wait-­‐for-­‐builds-­‐to-­‐finish)            (let  [result  (f  sofar  p)]                (workspace-­‐project-­‐close!  p)                result))        initval        projects))

=>  (reduce-­‐projects!  (fn  [sofar  p]  (conj  sofar  (.getName  p)))                                          []                                          (workspace-­‐projects))["AmbientTalk20080201"  "DesignPatterns"  "DissertationExamples"  "JHotDraw51"  "JavaTemplatesUnitTests"  "MLIForSootUnitTests"  "jEdit"]

lambda

but what if we want to know more than the name of each project?

Java interop

Applicative logic meta-programming... specify code characteristics through Ekeko relations, leave search to core.logic

collection of all substitutions for ?s and ?e

such that the following Ekeko relations hold:

has/3 holds for :expression, ?s, and ?e

ast/2 holds for :ReturnStatement, ?s

ast/2 holds for :NullLiteral, ?e

(ekeko [?s ?e] (ast :ReturnStatement ?s) (has :expression ?s ?e) (ast :NullLiteral ?e))

?e is the value of the property named :expression

of ASTNode ?s

actual search performed by core.logic

([#<ReturnStatement return null; #<NullLiteral null>] ... [#<ReturnStatement return null; #<NullLiteral null>])

([?s1 ?e2] ... [?sn ?en])

Applicative logic meta-programming... core.logic in a nutshell

core

.logi

cembedding of logic programming

port of Kanren [Friedman, Kiselyov, Bird] to Clojure by David Nolen

no operational impurities (e.g., cut), yet high performance features tabling, extensible constraints, extensible unification protocols

composing goals

functions that take a substitution either return a possibly infinite stream of substitutions (success) or nil (failure)

logic goals

constructors: always success: s#, always failure: f#, success if arguments unify: ==

(fresh  [?x  ?y]      (==  ?x  ?y)      (==  ?x  5))

(fresh  [?x  ?y]      (conde          [(==  ?x  1)  ..]        [(==  ?x  5)  ..]))

(fresh  [?x]    (g  ?x))  

(defn  g  [?y]    (fresh  []          (==  ?y  5)))    

introduces lexically scoped variableschains goals together

interleaves substitutions from goals

abstraction

Applicative logic meta-programming... using relations provided by the Ekeko library

concerncharacteristics

data flow

control flow

structural{syntactic

JDT DOM

JDT Model

control flow graph

SOOT data flow analyses{derived

from

(defn      ast-­‐references-­‐may-­‐alias    [?ast1  ?ast2]    (fresh  [?set1  ?set2  ?model]        (ast-­‐reference-­‐soot-­‐model-­‐points-­‐to  ?ast1  ?model  ?set1)          (ast-­‐reference-­‐soot-­‐model-­‐points-­‐to  ?ast2  ?model  ?set2)        (succeeds  (.hasNonEmptyIntersection  ^PointsToSet  ?set1  ?set2))))

e.g. relation of all JDT reference-valued expressions that may alias at run-time

... in practice: specifying idiom characteristics incrementally

(defn    statement-­‐returning-­‐null    [?s]    (fresh  [?e]          (ast  :ReturnStatement  ?s)        (has  :expression  ?s  ?e)        (ast  :NullLiteral  ?e)))

(defn      method-­‐returning-­‐null-­‐for-­‐type    [?m  ?t]    (fresh  [?s]                  (statement-­‐returning-­‐null  ?s)                  (ast-­‐encompassing-­‐method  ?s  ?m)                  (has  :returnType2  ?m  ?t)))

Applicative logic meta-programming

query in reusable form

same, but with the return type of the enclosing method

(ekeko*  [?s  ?e]    (ast  :ReturnStatement  ?s)      (has  :expression  ?s  ?e)      (ast  :NullLiteral  ?e))

familiar query

supposed to subtype java.util.Collection

(defn    method-­‐returning-­‐null-­‐for-­‐ctype    [?method  ?ast-­‐type]    (fresh  [?k  ?c-­‐type  ?type]                  (type-­‐qualifiedname  ?c-­‐type  "java.util.Collection")                  (method-­‐returning-­‐null-­‐for-­‐type  ?method  ?ast-­‐type)                  (ast-­‐type-­‐type  ?k  ?ast-­‐type  ?type)                  (type-­‐super-­‐type  ?type  ?collection-­‐type))

(defn    method-­‐always-­‐returning-­‐null-­‐for-­‐ctype    [?m  ?t]    (fresh  [?cfg]                  (method-­‐returning-­‐null-­‐for-­‐ctype  ?m  ?t)                  (method-­‐cfg  ?m  ?cfg)                    (method-­‐cfg-­‐entry  ?m  ?entry)                  (qwal  ?cfg  ?entry  ?end  []

               (qall  (q=>*)

                             (qcurrent  [?return]                                  (statement-­‐returning-­‐null  ?s)))))))

... in practice: specifying idiom characteristics incrementallyApplicative logic meta-programming

what if there are many method exits?

same, but only if method returns a Collection type

same, but only if all paths through the method end in a return statement that returns null

universally quantified regular path expression: 0 or more transitions before reaching the end of the path, which has to be a statement returning null

Reinout Stevens’ damp.qwal

The idiom marker tool in action

continuously adds a marker next to ?m

Status

being ported from SOUL

but you can already give it a spin!https://github.com/cderoove/damp.ekeko