m3 for moose

20
Oscar Nierstrasz Software Composition Group scg.unibe.ch SC Seminar 2014-04-07 M3 for Moose

Upload: oscar-nierstrasz

Post on 12-Jul-2015

331 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: M3 for Moose

Oscar Nierstrasz

Software Composition Group

scg.unibe.ch

SC Seminar 2014-04-07

M3 for Moose

Page 2: M3 for Moose

Roadmap

Page 3: M3 for Moose

The agile modeling problem

Page 4: M3 for Moose

4

Smalltalk

Navigation

Metrics

Querying

Grouping

Smalltalk

Java

C++

Python

Extensible meta model

Model repository

Moose is a powerful tool

once we have a model …

Roassal

Orion DSM ...BugMap

Page 5: M3 for Moose

5

Grammar stealing

Recycling trees

Parsing by example

Evolutionary Grammar

Generation

Incrementally refine

island grammars

Automatic structure

recognition

Page 6: M3 for Moose

6

(

(FAMIX.Namespace (id: 182)

(name 'snakes'))

(FAMIX.Class (id: 8)

(name 'DieTest')

...

m3(|project://...|)[

@fieldAccess={

...

},

...

Idea: steal models from Rascal

Especially

interesting for

languages other

than Java!

Page 7: M3 for Moose

7

Works, but is very painful

Errors in generated

MSE are hard to

debug

Page 8: M3 for Moose

M3 for Moose

Page 9: M3 for Moose

9

Idea: directly parse and transform

M3 models from Pharo

m3(|project://...|)[

@fieldAccess={

...

},

...

Page 10: M3 for Moose

10

m3(|project://p2-SnakesAndLadders|)[

@fieldAccess={

<|java+method://p2-SnakesAndLadders/snakes/Game/toString()|,|java+field://p2-SnakesAndLadders/snakes/Game/squares|>,

<|java+method://p2-SnakesAndLadders/snakes/Game/addSquares(int)|,|java+field://p2-SnakesAndLadders/snakes/Game/squares|>,

...

},

@extends={

<|java+class://p2-SnakesAndLadders/snakes/Snake|,|java+class://p2-SnakesAndLadders/snakes/Ladder|>,

<|java+class://p2-SnakesAndLadders/snakes/Ladder|,|java+class://p2-SnakesAndLadders/snakes/Square|>,

...

},

@methodInvocation={

<|java+method://p2-SnakesAndLadders/snakes/SimpleGameTest/move8jillWins(snakes.Game)|,|java+method://p2

<|java+variable://p2-SnakesAndLadders/snakes/Game/toString()/buffer|,|java+constructor://p2

...

},

@typeDependency={

<|java+method://p2-SnakesAndLadders/snakes/Square/nextSquare()|,|java+primitiveType://p2-SnakesAndLadders/int|>,

module m3::m3util

import lang::java::jdt::m3::Core;

import lang::java::m3::TypeHierarchy;

import IO;

import List;

/* dumpM3(|project://p2-SnakesAndLadders|); */

@doc { Write the M3 model for an Eclipse Java project to its source directory. }

public void dumpM3(loc project) {

M3 m = createM3FromEclipseProject(project);

loc file = m.id + "<m.id.authority>.m3.txt";

iprintToFile(file, m);

}

URIs (“locations”)

Step 1: dump M3 from Rascal and Eclipse

Page 11: M3 for Moose

11

Step 2: parse M3

Page 12: M3 for Moose

12

URIs are parsed separately

Page 13: M3 for Moose

13

Step 3: build POSOs (Plain Old Smalltalk Objects)

PPM3ModelParser>>start

^ super start

==> [ :nodes |

M3Model new

project: nodes second;

annotations: nodes fourth;

uriCache: uriCache ]

Page 14: M3 for Moose

14

Step 4: transform URIs to FAMIX entities

M3Model>>buildURIs

uriCache values do:

[ : each | |entity|

entity := each buildFAMIXEntity.

entity ifNotNil: [ mooseModel silentlyAdd: entity ] ]

M3URI>>famixClass

^ FAMIXClass new

name: self name;

yourself

M3URI>>famixInterface

^ self famixClass

isInterface: true;

yourself

M3URI>>famixMethod

^ FAMIXMethod new

name: self path;

yourself

M3URI>>famixConstructor

^ self famixMethod

isConstructor: true;

yourself

M3URI>>famixField

^ FAMIXAttribute new

name: self name;

yourself Etc. etc.

M3URI>>buildFAMIXEntity

famixEntity := self perform: (self class famixMethodFor: self scheme).

^ famixEntity

Page 15: M3 for Moose

15

M3Model>>buildExtends

| extends |

extends := self at: 'extends'.

extends ifNotNil:

[extends do:

[ : inheritance || aSubclass aSuperclass |

aSubclass := inheritance first famixEntity.

aSuperclass := inheritance second famixEntity.

mooseModel silentlyAdd:

(FAMIXInheritance new

subclass: aSubclass;

superclass: aSuperclass) ] ]

Etc. etc.

Step 5: interpret annotations for FAMIX entities

Page 16: M3 for Moose

16

M3Model>>buildContainment

...

(self at: 'containment') do:

[ : each | | whole part |

whole := each first famixEntity.

part := each second famixEntity.

part setContainer: whole.

...

]

... FAMIXAttribute>>setContainer: aFamixEntity

self assert: [ aFamixEntity isClass ].

aFamixEntity addAttribute: self

FAMIXLocalVariable>>setContainer: aFamixEntity

self assert: [ aFamixEntity isMethod ].

self parentBehaviouralEntity: aFamixEntity

FAMIXMethod>>setContainer: aFamixEntity

self assert: [ aFamixEntity isClass ].

aFamixEntity addMethod: self

Caveat! mappings from M3 to FAMIX can be tricky

Page 17: M3 for Moose

17

Step 6: load into Moose!

M3Model import transformToMoose; install.

MoosePanel open.

Page 18: M3 for Moose

Lessons Learned

Page 19: M3 for Moose

19

It is easy to get lost when

your parser backtracks

Domain-specific browsers and debuggers are cool!

Two-level parsers

simplify development

and debugging

Model transformation

is not straightforward

m3(|project://...|)[

@fieldAccess={

...

},

...

?!

Page 20: M3 for Moose

20

Links

http://smalltalkhub.com/#!/~onierstrasz/M3ForMoose

https://github.com/onierstrasz/M3ForMooseTestCase

https://github.com/onierstrasz/rascal-m3-to-mse