3

I am trying to extract some facts about type declarations from Java M3 models. From a set of M3 files, I tried to use a comprehension, such as

> [type(m) | m <- models];

Though I got: Undeclared variable: types

Then I just tried to obtain facts from methods, using:

> [methods(m) | m <- models];

As the documentation explain. Nevertheless, I got something like:

|std:///lang/java/m3/Core.rsc|(8877,1,<186,52>,<186,53>): NoSuchAnnotation("declarations")

So, what is the correct approach to navigate on a set o M3 models? How can I get information about the classes and interfaces of a M3 model?

I have built the M3 files using the function createM3FromProjectJars.

1 Answers1

3

Good question; documentation about this as of yet scarce. The best by-example code is here: http://tutor.rascal-mpl.org/Recipes/Recipes.html#/Recipes/Metrics/MeasuringJava/MeasuringJava.html

The source code of the M3 model can explain a lot here:

E.g. the latter contains these definitions:

anno rel[loc from, loc to] M3@extends;            // classes extending classes and interfaces extending interfaces
anno rel[loc from, loc to] M3@implements;         // classes implementing interfaces
anno rel[loc from, loc to] M3@methodInvocation;   // methods calling each other (including constructors)
anno rel[loc from, loc to] M3@fieldAccess;        // code using data (like fields)
anno rel[loc from, loc to] M3@typeDependency;     // using a type literal in some code (types of variables, annotations)
anno rel[loc from, loc to] M3@methodOverrides;    // which method override which other methods
anno rel[loc declaration, loc annotation] M3@annotations;

and the former contains these:

anno rel[loc name, loc src]        M3@declarations;            // maps declarations to where they are declared. contains any kind of data or type or code declaration (classes, fields, methods, variables, etc. etc.)
anno rel[loc name, TypeSymbol typ] M3@types;                   // assigns types to declared source code artifacts
anno rel[loc src, loc name]        M3@uses;                    // maps source locations of usages to the respective declarations
anno rel[loc from, loc to]         M3@containment;             // what is logically contained in what else (not necessarily physically, but usually also)
anno list[Message]                 M3@messages;                // error messages and warnings produced while constructing a single m3 model
anno rel[str simpleName, loc qualifiedName]  M3@names;         // convenience mapping from logical names to end-user readable (GUI) names, and vice versa
anno rel[loc definition, loc comments]       M3@documentation; // comments and javadoc attached to declared things
anno rel[loc definition, Modifier modifier] M3@modifiers;     // modifiers associated with declared things

These definitions exactly document the model for Java M3 together. I don't know how much of this information is present if you generate the M3 model from a jar file directly. From an Eclipse source project, all of these tables are filled.

To implement your query you can:

  • [ m@types | m <- models] ; generates a list[rel[loc name, TypeSymbol typ]]
  • { *m@types | m <- models} ; a rel[loc name, TypeSymbol typ] union of all types tables in all models
  • { t | m <- models, t <- m@types} ; different definition of the previous
Jurgen Vinju
  • 6,393
  • 1
  • 15
  • 26
  • I tried the above options but got NoSuchAnnotation("types"), Perhaps I forgot to import something. In order to test, I imported: import lang::java::m3::Core; import lang::java::jdt::m3::Core;import lang::java::jdt::m3::AST; Is there anything else? Another possibility is that createM3FromProjectJars does not load all M3 information. – Rodrigo Bonifacio Nov 30 '16 at 01:08
  • 1
    The exception is about the absence of the annotation on the value indeed. So the jar extractor does not produce this one yet. In the Node library is a function top get all annotations as a map to see what you do have. – Jurgen Vinju Nov 30 '16 at 07:45
  • Thanks. One more question, printing the contents of a M3, I see things like: <|java+class:///br/unb/cic/Rascal/Main|,|project://JavaSamples/src/br/unb/cic/Rascal/Main.java|(552,675,<30,0>,<64,1>)>. I am wondering whether it is possible to visit the class names using the designator java+class. Is it possible? – Rodrigo Bonifacio Nov 30 '16 at 11:02
  • Depends on what you mean by "visit". You can read the a class using `readFile` on a location, also schemes like `java+class`. You can also visit a Java AST and find `@decl` annotations on names entities (a product of name resolution). The `M3@containment` relation helps to find where things are hierarchically as well. The `IO::resolveLocation` can also turn logical names into physical locations for you. PS: this all only works if `registerProject` has been called to update the internal name server and this happens automatically in `createM3FromEclipseProject` but otherwise you do it yourself. – Jurgen Vinju Nov 30 '16 at 19:41