I'm trying to create a method that recursively looks for a For-loop. I need to initialize the return value first (a tuple) but how do I do this exactly? I've tried: tuple[list[Expression],Statement] = [];
Also, if I would bind a complete statement, like;
case s:\for(_,_,_,_):
would this be the correct type: tuple[list[Expression],Statement]?
public tuple[list[Expression],Statement] showForLoops(loc project) {
set[loc] files = javaFiles(project);
set[Declaration] decls = createAstsFromFiles(files, false);
tuple[list[Expression],Statement] result = [];
visit (decls) {
case \for(initializers,_,_,body): result += < initializers, body>;
}
return(result);
}
The plain answer is that you have to choose a Statement
type like this:
result = <[], empty()>; // using the empty statement as a default
Note how I did not use a type (it can be inferred)
You could also write it with a type:
tuple[list[Expression],Statement] result = <[], empty()>;
There are other ways though to write this code, which you might find interesting.
The \for
constructor itself, can replace the concept of the tuple you required. You can later project out its fields using myForLoop.initializers
(for example):
Statement findFirstForStatement(loc project) {
decls = createAstsFromFiles(files, false);
visit(decls) {
case f:\for(_,_,_,_): return f;
}
return empty();
}
rascal>ff = findFirstForStatement(pr);
Statement: for(....)
rascal>ff.initializers
list[Expression]: [...]
Or you can use a Maybe:
import util::Maybe;
Maybe[tuple[list[Expression], Statement]] findFirstForLoop(loc project) {
decls = createAstsFromFiles(files, false);
visit(decls) {
case f:\for(_,_,_,_) : return just(f);
}
return nothing();
}
Or, finally, you might throw an exception if you can't find anything:
Statement findFirstForLoop(loc project) {
decls = createAstsFromFiles(files, false);
visit(decls) {
case f:\for(_,_,_,_) : return f;
}
throw "couldn't find a for loop";
}
And a Bonus example collects all the for loops instead of finding the first:
list[Statement] getAllForLoops(loc project) {
decls = createAstsFromFiles(files, false);
result = [];
visit(decls) {
case f:\for(_,_,_,_) : result += [f];
}
return result;
}
Could also be written as a comprehension:
list[Statement] getAllForLoops(loc project) {
decls = createAstsFromFiles(files, false);
return [ f | /f:\for(_,_,_,_) := decls];
}