Analysing Java with VSCode

VSCode is an incredible editor tool. Thanks to its extensions, one can develop using plenty of programming languages. However, what about analyzing one software system using VSCode?

In this blog post, I will present you how to use VSCode with Moose to analyze Java code. As an example, I will reproduce the blog post of Christopher Fuhrman.

Even if we can perform some analysis from VSCode, using the Moose tool natively gives a better user experience. Still, I believe it might interest people using only the VSCode tool.

Install VSCode and the Pharo Language Server extension

Download and install the required tools

To perform the analysis, we will use the insider version of VSCode. Currently, only this version supports the NoteBook feature we will use.

So, as a first step, install the last VSCode insider version.

We will also need a Moose image and a Pharo VM. For this blog post, we will use a Moose 8 image based on Pharo 8.

Do not take the headless version (it has not been tested)

Once you have download VSCode, Moose 8, and the Pharo VM, we will install the extension in VSCode.

Install extension

From now on, you must start VSCode insider with the following parameters (--enable-proposed-api badetitou.pharo-language-server). It allows VSCode to use the Notebook API.

Execute the following command in a terminal:

1code-insiders --enable-proposed-api badetitou.pharo-language-server

Or in Windows:

1code-insiders.cmd --enable-proposed-api badetitou.pharo-language-server

Configure VSCode

We now need to configure the Pharo Language Server extension. To do so:

If you use Windows, you might need to remove all space characters in the path.

Once the configuration is done, you can create a new file named oo-analysis.moosebook. It should open as a VSCode notebook and a Pharo image (you can reduce the Pharo image, but do not close it).

Set up the analysis of a new project

Clone the Java project you want to analyze

First, we are going to download the GitHub project we want to analyze. To do so, create a new code cell in VSCode with the following code:

1javaProjectFileRef := MooseEasyUtility cloneGitHubRepo: ''.

This piece of code will download the project under our Pharo image folder. To execute the cell, press the run arrow next to the cell. In case of success, a little tick appears and the path to the clone project has output of the cell.

Cell executed after clone

Parse the Java code to make FAMIX model

As in the original blog post of Christopher, now we will parse the Java project and create a FAMIX model. To parse the Java project, we use VerveineJ v1.x.x (v1.x.x works with Moose 8, whereas v2.x.x is under modification to work with the future Moose 9).

Contrary to the original blog post, we will download VerveineJ v1.0.2 (and not v1.0.1). It includes nice fixes.

.mse is a file format used by Moosetechnology to represent its model and meta-model. Other formats exist.

Load the model

The last step is to load the model in the Moose image (the one we are controlling using VSCode). In a new cell, execute:

1mseFileRef := 'tmp/HFDP.mse' asFileReference. "Generated by FamixMaker" 2mseStream := mseFileRef readStream. 3mseStream 4 ifNotNil: [ 5 mooseModel := MooseModel importFromMSEStream: mseStream. 6 mooseModel rootFolder: 7 'tmp/MooseEasyRepos/bethrobson__Head-First-Design-Patterns'. 8 mseStream close. ] 9 ifNil: [ self error: 10 'Could not load MSE file into Moose: ' , mseFileRef asString ]. 11mseStream. 12mooseModel install

The output of the cell should be a MooseModel #HFDP(30946).

Congrats! You have set up everything. Now it is time to analyze the project 🚀


Visualize a Java package in PlantUML

To visualize Java packages using PlantUML. We first install the PlantUML connector of Pharo (PlantUMLPharoGizmo).

To do so, simply create a new code cell with the installation script and execute it.

1"Install PlantUMLPharo" 2version := 'master'. 3Metacello new 4 repository: 'github://fuhrmanator/PlantUMLPharoGizmo:' , version, '/src'; 5 baseline: 'PUGizmo'; 6 load.

Then, you can visualize the classes of a package by executing a Pharo Script.

1attribute := true. 2method := false. 3inheritance := true. 4aggregation := true. 5createCheckBox := false. 6 7preference := 'set namespaceSeparator ::' , String cr 8 , 'hide empty members' , String cr , 'scale 1' , String cr 9 , 'left to right direction' , String cr. 10 11items := mooseModel allModelClasses select: [:each | each mooseName beginsWith: 'headfirst::designpatterns::combining::decorator' ]. 12 13 14pUMLSource := PUGizmo 15 plantUMLSourceForMooseJavaClasses: items 16 withPreference: preference 17 withRelationships: 18 {attribute. 19 method. 20 inheritance. 21 aggregation. 22 createCheckBox}. 23 24plantKey := pUMLSource asPlantUMLKey. 25serverUrl := '', plantKey. 26imageMorph := (ZnEasy getPng: serverUrl asUrl).

In the above example, as in the original blog post, we focus on the package: headfirst::designpatterns::combining::decorator and we show the classes attributes, inheritances, and aggregation. Executing the code gives the following image as the output of the VSCode cell.

Output after cell execution

Perform a Moose analysis using Pharo

It is also possible to execute some classic Pharo code. We can request the list of classes that implement more than one interface.

1"Query all classes that have more than two direct FAMIX superclasses" 2classesImplementingMoreThanOneInterface := mooseModel allModelClasses 3 select: [ :each | 4 each directSuperclasses size > 2 ]. 5String streamContents: [ :stream | classesImplementingMoreThanOneInterface do: [:class | stream << class name ] separatedBy: [stream << ', ' ] ]

Output after cell execution

Visualisation with Roassal

Finally, one can use Roassal2 (or Roassal3 in Pharo 9) to create custom visualization.

It is possible to use pre-built visualization coming from Moose, such as the System Nesting map:

1view := RTView new. 2FAMIXSystemNestingMap new 3 viewNamespaces: (mooseModel allNamespaces select: [ :each | each allClasses anySatisfy: [ :c | c isStub not ] ]) 4 highlighting: {} 5 onRaw: view. 6view

Output after cell execution nexting map

Or every other Roassal visualization!