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.
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:
https://github.com/usethesource/rascal/blob/master/src/org/rascalmpl/library/analysis/m3/Core.rsc
https://github.com/usethesource/rascal/blob/master/src/org/rascalmpl/library/lang/java/m3/Core.rsc
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
Related
I tried format document but that just prettifies the code, is there a tool to reorder the appearance of the namespaces, classes, their properties in a file ( lexicographical or otherwise ) so that two autogenerated files can be textually compared to each other?
Human generated files don't have more than a class in a file, or they are hierarchical when there are many classes in the same file, so no need to resort the order of classes and their properties, but is there a tool to reformat and order a file by Class names, fields, properties, Method names and signatures?
The original problem is with updating WCF service, moves classes all over the Reference.cs file.
Edit :
To reproduce just update a WCF service and watch the Reference.cs file being completely juxtaposed, classes move up and down in the file. Trying to have a large autogenerated C# file sorted in unique way to enable textual comparison while the structure remains isomorphic to the original code.
Edit 2: Concrete example code
Suppose file is as below (psudo code)
Namespace S2
{
Class C2
Method M2
Property P2
Constructor CTOR2
Field F2
Method M1
Property P1
Field F1
Constructor CTOR1
}
Namespace S1
{
Class C1
Method M2
Property P2
Constructor CTOR2
Field F2
Method M1
Property P1
Field F1
Constructor CTOR1
}
then after sorted formatting it would be
Namespace S1
{
Class C1
Constructor CTOR1
Constructor CTOR2
Field F1
Field F2
Property P1
Property P2
Method M1
Method M2
}
Namespace S2
{
Class C2
Constructor CTOR1
Constructor CTOR2
Field F1
Field F2
Property P1
Property P2
Method M1
Method M2
}
Note : it doesnt matter what the order of properties, methods, fields are apearing, as long as after the sort they always apear in the same order.
is there a tool to reorder the appearance of the namespaces, classes,
their properties in a file ( lexicographical or otherwise ) so that
two autogenerated files can be textually compared to each other?
After spending a long time serching it, I found these:
1) Resharper extension and its Greenkeeper has stated this.
2) CodeMaid extension
But l am not sure whether these extensions meet all your requirements and if that still is not what you're looking for, I'm afraid what you want is not supported so far.
I recommend you could post a feature request in our User Voice forum(DC)----suggest a feature to share your idea.
Besides, you could share the link in this thread and anyone who is interested in this including us will vote it to get the attention of Microsoft as soon as possible.
Hope it could help you.
I am trying to serialize a data structure, that involves a couple of discriminated unions and records. At some moment, to improve performance (its a scientific computing project), I tried to change some of the types participating in the structure to be .NET structs. However, in one particular case that broke my checkpoints, that are based on BinaryFormatter.
After adding [<Struct>] to one of my records, they started failing serialization roundtrip with the following message on deserialize: Field in TypedReferences cannot be static or init only.
Since, I was only able to find a suggestion to add [<CLIMutable>] to that record, so that its fields are no longer readonly. However, unexpectedly, that did not help.
I managed to narrow the example down to this:
module BinSerializer =
type Node = Leaf | Node of Node * Node
[<Struct>]
[<CLIMutable>]
type Struct = { Term: byte; Node: Node }
type Uni = A | B | S of Struct
open System.IO
open System.Runtime.Serialization.Formatters.Binary
let fail() =
let formatter = BinaryFormatter()
use stream = new MemoryStream()
formatter.Serialize(stream, S({ Term = 0uy; Node = Leaf }))
stream.Flush()
stream.Position <- 0L
formatter.Deserialize(stream) |> ignore
BinSerializer.fail()
Removing [<Struct>] lets the call succeed. Removing Node field from Struct too.
F# 4.1 targeting .NET 4.7.1 + FSharp.Core 4.4.3
I was curious to know if one could define a data type that we know, should be a tuple, but whose length (or number of elements is indeterminable) currently. The application is as follows:
//I want to declare a data type, one of whose argument is a tuple,
public data MyType=fromListCartesianProduct(tuple<?> product)
//Later I want to instantiate a MyType data by using taking List-CartesianProduct
//instantiate some MyType data
foreach(aTuple in [1,2,3]*["a","b"])
someArr[i]=fromListCartesianProduct(aTuple)
The salient observation is that the number of elements in aTuple is indeterminable while declaring "MyType". Can I still declare such a type in a rascal script?
As an alternate, I would declare MyType as:
public data MyType=fromListCartesianProduct(list[] product)
and convert each tuple from taking the cartesian product into a list before constructing the specific instances. For reasons of clarity and others, I would like to define MyType as I previously did.
In principe the answer is no. Tuples have fixed length and we do not (yet) have row polymorphism.
Having said that, data constructors do support different kinds of polymorphism which might help:
row polymorphism using keyword parameters, you can always add more keyword parameters to a data-type, as in
data MyType = myCons(int j = 0); // initial decl
data MyType(int k = 1); // extension with another field
overloading, you can always add more constructors with more parameters
data MyType = f(int i); // initial declaration
data MyType = f(int i, int j); // overloaded declaration with more fields
You might use the make function from Type to dynamically construct such constructors based on argument lists. At the risk of run-time type exceptions of course.
Another way of dealing with data of unpredictable type is to go up one level in the type hierarchy (let it be value), and later pattern match your way out again:
list[value] myListRelationOfUnknownType = ...;
for (<int i, int j> <- myListRelationOfUnknownType)
println("printing only pairs of ints: <i> - <j>");
for (<int i, int j, int k> <- myListRelationOfUnknownType)
println("printing only the triples of ints: <i> - <j> - <k>");
That's a statically more safe way.
I am trying to understand the following code, particularly StringConstant:
type StringConstant = StringConstant of string * string
[<EntryPoint>]
let main argv =
let x = StringConstant("little", "shack")
printfn "%A" x
0 // return an integer exit code
(By way of context, StringConstant is used in the FParsec tutorial, but this example does not use FParsec.)
What I would like to know is:
what exactly is the type statement doing?
once I instantiate x, how would I access the individual "parts"
("little" or "house")
As others already noted, technically, StringConstant is a discriminated union with just a single case and you can extract the value using pattern matching.
When talking about domain modelling in F#, I like to use another useful analogy. Often, you can start just by saying that some data type is a tuple:
type Person = string * int
This is really easy way to represent data, but the problem is that when you write "Tomas", 42, the compiler does not know that you mean Person, but instead understands it as string * int tuple. One-case discriminated unions are a really nice way to name your tuple:
type Person = Person of string * int
It might be a bit confusing that this is using the name Person twice - first as a type name and second as a name of the case. This has no special meaning - it simply means that the type will have the same name as the case.
Now you can write Person("Tomas", 42) to create a value and it will have a type Person. You can decompose it using match or let, but you can also easily write functions that take Person. For example, to return name, you can write:
let getName (Person(name, _)) =
name
I think single-case discriminated unions are often used mainly because they are really easy to define and really easy to work with. However, I would not use them in code that is exposed as a public API because they are a bit unusual and may be confusing.
PS: Also note that you need to use parentheses when extracting the values:
// Correct. Defines symbols 'name' and 'age'
let (Person(name, age)) = tomas
// Incorrect! Defines a function `Person` that takes a tuple
// (and hides the `Person` case of the discriminated union)
let Person(name, age) = tomas
StringConstant is a discriminated union type, with just a single case (also named StringConstant). You extract the parts via pattern matching, using match/function or even just let, since there is just a single case:
let (StringConstant(firstPart, secondPart)) = x
type StringConstant = StringConstant of string * string
results in a discriminated union with one type.
type StringConstant = | StringConstant of string * string if you execute it in F# interactive.
You can see the msdn documentation on that here.
You can get the value out like this:
let printValue opt =
match opt with
| StringConstant( x, y) -> printfn "%A%A" x y
The other guys already mentioned how you extract the data from a discriminated union, but to elaborate a little more on Discriminated unions one could say that they are sorta like enums on steroids. They are implemented behind the scenes as a type hierarchy where the type is the base class and the cases are subclases of that baseclass with whatever parameter they might have as readonly public variables.
In Scala a similar data-structure is called case classes which might help you convince yourself of this implementationmethod.
One nice property of discriminated unions are that they are self-referenceable and therefor are perfect for defining recursive structures like a tree. Below is a definition of a Hoffman coding tree in just three lines of code. Doing that in C# would probably take somewhere between 5 and 10 times as many lines of code.
type CodeTree =
| Branch of CodeTree * CodeTree * list<char> * int
| Leaf of char * int
For information about Discriminated Unions see the msdn documentation
For an example of using Discriminated Unions as a tree-structure see this gist which is an implementation of a huffman decoder in roughly 60 lines of F#)
F# has feature called "Type extension" that gives a developer ability to extend existing types.
There is two types of extensions: intrinsic extension and optional extension. First one is similar to partial types in C# and second one is something similar to method extension (but more powerful).
To use intrinsic extension we should put two declarations into the same file. In this case compiler will merge two definitions into one final type (i.e. this is two "parts" of one type).
The issue is that those two types has different access rules for different members and values:
// SampleType.fs
// "Main" declaration
type SampleType(a: int) =
let f1 = 42
let func() = 42
[<DefaultValue>]
val mutable f2: int
member private x.f3 = 42
static member private f4 = 42
member private this.someMethod() =
// "Main" declaration has access to all values (a, f1 and func())
// as well as to all members (f2, f3, f4)
printf "a: %d, f1: %d, f2: %d, f3: %d, f4: %d, func(): %d"
a f1 this.f2 this.f3 SampleType.f4 (func())
// "Partial" declaration
type SampleType with
member private this.anotherMethod() =
// But "partial" declaration has no access to values (a, f1 and func())
// and following two lines won't compile
//printf "a: %d" a
//printf "f1: %d" f1
//printf "func(): %d" (func())
// But has access to private members (f2, f3 and f4)
printf "f2: %d, f3: %d, f4: %d"
this.f2 this.f3 SampleType.f4
I read F# specification but didn't find any ideas why F# compiler differentiate between value and member declarations.
In 8.6.1.3 section of F# spec said that "The functions and values defined by instance definitions are lexically scoped (and thus implicitly private) to the object being defined.". Partial declaration has all access to all private members (static and instance). My guess is that by "lexical scope" specification authors specifically mean only "main" declaration but this behavior seems weird to me.
The question is: is this behavior intentional and what rationale behind it?
This is a great question! As you pointed out, the specification says that "local values are lexically scoped to the object being defined", but looking at the F# specification, it does not actually define what lexical scoping means in this case.
As your sample shows, the current behavior is that the lexical scope of object definition is just the primary type definition (excluding intrinsic extensions). I'm not too surprised by that, but I see that the other interpretation would make sense too...
I think a good reason for this is that the two kinds of extensions should behave the same (as much as possible) and you should be able to refactor your code from using one to using the other as you need. The two kinds only differ in how they are compiled under the cover. This property would be broken if one kind allowed access to lexical scope while the other did not (because, extension members technically cannot do that).
That said, I think this could be (at least) clarified in the specification. The best way to report this is to send email to fsbugs at microsoft dot com.
I sent this question to fsbugs at microsoft dot com and got following answer from Don Syme:
Hi Sergey,
Yes, the behaviour is intentional. When you use “let” in the class scope the identifier has lexical scope over the type definition. The value may not even be placed in a field – for example if a value is not captured by any methods then it becomes local to the constructor. This analysis is done locally to the class.
I understand that you expect the feature to work like partial classes in C#. However it just doesn’t work that way.
I think term "lexical scope" should be define more clearly in the spec, because otherwise current behavior would be surprising for other developers as well.
Many thanks to Don for his response!