1 / 21

Guarded Program Transformations Using JTL

Guarded Program Transformations Using JTL. Tal Cohen, Joseph (Yossi) Gil, Itay Maman (submitted to ECOOP’07) Presented by Oren Mishali. Introduction. A growing interest in using the logic paradigm to query code

elise
Download Presentation

Guarded Program Transformations Using JTL

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Guarded Program Transformations Using JTL Tal Cohen, Joseph (Yossi) Gil, Itay Maman (submitted to ECOOP’07) Presented by Oren Mishali

  2. Introduction • A growing interest in using the logic paradigm to query code • The paper describes a side-effect free technique of using the paradigm for the task of program transformation • The technique is presented as an extension to JTL • Every JTL predicate maintains a “baggage” string variable • Simple rules for computing the baggage of compound predicates • The baggage string is returned upon successful match

  3. The Basics

  4. Simple Baggage Management • The principle: any predicate returns the text of a Java code fragment which can be used for specifying the match “final” “final abstract” “public static int oldValue” “class Complex extends Number” “” “”

  5. Tautologies • Predicates which always hold • (Hence always produce output)

  6. Multiple Baggage • Suppressing the output of predicates: %public %static %final _ '?*'; %[public static final] _ '?*'; • A name of a Java class should begin with a lower case: testClassName := %2[ class '[a-z]?*' "begins with a lowercase letter." ]; testClassName := %2[class '[a-z]?*‘ "begins with a lowercase letter." ] | [class '?*‘ "is properly named."];

  7. String Literals • Multi-line strings: • Renaming a method/field: \[ private String oldName; private String newName; \] rename[Prefix] := modifiers _ prepend[Prefix] [ method (*) throwsList "{ #[torso] }"| field "= #[torso];“ ]; • Suppressing the padding space: class “New”+ ‘?*’ • The ‘#’ character: class "ChildOf"+ ['?*‘ is T] "extends #T“ prepend[Prefix] := "#Prefix“ +"#";

  8. Baggage Management in Quantifiers • Output members that violate the Java coding convention: badlyNamedClassMembers := %class %{[field|method] ‘[A-Z]?*’“is badly named.";%} • Pseudo quantifiers: optional_interfaces := implements: %{ first "implements"; exists _; between ","; last nothing; %} | nothing;

  9. Transformation examples

  10. Using JTL in an IDE and for Refactoring • Extracting the public protocol of a class: elicit_interface := %class -- Guard modifiers "interface“ prepend["P_"] { optional %public !static method header ";" ; }; • Generating a prototype implementation from an interface: defVal := %boolean "false" | %primitive "0" | %void nothing | "null";gen_class := %interface -- Guardmodifiers "class“ prepend["C_"] "implements #" {header \[ { return #[defVal]; } \]};

  11. Using JTL in an IDE and for Refactoring addEquals := %class header %[# is T] declares: {![boolean equals (Object)] declaration; last \[ @Override boolean equals(Object obj) { if (obj == null) return false; if (obj == this) return true; if (!obj.getClass().equals(this.getClass())) return false; #T that = (#T)obj; // downcast the parameter to the current type #[T.compareFields] // invoke helper predicate for field comparison return true; // all field comparisons succeeded } \]; compareFields := { -- generate field-comparison code %[primitive field, '?*‘ is Name] -- guard for primitive fields "if (this.#Name != that.#Name) return false;"; %[!primitive field, '?*‘ is Name] -- guard for reference fields "if (!this.#Name.equals(that.#Name)) return false;"; } } • Adding an equals method to a class:

  12. JTL as a Lightweight AOP language • Weaving a “before” advice to all public methods: loggingAspect := %class header declares: { targetMethod := public !abstract method; -- pointcut definition %targetMethod header \[ { System.out.println("Entering method #"); #[torso] } \] | declaration; } • What about other kinds of advices? • (around, after returning, after throwing etc.) • The answer is in the next slide…

  13. loggingAspect2 := %class header declares: { targetMethod := public !abstract method; -- pointcut definition } actualsAsString := %(first \[ "(" + \]; last \[ + ")" \]; between \[ + ", " + \];argName; -- at least one; iterate as needed%)| "()"; -- no arguments -- rename matching methods: %targetMethod rename["original_"] | declaration; %targetMethod header "{" %[ !void, _ is Return ] -- Guard for non-void methods \[ System.out.println("Entering #" + #[actualsAsString]); try { #Return result = #[prepend["original_"]] #[argNames]; } catch (Throwable e) { System.out.println("Exception: " + e); throw e; } System.out.println("Returned " + result); return result; \] • JTL AOP is limited to ‘execution’ pointcuts • Generated code is specific per method to which the advice is applied • No usage of runtime reflection • No boxing/unboxing | -- deal with void methods \[ System.out.println("Entering #Name“ + #[actualsAsString]); try { // Invoke the renamed original: #[prepend["original_"]] #[argNames]; } catch (Throwable e) { System.out.println("Exception: " + e); throw e; } \] ] "}";

  14. Templates, Mixins and Generics • Generating a SINGLETON class: singleton := "public" class "Singleton"+ '?*', %[# is T] { %[public constructor ()] | %2 "#T has no public zero-args constructor."; last \[ private Singleton#T() { } private static #T instance = null; public static #T getInstance() { if (instance == null) instance = new #T(); return instance; } \]; } • Cannot be implemented using Java generics • Is also superior to C++ template approach • Because requirements on the parameter are expressed explicitly

  15. Templates, Mixins and Generics • A guarded mixin-like transformation: undoMixin := "public" class [# is T] "Undoable#T extends #T" { %[!private void setName(String)] | %2 "#T has no matching setName method."; %[!private String getName()] | %2 "#T has no matching getName method."; all ![!private undo()] | %2 "Conflict with existing undo method."; last \[ private String oldName; public void undo() { setName(oldName); } public void setName(String name) { oldName = getName(); super.setName(name); } \]; }

  16. Non-Java Output • Persistence: mapping between a class and a relational database • In most modern systems mapping is defined using annotations: CREATE TABLE OWNER (id INTEGER PRIMARY KEY,firstName VARCHAR NOT NULL,lastName VARCHAR NOT NULL); … @Table class Account { @Id @Column long id; // Primary key @Column float balance; @ForeignKey @Column(name="OWNER_ID") Person owner; } @Table(name="OWNER") class Person { @Id @Column long id; @NotNull @Column String firstName; @NotNull @Column String lastName; }

  17. @Table(name="OWNER") class Person { @Id @Column long id; @NotNull @Column String firstName; @NotNull @Column String lastName; } CREATE TABLE OWNER (id INTEGER PRIMARY KEY,firstName VARCHAR NOT NULL,lastName VARCHAR NOT NULL); … generateDDL := %class "CREATE TABLE" tableName %{ first "("; last ")"; between ","; %[ @Column field ] => %sqlType | %2 ["Unsupported field type, field" '?*']; columnName sqlType sqlConstraints; %} sqlType := %String "VARCHAR“ | %integral "INTEGER“ | %real "FLOAT" | %boolean "ENUM('Y','N')" | %BigDecimal "DECIMAL(32,2)" | %Date "DATE" | foreignKey; columnName := [ %@Column(value=CName:STRING) "#CName" ]| [ %@Column() '?*' ]; --Default column name = field name …

  18. Related Work and Discussion

  19. JTL AOP • JTL views aspects as transformations of a software base • This perspective was presented earlier by Fradet and Sudholt • AST-based transformations: a richer set of join-points • LogicAJ: “the feature set of AspectJ can be completely mapped to a set of conditional program transformations” • JTL uses logic-based program transformation for weaving • Aspect-oriented logic meta-programming (AOLMP) • A very orderly approach, no free-form strings, easier to define and reason about aspects • JTL AOP is limited, “quick-and-dirty” AOP language • However, JTL is not limited to AOP!

  20. Output Validation • JTL is not “type-safe” • A JTL program p may generate a non-valid program • A general validation is undecidable, however: • proving that p always generates valid programs in a specific target language is possible • in order to prove that p always generates valid code: • Find the grammar Gp • Prove that L(Gp) L(G) • In JTL, Gp = p • It is possible and practical to decide if L(G) L(Gxml) • Hence, it is possible to validate JTL-XML program • In any case, JTL’s Java output is always processed by a Java compiler ∩ ∩

  21. Thanks!(in particular to Tal Cohen)

More Related