Moose Famix

Moose

Famix

General purpose meta-models building framework

Introduction

Moose

Moose is a powerful open source platform for software and data analysis. It offers multiple services ranging from importing and parsing data, modeling, measuring, querying and mining of information. It has great support for the creation of interactive and visual analysis tools.

For more information about Moose see http://www.moosetechnology.org.

Famix

Famix is a basic meta-modeling framework for Moose. It provides building blocks from which you can build own custom meta-model that fits your particular needs while you still can benefit from the advantages that Moose offers.

Historical perspective

In Moose preceding the versions 7, the FAMIX was a single meta-model that tried to cover the most common properties of all standard languages. This approach has several obvious advantages. With a single meta-model for all languages, you can easily do a software analysis on projects written in them and easily cover very common cases when you have a single project that uses multiple languages at once. The meta-model that provides descriptions of language elements like functions, classes or variables simply uniforms everything into a single frame.

This approach where only one meta-model is used has the single but very important disadvantage: it does not work generally. The FAMIX meta-model described well languages like Java, C#, C, C++ and Smalltalk. However, even in the case of these languages, the description was rough and haven't covered all details it could. For example, in the case of Smalltalk, the FAMIX was not describing entities like slots, traits, shared pools and so on. When you analyzed a model in this language, such details were hidden and slots had to be described only with the concept of instance variables. It was possible to investigate the name of slots, browser their users or computer metrics related to them but by default, FAMIX had no default way of modeling other slot properties like their definition.

The Pharo as one particular Smalltalk implementation slightly changed the language metamodel in version 7 by an introduction of stateful traits. It was not possible to cover it with the FAMIX meta-model. It was impossible to describe languages like SQL, various types of domain specific languages nor data without significant ad-hoc extensions to the FAMIX meta-model.

The need for meta-model unification lead sometimes to bizarre design decisions that had no sense in particular languages. For example, the methods were owned by general type, not by classes that are only a kind of types. The inheritance was described on the level of types too so then it was possible to theoretically have a Java model that has a primitive type int with several methods and inherits from float. For FAMIX it was still a valid model.

The basic meta-model for Moose prior versions 7 was named FAMIX (all characters were uppercase). The name for the new generation of the meta-model based on groups of traits is named simply Famix.

While FAMIX tried to unify the meta-models for various languages, it had to unite the most common concepts. Let's take a look at a simplified fragment of Java meta-model (figure ).

Java and C meta-model fragments
Java and C meta-model fragments

Java meta-model needs to describe methods and classes. Both of the meta-model elements share some behavior (e.g. they can have a link to source) so they inherit from common superclass JavaEntity. The C language does not have classes or methods. On the other hand, it needs to describe the concept of functions that is not used in Java.

The C++ has classes and it the programs can use methods and functions together. Functions and methods are to some extent similar behavioural entities so it makes sense to introduce a common generalization for them.

C++ meta-model fragment
C++ meta-model fragment

While FAMIX tried to uniform all these languages, its metamodel followed the structure of the C++ metamodel. So when a user analyzed a C program using Moose, the tools provided a lot of data like metrics for classes that had not any sense in the context of the C program.

Standalone meta-models

The Famix in Moose version 7 was significantly changed. Now the Famix is not one unifying meta-model that tries to cover everything, but it is a set of building blocks, small fragments of the meta-models. A user creates own meta-models of these fragments and can easily add custom elements that cannot be described by anything that Famix provides by default. That is especially important for modelling of custom domain-specific languages or structured data.

Now every modeled language has its own standalone meta-model. Particular meta-models do not share entities, so every language has custom classes even for the very general meta-model entities like named entities (was FAMIXNamedEntity). Now we need JavaNamedEntity, CNamedEntity, SmalltalkNamedEntity and so on.

Trait groups

The fundamental component of the Famix is a trait group. A trait group always describes a fragment of meta-model and can consist of one, two or more entities and relations between them.

We can demonstrate it on an example of the access. In some meta-model, we have two kinds of entities: local variables and methods. Methods contain a code that reads some local variables or writes data to them. Let's have a program that contains a method named aMethod with a local variable named foo. It writes data to it and then uses it in a method call.

    public void aMethod() {
        int foo = 5;
        someMethod(foo);
    }

Now we will try to model our little program using the meta-model. We will create an object for the method aMethod, an object that models the variable foo that contains information, wherein the code the instance variable was declared. But one crucial information is missing. We would like where in the code the variable was accessed and what kind of access was that. Was the variable written or read? With such information, we can do a straightforward but useful analysis of the program models and decide, what local variables were not used or just written and never read.

To model the association between the variable and method, we will introduce a new kind of entity in our metamodel: the access. For every access to a local variable, we will create an object that describes is. It will contain information what the accessed local variable was, what method accessed it, wherein the code this concrete access is placed and what kind of access is it (read or write).

The Famix provides a meta-model fragment exactly for this use-case. It contains a trait group named Access that describes three entities: access itself (Access), the element that is being accessed (Accessible, in our case, it is the local variable) and an entity that contains accesses (WithAccesses, in case of our meta-model it is the method).

Access trait group
Access trait group

This trait group describes relations between these three entities. So WithAccesses has accesses, Accessible has incomming accesses, and the Access stores information aoubt its accessor and variable.

The entities that Famix provides are not real meta-model entities. They cannot be instantiated directly. They are provided in form of traits. That means that you need to apply them on your custom meta-model. That's why in following text they will have a prefix T (meaning trait).

The concrete language meta-model will contain three real entities: JavaLocalVariable, JavaMethod and JavaAccess. What we will do is to apply the traits provided by the Famix trait group on them. So JavaAccess will use the trait TAccess, JavaMethod will use the trait TWithAccesses and

Famix traits applied on real meta-model entities
Famix traits applied on real meta-model entities

In reality, the traits names include prefĂ­x FamixT so the real trait names are FamixTAccess, FamixTAccessible and FamixTWithAccesses.

The entities and relations that trait groups describe tend to be as general as possible. We can use it for the description of accesses to other kinds of variables like instance variables or global ones. We can use the same group in the C meta-model for the description of functions to variables.

To use these traits in our meta-model is the only operation we need. When we do that, they automatically extend capabilities of our meta-model so the entities of a model will provide relevant related information in the inspectors and so on.

The particular meta-model entities are not limited on only class group, they can use traits from various Famix trait gropus so you can easily compose a custom meta-model with a non-trivial functionality with minimum of effort.

Remember: Famix trait groups are concept that allows reuseability of meta-model fragments and easy composition of custom meta-models.

Famix meta-model definition

To make the composition of meta-models easier, Moose provides a special builder. The builder uses custom Smalltalk-based domain specific language for meta-models definition so when you create a custom meta-model, you describe it using this DSL and the Smalltalk classes of the meta-model will be automatically generated or updated.

More in the chapter Meta-model Definition