In ClaiR it is not (yet) possible to write changes made in the AST back to file.
For this reason, I create a list lrel[int, int, str] changes = [];
with startposition and endposition of the substring to remove, and a string with which it needs to be replaced.
When I have a full list of changes I want to make to a source file, I sort the changes and open the file with fb = chars(readFile(f));
make the changes
public list[int] changeCharList(list[int] charList, lrel[int, int, str] changesList) {
int offset = 0;
for (t <- [0 .. size(changesList)]) {
tuple[int startIndex, int endIndex, str changeWithString] change = changesList[t];
int startIndexWithOffset = change.startIndex + offset;
int endIndexWithOffset = change.endIndex + offset;
list[int] changeWithChars = chars(change.changeWithString);
for (i <- [startIndexWithOffset .. endIndexWithOffset]) {
charList = delete(charList, startIndexWithOffset);
}
for (i <- [0 .. size(changeWithChars)]) {
charList = insertAt(charList, startIndexWithOffset + i, changeWithChars[i]);
}
offset += size(changeWithChars) - (change.endIndex - change.startIndex);
}
return charList;
}
and write to file writeFileBytes(f, fb);
This approach works for source files without expanded macros, but it does not work for sources files with expanded macros. In the later case the offsets used in the AST do not map the offsets with the file opened using readFile
.
As a workaround I can comment macros before running Rascal and uncomment them after running Rascal. I do not like this.
Is there a way to recalculate the offsets in such a way that the AST offsets map the file read offsets?