I'm trying to get the Declaration of methods using AST, so I can traverse it, looking for certain statements. It worked before, but I can't get it to work anymore, the Declaration I'm getting looks to me like there's some kind of parsing error. I cannot find information on how to fix this:
{<|java+method:///MetricsTest/testMethod()|,compilationUnit([],[],src=|java+method:///MetricsTest/testMethod()|(0,30,<1,0>,<2,2>),decl=|java+compilationUnit:///MetricsTest/testMethod()|,messages=[error("Syntax error on token \"void\", @ expected",|java+method:///MetricsTest/testMethod()|(7,4,<1,0>,<1,0>)),error("Syntax error, insert \"enum Identifier\" to complete EnumHeader",|java+method:///MetricsTest/testMethod()|(23,1,<1,0>,<1,0>))])>}
My (partial) code is as follows:
public rel[loc, loc] getMethods(M3 model) {
return { <x,y> | <x,y> <- model.containment
, x.scheme=="java+class"
, y.scheme=="java+method" || y.scheme=="java+constructor"
};
}
public rel[loc, Declaration] getMethodLocWithDeclaration(M3 model) {
rel[loc, loc] methods = getMethods(model);
rel[loc, Declaration] methodsWithAST = {};
for(<loc c, loc m> <- methods) {
methodsWithAST += <m, createAstFromFile(m, false)>;
}
return methodsWithAST;
}
Does anyone have a clue on how I can fix this?
The createAstFromFile
function will return "half" an AST even if there is a parse error in the input file. So you get an compilationUnit
node, but immediately below it there is an error
node which contains the information about the parse error.
The top compilationUnit
node also seems to have a field messages
which lists all the errors of the current file.
There are two parse errors that the Java compiler found in that particular file:
error("Syntax error on token \"void\", @ expected",|java+method:///MetricsTest/testMethod()|(7,4,<1,0>,<1,0>))
error("Syntax error, insert \"enum Identifier\" to complete EnumHeader",|java+method:///MetricsTest/testMethod()|(23,1,<1,0>,<1,0>))])
To fix this, I'd open the MetricsTest class in Eclipse and use the editor support to fix the file. When the file is fixed and you try the createAstFromFile function again, it should work again.
One way to make sure you know what you are exactly parsing, is to use the readFile
function from the IO library. It could very well be that you are sending only a part of a file to the java parser, and it can only handle full files.
If you'd add this to your for-loop, you could detect if that is the case:
println("Parsing \'<readFile(m)>\'");
It's likely you are passing this: |java+method:///MetricsTest/testMethod()|(23,1,<1,0>,<1,0>))
as the URI to createAstFromFile, and that is only part of the MetricsTest.java
file. I'm guessing this is what goes wrong.
To fix that, you can look up the real source location from the decls
relation in an M3 model, and then use .top
to cover the whole file. An alternative is to construct a java+compilationUnit
URI for the MetricsTest
class and give that to the createAstFromFile
function, or look that one up from the containment
relation.