+ All Categories
Home > Technology > Extension and Evolution

Extension and Evolution

Date post: 25-May-2015
Category:
Upload: eelco-visser
View: 633 times
Download: 3 times
Share this document with a friend
Description:
Model-driven software development lecture about techniques for customizing code generated from models.
Popular Tags:
61
Extension and Evolution IN4308 Model-Driven Software Development Lecture 12 Eelco Visser Software Engineering Research Group Delft University of Technology Netherlands May 25, 2010
Transcript
Page 1: Extension and Evolution

Extension and EvolutionIN4308

Model-Driven Software DevelopmentLecture 12

Eelco Visser

Software Engineering Research GroupDelft University of Technology

Netherlands

May 25, 2010

Page 2: Extension and Evolution

GPLprogram

GPLprogram compilecompile 'machine'

code

'machine'code

'model''design'

'model''design' codecode

Conventional Software Development

Page 3: Extension and Evolution

Conventional Software Maintenance

GPLprogram

GPLprogram

understandunderstand

'machine'code

'machine'code

'model''design'

'model''design' compilecompile

modifymodify

abstractions encoded in programmaintenance at low level of abstraction

Page 4: Extension and Evolution

GPLprogram

GPLprogram compilecompile 'machine'

code

'machine'codegenerategenerate

DSLprogram(model)

DSLprogram(model)

raise the level of abstraction to a technical or application domainautomatically generate implementation code from model

Model-Driven Software Development

Page 5: Extension and Evolution

modifymodify

maintenance on models instead of implementationimplementation regenerated after modification of models

Model-Driven Software Evolution

Page 6: Extension and Evolution

What makes a good DSL?

Page 7: Extension and Evolution

Expressivity

expressive dsl requires (much) less code than gpl implementationfewer lines of code = less implementation effort

Page 8: Extension and Evolution

Coverage

dsl covers a subset of programs in the target languagegenerator is not surjective

Page 9: Extension and Evolution

Completeness

incomplete code generation produces programs with holesto be filled in by developer

Page 10: Extension and Evolution

Portability

dsl-to-csharpdsl-to-csharp

abstract over the target domaingenerate code for multiple platforms from same model

C#C#

JavaJavadsl-to-javadsl-to-java

Page 11: Extension and Evolution

Code Quality

does generator produce robust and correct code?are errors detected early in the translation pipeline?

model verification is preferable over debugging target code

Page 12: Extension and Evolution

DSL Engineering Dimensions

● expressivity

● coverage

● completeness

● portability

● code quality

● evolution

Page 13: Extension and Evolution

Coverage

dsl covers a subset of programs in the target languagegenerator is not surjective

not all target programs are reachable

Page 14: Extension and Evolution

Coverage of 'Interesting' Programs

targeting representatives of equivalence classescan we reach all equivalence classes?

Page 15: Extension and Evolution

Program Equivalence

when are two programs the same?

Many programs are the same if we abstract over 'implementation details'.

Page 16: Extension and Evolution

Program Equivalence

Two programs are the same if they have the same

- behaviour- userinterface- effects on the database- performance

What is the meaning of 'same'?

Abstract over non-important differences

Implementation details(e.g. order of statements does not always matter)

Look and feel

Page 17: Extension and Evolution

Reasons for Lack of Coverage

Completeness

only part of the domain is covered

Example: domain model vs business logic

80/20 rule : generate 80%, write 20%

Tuning

the generated code is not exactly what is desired

Page 18: Extension and Evolution

Customization of Generated Code

not all customizations can be realized in models generated code may need to be adapted

modify

Page 19: Extension and Evolution

Scaffolding (aka Fill in the Blanks)

incomplete code generation produces programs with holesto be filled in by developer

Page 20: Extension and Evolution

Scaffolding (aka Fill in the Blanks)

'boilerplate code' is generated'business methods' should be

filled in by developer

PublicationPublication

title : Stringauthors → List<Author>journal → Journal

title : Stringauthors → List<Author>journal → Journal

citation() : Stringcitation() : String

public class Publication { Private String _title; Public String getTitle() { Return _title; } Public void setTitle(x : String) { _title := x; } … getters, setters for authors, journal … Public String citation() { // fill in code }

}

public class Publication { Private String _title; Public String getTitle() { Return _title; } Public void setTitle(x : String) { _title := x; } … getters, setters for authors, journal … Public String citation() { // fill in code }

}

Page 21: Extension and Evolution

Scaffolding Breaks Evolution

if model and code are modified, how do we merge the results?

??

modifymodify

modifymodify ??

Page 22: Extension and Evolution

Protected Regions

generator preserves 'protected regions'does not support unanticipated tuning

breaks generator encapsulation by exposing implementation

modifymodifymodifymodify

modifymodify

modifymodify

copycopy

copycopy

Page 23: Extension and Evolution

Protected Regionspublic void openUserScreenShowPersons() { ShowPersonsScreenComposite showPersonsScreen = new ShowPersonsScreenComposite(mainController.getShowPersonsScreenContainer() .getScreenParent(), this); /*PROTECTED REGION ID(ShowPersons_game_behavior_usecases_persons_ScreenComposite) ENABLED START*/ showPersonsScreen.personList.add("Marcy"); showPersonsScreen.personList.add("Freddy"); showPersonsScreen.personList.add("Mary-Anne"); /*PROTECTED REGION END*/ mainController.getShowPersonsScreenContainer() .showScreen(showPersonsScreen); // next step called by gui to transition...() method}public void systemCallEnd() { /*PROTECTED REGION ID(systemCall_game_behavior_usecases_personsend) ENABLED START*/ // TODO: perform activity mainController.getShowPersonsScreenContainer().getShell().close(); /*PROTECTED REGION END*/ }

Source: http://public.tfh-berlin.de/~petrasch/uploads/media/TU_MDAPetrasch_110907.pdf

Page 24: Extension and Evolution

Roundtrip Engineering

extract model from modified codecan changes to code be reflected in model?

implies lack of abstraction

modifymodify

Page 25: Extension and Evolution

Roundtrip Engineering

Make changes to model and codecan changes to code be reflected in model?

implies model/code bijection

modifymodify

modifymodify

preserve?preserve?

Page 26: Extension and Evolution

Tuning Generated Code

default pretty-print rules can be generated; tuning needed to get it right general: skeleton for user interface from data model need tuning

Entity -- KW["entity"] _1 KW[":"] _2 KW["{"] _3 _4 KW["}"]

Entity -- V[V is=2[H[KW["entity"] _1 KW[":"] _2 KW["{"]] _3 _4] KW["}"]]

"entity" Id ":" Id "{" Property* Function* "}" -> Entity {cons("Entity")}

Page 27: Extension and Evolution

Customization 'From the Outside'

customization should never require direct modification of generated code customization code must modify/interact with generated code

what is the interface? avoid exposing generation scheme

Page 28: Extension and Evolution

Customization with Partial Classes

partial class extends generated class without modifying generated files

inputs

Page 29: Extension and Evolution

Customization with Partial Classes

public partial class Publication { // generated code; don't change private Author _author; public Author getAuthor () { return _author; } }

public partial class Publication { // generated code; don't change private Author _author; public Author getAuthor () { return _author; } }

public partial class Publication { public String citation() { ... if(this.getAuthor() != null) { c := c + getAuthor().getName() } ... } }

public partial class Publication { public String citation() { ... if(this.getAuthor() != null) { c := c + getAuthor().getName() } ... } }

entity Publication { Author → Author …}

entity Publication { Author → Author …}

Page 30: Extension and Evolution

Evolution with Partial Classes

examples: pp tables, styling

modifymodify

????

Page 31: Extension and Evolution

Customization with Inheritance

class GenPublication { // generated code; don't change private Author _author; public Author getAuthor () { return _author; } }

class GenPublication { // generated code; don't change private Author _author; public Author getAuthor () { return _author; } }

class Publication extends GenPublication { public String citation() { ... if(this.getAuthor() != null) { c := c + getAuthor().getName() } ... } }

class Publication extends GenPublication { public String citation() { ... if(this.getAuthor() != null) { c := c + getAuthor().getName() } ... } }

entity Publication { Author → Author …}

entity Publication { Author → Author …}

gen default

Page 32: Extension and Evolution

Generate Subsystem

generated code is called from regular code

Page 33: Extension and Evolution

Calling Stratego from C

module foobar

strategies

foo = innermost(Foo <+ Bar)

module foobar

strategies

foo = innermost(Foo <+ Bar)

#include “foobar.h”

void main() { ATerm t = parse(file); t = foo_0_0(NUL, t); ...}

#include <strinclude.h>

ATerm foo_0_0(StrSL sl, Aterm t) { t = innermost_1_0(...); return t;}

calling convention should be fixed, implementation is hidden

Page 34: Extension and Evolution

Model/Code Interaction

customization code should be considered as part of the generator inputshould interact with (interface of) models, not with generated code

Page 35: Extension and Evolution

Built-in Types

make external code available through type abstraction to modelbuilt-in types capture domain-specific functionality

Aimpl a;x.a.f()

Aimpl a;x.a.f()

a :: Af(x.a)

a :: Af(x.a)

class Aimpl { f() {…}}

class Aimpl { f() {…}}

Page 36: Extension and Evolution

Built-in Types: Patch

entity PageDiff { page -> Page next -> PageDiff title :: String patch :: Patch created :: Date previous -> PageDiff date :: Date author -> User version :: Int}

extend entity Page {function makeChange(.., newText : WikiText,...) : Page { PageDiff { ... patch := newText.makePatch(this.content) ... }}}extend entity PageDiff { function computeContent() : WikiText { if (next = null) { return patch.applyPatch(page.content); } else { return patch.applyPatch(next.content); } }

Page 37: Extension and Evolution

Foreign Function Interface

declare functions/types available in 'native' libraries

call fcall f

prim(f)prim(f)def fdef f

Page 38: Extension and Evolution

Foreign Function Interface

Primitives in Stratego allow calling (wrapped) native functions.

epoch2local-time = ?EpochTime(t) ; prim("SSL_epoch2localtime", t) ; prim-tuple-to-ComponentTime

epoch2local-time = ?EpochTime(t) ; prim("SSL_epoch2localtime", t) ; prim-tuple-to-ComponentTime

Page 39: Extension and Evolution

Multi Models

Page 40: Extension and Evolution

Multiple Models / Multiple DSLs

split model into several modelscombine DSLs to increase coverage

Page 41: Extension and Evolution

CC CC

YACCYACCLEXLEX

LEX: lexical analysis with regular grammarsYACC: context-free analysis with context-free grammars

Multiple Models / Multiple DSLs

Page 42: Extension and Evolution

Multiple Models / Multiple DSLs

ChecksChecksJPAJPA ServletsServlets

UIUIDMDM ACAC

DM: data modelUI: user interface

AC: access control

Page 43: Extension and Evolution

Model/Model Interaction

consider models as components / moduleswhat is interface of a model? what is the scope of model elements

model encapsulation; separate compilation

Page 44: Extension and Evolution

LEX & YACC

"PRINT" { return PRINT; }[0-9]+ { yylval = atoi(yytext); return NUMBER; }[a-z] { yylval = yytext[0] - 'a'; return NAME; } \ { ; }\n { nextline(); }\t { ; }"//".*\n { nextline(); }. { yyerror("illegal token"); }

"PRINT" { return PRINT; }[0-9]+ { yylval = atoi(yytext); return NUMBER; }[a-z] { yylval = yytext[0] - 'a'; return NAME; } \ { ; }\n { nextline(); }\t { ; }"//".*\n { nextline(); }. { yyerror("illegal token"); }

statement: designator ASSIGN expression | PRINT expression | IF expression THEN stmtseq ELSE stmtseq FI | IF expression THEN stmtseq FI | WHILE expression DO stmtseq OD ;

statement: designator ASSIGN expression | PRINT expression | IF expression THEN stmtseq ELSE stmtseq FI | IF expression THEN stmtseq FI | WHILE expression DO stmtseq OD ;

Page 45: Extension and Evolution

lexical syntax [a-zA-Z][a-zA-Z0-9\_]* -> Id [a-zA-Z0-9\-\_]+ -> FileName {FileName "/"}+ -> ModuleName ~[\n\r]* -> SectionName context-free syntax "{" Statement* "}" -> Block {cons("Block")} Block -> Statement "var" Id ":" Sort ";" -> Statement {cons("VarDecl")} Exp ";" -> Statement {cons("Stat")} "return" Exp ";" -> Statement {cons("Return")}

context-free syntax "module" ModuleName Section* -> Module {cons("Module")} "imports" ModuleName -> Definition {cons("Imports")}

lexical syntax [a-zA-Z][a-zA-Z0-9\_]* -> Id [a-zA-Z0-9\-\_]+ -> FileName {FileName "/"}+ -> ModuleName ~[\n\r]* -> SectionName context-free syntax "{" Statement* "}" -> Block {cons("Block")} Block -> Statement "var" Id ":" Sort ";" -> Statement {cons("VarDecl")} Exp ";" -> Statement {cons("Stat")} "return" Exp ";" -> Statement {cons("Return")}

context-free syntax "module" ModuleName Section* -> Module {cons("Module")} "imports" ModuleName -> Definition {cons("Imports")}

Language Integration and Separation of Concerns

SDF integrates lexical and contex-free syntax

Page 46: Extension and Evolution

Language Integration and Separation of Concerns

define page topic (topic : Topic) { … navigate(editTopic(topic)){…} …}define page editTopic(topic : Topic) { … }

define page topic (topic : Topic) { … navigate(editTopic(topic)){…} …}define page editTopic(topic : Topic) { … }

extend entity Topic { acl -> ACL }

extend entity Topic { acl -> ACL }

predicate mayViewWeb(w : Web) { ((w.acl.view.length = 0) || memberOf(w.acl.view))}predicate mayEditWeb(w : Web) { memberOf(w.acl.edit)}rules page topic(topic : Topic) { mayViewTopic(topic)}rules page editTopic(topic : Topic) { mayEditTopic(topic)}

predicate mayViewWeb(w : Web) { ((w.acl.view.length = 0) || memberOf(w.acl.view))}predicate mayEditWeb(w : Web) { memberOf(w.acl.edit)}rules page topic(topic : Topic) { mayViewTopic(topic)}rules page editTopic(topic : Topic) { mayEditTopic(topic)}

data model

userinterface

access control

WebDSL provides separate languages for different concerns. Language integration enables verified cross-language references.

Page 47: Extension and Evolution

Embedded Domain-Specific Languages

GPLprogram

GPLprogram

compilecompile 'machine'code

'machine'code

assimilateassimilateDSLprog

MetaBorg (OOPSLA'04)DSLs for abstraction over libraries/frameworks

fine-grained interaction with 'host' codelanguage conglomerates mix DSL and GPL code

Page 48: Extension and Evolution

Swing Userinterface Languageimport javax.swing.*;import java.awt.*; public class Test3 { public static void main(String[] ps) { JFrame frame = frame { title = "Welcome!" content = panel of border layout { center = label { text = "Hello World" } south = panel of grid layout { row = { button { text = "cancel" } button { text = "ok"} } } } }; frame.pack(); frame.setVisible(true); }}

Page 49: Extension and Evolution

DSL with embedded GPL Code

compilecompile 'machine'code

'machine'code

assimilateassimilate

provide GPL expressivity/coverage to complement DSL

Page 50: Extension and Evolution

DSL with embedded GPL Code

vexp : dexp { $$.hi = $$.lo = $1; } | '(' dexp ',' dexp ')' { $$.lo = $2; $$.hi = $4; if( $$.lo > $$.hi ){ printf( "interval out of order\n" ); YYERROR; } } | dexp '*' vexp { $$ = vmul($1, $1, $3); } | vexp '/' vexp { if(dcheck($3)) YYERROR; $$ = vdiv($1.lo, $1.hi, $3); }

Source: http://dinosaur.compilertools.net/yacc/index.html

Page 51: Extension and Evolution

Mixing DSLs: HQL in WebDSL

function sortedBlogEntries(b : Blog) : List<BlogEntry> { var entries : List<BlogEntry> := select distinct e from BlogEntry as e, Blog as b where (b = ~b) and (e member of b._entries) order by e._created descending; return entries;}

Page 52: Extension and Evolution

Evolution

Page 53: Extension and Evolution

evolution scenarios

DSLprogram(model)

DSLprogram(model)

DSLprog

Page 54: Extension and Evolution

regular evolution

DSLprogram(model)

DSLprogram(model)

DSLprog

DSLprogram(model)

DSLprogram(model)

DSLprogmodifymodify

regular evolution: adapt software to new requirementsimplementation simply regenerated after modification of models

Page 55: Extension and Evolution

language evolution

DSLprogram(model)

DSLprogram(model)

DSLprog

evolveevolve

language (syntax and/or transformations) evolve

Page 56: Extension and Evolution

model migration

DSLprogram(model)

DSLprogram(model)

DSLprog

DSLprogram(model)

DSLprogram(model)

DSLprog

evolveevolve

migratemigrate

language evolution requires migration of models

Page 57: Extension and Evolution

platform evolution

DSLprogram(model)

DSLprogram(model)

DSLprog

DSLprogram(model)

DSLprogram(model)

DSLprog

evolveevolve

changes in the platform requires evolution of transformations

evolveevolve

Page 58: Extension and Evolution

model extraction

DSLprogram(model)

DSLprogram(model)

DSLprog

DSLprogram(model)

DSLprogram(model)

DSLprog abstractabstract

derive DSL programs from (legacy) GPL programs

Page 59: Extension and Evolution

abstraction evolution

DSLprogram(model)

DSLprogram(model)

DSLprog

develop higher-level abstractions

DSLprogram(model)

DSLprogram(model)

DSLprog

abst

ract

Page 60: Extension and Evolution

Coupled Evolution

Datamodel

Datamodel

DataModel'

DataModel'

Data Data'Data'migratemigrateDataData

evolveevolve

Page 61: Extension and Evolution

Schedule

● Lab: implement your DSL

● Design 1: demonstrations Thursday and Friday

● Cases: grades coming up

● Lecture 13: Betsy Pepels from CapGemini

● Lecture 14: Johan den Haan & Michel Westrate from Mendix


Recommended