Skip to content
This repository was archived by the owner on Oct 11, 2023. It is now read-only.

Integration with applications outside of MPS

Tamas Szabo edited this page Jan 7, 2019 · 13 revisions

We are actively working on making IncA available outside of MPS, this way making it easy to integrate IncA with other IDEs, as well. Before we provide details about our actual roadmap, let us revisit the main components of an incremental IncA analysis.

  1. Metamodel: The IncA analysis needs to be written against an MPS language. For example, when analyzing source code, the MPS language is the grammar of the code’s language. When analyzing a control flow graph, the metamodel describes the format of the graphs.
  2. Analysis: The analysis needs to be written in the IncA language.
  3. Initial model (or program in other words): The analysis operates on a model, and IncA caches analysis-specific information about the model. The model must adhere to the metamodel from above. When analyzing source code, this model is the source code. When analyzing a control flow graph, it is a description of that graph. IncA provides an interface with which it can be informed about the initial model.
  4. Model changes: The model can change over time and IncA can react to these changes. IncA provides an interface with which it can be informed about changes to the model.
  5. Analysis results:
  • Given the metamodel, the analysis, the initial model, IncA’s run-time system computes the initial analysis result.
  • Given subsequent model changes, IncA’s run-time system computes changes to the initial analysis result. IncA indicates what has changed by notifying user-provided observers.

Ultimately, our end goal is to make it possible to define and use all five of these components without MPS. However, we defined a series of steps to get there, which we describe next. This document will be updated as we make progress in this line of work.

Metamodel

We defined a simple grammar for the definition of metamodels. Using this grammar, you can simply write down your metamodel in a text file, and we can automatically convert the metamodel into an MPS language.

The Xtext-style grammar definition is as follows:

Metamodel: 
	  contents += MetamodelContent*;


MetamodelContent: 
	  StartConstructorDeclaration
	| ConstructorDeclaration
	| SubsortDeclaration;
	
StartConstructorDeclaration: 
	  'start' name=ID;
	  
ConstructorDeclaration:
	  'constructor' name=ID '(' (params += ConstructorParam (',' params += ConstructorParam)*)? ')' ':' sort=SortNamed;
	  
SubsortDeclaration:
	  'subsort' sub=Sort '<:' sup=Sort;
	  
ConstructorParam
	  name=ParameterName ':' sort=Sort;
	  
Sort:
	  integer
	| string
	| boolean
	| SortNamed;
	
SortNamed:
	  name=ID (isList?='*')? (isOptional?='?')?
	
ParameterName:
	  ID
	| '_';

As an example, the WHILE language in this grammar looks like as follows:

start Block

subsort Literal <: Expr                                      

constructor Block(stmts:Stmt*): Block

constructor Declare(var:string): Stmt
constructor Assign(var:string, exp:Expr): Stmt
constructor While(cond:Expr, body:Block): Stmt
constructor If(cond:Expr, then:Block, else:Block?): Stmt
constructor Print(expr:Expr): Stmt

constructor Plus() : BinOp                                   
constructor Minus() : BinOp                                  
constructor Times() : BinOp                                  
constructor DivBy() : BinOp                                  
constructor And() : BinOp                                    
constructor Or() : BinOp                                     
constructor Eq() : BinOp                                     
                                                             
constructor Neg() : UnOp                                     
constructor Not() : UnOp                                     
                                                             
constructor BoolLit(boolean) : Literal                     
constructor NumberLit(_:integer) : Literal                   
                                                             
constructor VarRef(var:string): Expr
constructor BinOpExpr(left:Expr, op:BinOp, right:Expr) : Expr
constructor UnOpExpr(op:UnOp, exp:Expr) : Expr               

Now, you are ready to import the metamodel definition and create MPS concepts representing them. If you do not yet have an MPS language, simply create an empty one. Then, right click on the structure model of your language and select the Import Metamodel Declaration item. Select the text file using the file chooser window. After you click Open, the MPS concepts are automatically created according to your metamodel.

Analysis

For now, the analysis needs to be defined inside MPS. We believe that all the IDE features that we have for the IncA language are actually really useful during the development of the analyses. Beyond the usual code completion, syntax highlighting, outline, we also have various checks helping to avoid common pitfalls, and we do provide a handy debug utility called the IncA Explorer.

Initial model

Given the metamodel definition from before, if you define a model in a text format that adheres to the metamodel, we can automatically import that into an MPS AST. This way you can immediately try out your previously defined analysis on example inputs.

Using the grammar of the WHILE language from before, an example model could look like as follows:

Block([

Declare("x"),
Declare("y"),
Declare("z"),

Assign("x", VarRef("y")),

If(BoolLit(true),
  Block([Assign("z", NumberLit(0))]),
  Block([Assign("z", NumberLit(1))])
),

Print(VarRef("z"))

])

Once you defined the model in a text file, you can import that in MPS with the following steps:

  1. Make sure that the MPS model where you want to import to defines your MPS language containing the metamodel in the Used Languages part of the Model properties. This is mandatory because, otherwise, the importer will not find the concepts representing your metamodel elements.
  2. Right click on the target model and select the Import AST Model item.
  3. Select the text file describing your initial model.

After you click Open, the initial model will be automatically created in the target model.

Model changes

Given a series of textual model definitions, you can replay the series of changes deltas in your MPS model. After you have imported the initial model, you can simply select one of the root nodes in your model, right click on it, and select the Update AST Model item. This will import the selected model definition, compute the delta between the old AST and the new AST, and apply the delta on the old AST. Simply replacing the old AST with the new AST is against efficient icrementalization of IncA program analyses - we want to compute as precise a delta as possible.

Of course, computing the delta efficiently is a hard problem. Our current model differencer serves only testing purposes. For real world scenarios, efficient computation of deltas may require sophisticated diffing algorithms, incremental parsing, or projectional editing (exactly what MPS offers).

Analysis results

The easiest way to try out an IncA analysis is to use the IncA Explorer, which is available from the Tools menu of MPS. You can simply load an IncA analysis and an initial model into the IncA Explorer using the "green play button". Once you have loaded them, you can already start examining the initial analysis result. Updating the model triggers the IncA analysis to update its result, which is automatically reflected in the IncA Explorer's tree viewer.

IncA also comes with a DSL to access the analysis result from MPS code. Technically, this DSL is a Java language extension. You can examine the DSL in action in the AnalysisResultAccess class of the org.inca.data.test.analyses solution.

Clone this wiki locally