Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/org/rascalmpl/library/IO.rsc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ The following input/output functions are defined:
module IO

import Exception;

extend analysis::diff::edits::FileSystemChanges;

@synopsis{All functions in this module that have a charset parameter use this as default.}
Expand Down Expand Up @@ -209,7 +210,6 @@ exists(|std:///IO.rsc|);
@javaClass{org.rascalmpl.library.Prelude}
public java bool exists(loc file);


@synopsis{Find a named file in a list of locations.}
@examples{
```rascal-shell
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import Set;
import IO;
import util::Monitor;

private loc here = |std:///lang/rascal/syntax/grammar/definition/Modules|;

@memo
@synopsis{Converts internal module representation of Rascal interpreter to single grammar definition}
public Grammar modules2grammar(str main, map[str name, tuple[set[str] imports, set[str] extends, set[SyntaxDefinition] defs] \mod] mods) {
Expand Down Expand Up @@ -51,24 +53,30 @@ public Grammar fuse(GrammarDefinition def) {
done = {};
deps = dependencies(def);

if (!def.modules[def.main]?) {
jobWarning("the main module is unavailable <def.main> (ignored)", here);
}

while (todo != {}) {
<nm,todo> = takeOneFrom(todo);
done += nm;
if(def.modules[nm]?){
\mod = def.modules[nm];
result = (compose(result, \mod.grammar) | compose(it, def.modules[i].grammar) | i <- deps[nm], def.modules[i]?);
todo += (\mod.extends - done);
}
else {
warning("Fuse algorithm misses module definition for dependency <nm>", |unknown:///|);

\mod = def.modules[nm];

for (str i <- deps[nm], !def.modules[i]?) {
jobWarning("<nm> imports or extends the unavailable module <i> (ignored)", here);
}

result = (compose(result, \mod.grammar) | compose(it, def.modules[i].grammar) | i <- deps[nm], def.modules[i]?);
todo += (\mod.extends - done);
}

return result;
}




public GrammarModule module2grammar(Module \mod) {
<nm, imps, exts> = getModuleMetaInf(\mod);
return \module(nm, imps, exts, syntax2grammar(collect(\mod)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,26 @@ int main(list[str] args) {
storeParsersForModules(pcfg);
}
```

Or, you could use the ((PathConfig)) parameter feature of `main` functions. The Rascal maven plugin will
make sure to pass the proper ((PathConfig)) parameter to your main function:
```rascal
module YourMainModule

import util::Reflective;
import lang::rascal::grammar::storage::ModuleParserStorage;

int main(PathConfig pcfg = pathConfig()) {
storeParsersForModules(pcfg);
}
```
}
void storeParsersForModules(PathConfig pcfg) {
storeParsersForModules({*find(src, "rsc") | src <- pcfg.srcs, bprintln("Crawling <src>")}, pcfg);
storeParsersForModules({*find(src, "rsc", exclude={*pcfg.ignores}, checkExist=true) | src <- pcfg.srcs, bprintln("Crawling <src>")}, pcfg);
}

void storeParsersForModules(set[loc] moduleFiles, PathConfig pcfg) {
storeParsersForModules({parseModule(m) | m <- moduleFiles, bprintln("Loading <m>")}, pcfg);
storeParsersForModules({parseModule(m) | m <- moduleFiles, m notin pcfg.ignores, bprintln("Loading <m>")}, pcfg);
}

void storeParsersForModules(set[Module] modules, PathConfig pcfg) {
Expand Down
85 changes: 72 additions & 13 deletions src/org/rascalmpl/library/util/FileSystem.rsc
Original file line number Diff line number Diff line change
Expand Up @@ -7,35 +7,94 @@
}
module util::FileSystem

import Exception;
import IO;
import util::Monitor;

@synopsis{Model of a file system with its (nested) files and directories}
data FileSystem
= directory(loc l, set[FileSystem] children)
| file(loc l)
;

FileSystem crawl(loc l) = isDirectory(l) ? directory(l, {crawl(e) | e <- l.ls}) : file(l);
@synopsis{Extract a compositional ((FileSystem)) model starting from a given directory location.}
@description{
* Using `exclude` you can avoid going into certain directories or filter specific files from the result.
* With `checkExist=true` the `l` parameter is checked to exist before the file system is crawled and a PathNotFound exception is thrown if not.
}
FileSystem crawl(loc l, set[loc] exclude= {}, bool checkExist=false) throws PathNotFound
= isDirectory(l) ? directory(l, {crawl(e, exclude=exclude, checkExist=false) | e <- l.ls, l notin exclude}) : file(l)
when checkExist ==> throwNotExist(l)
;

@synopsis{Recursively lists locations of all files from the supplied directory.
If input is a file, its location is returned instead.}
set[loc] files(loc l) = isDirectory(l) ? { *files(e) | e <- l.ls } : {l};
@synopsis{Recursively lists locations of all files from the supplied directory.}
@description{
* If input `l` is a file, its location is returned instead.
* Using `exclude` you can avoid going into certain directories or filter specific files from the result.
* With `checkExist=true` the `l` parameter is checked to exist before the file system is crawled and a PathNotFound exception is thrown if not.
}
set[loc] files(loc l, set[loc] exclude={}, bool checkExist=false) throws PathNotFound
= isDirectory(l) ? { *files(e, exclude=exclude, checkExist=false) | e <- l.ls, e notin exclude} : {l}
when checkExist ==> throwNotExist(l);

@synopsis{Recursively lists locations of all files that satisfy the filter criterion `filt`.
For a file to be included, `filt` must return `true` for it.}
set[loc] find(loc f, bool (loc) filt)
@synopsis{Recursively lists locations of all files that satisfy the filter criterion `filt`.}
@description{
* For a file to be included, `filt` must return `true` for it. All directories are traversed though, regardless of `filt`.
* Using `exclude` you can avoid going into certain directories or filter specific files from the result.
* With `checkExist=true` the `f` parameter is checked to exist before the file system is crawled and a PathNotFound exception is thrown if not.
}
set[loc] find(loc f, bool (loc) filt, set[loc] exclude = {}, bool checkExist=false) throws PathNotFound
= isDirectory(f)
? {*find(c, filt) | c <- f.ls} + (filt(f) ? {f} : { })
? {*find(c, filt, exclude=exclude, checkExist=false) | c <- f.ls, c notin exclude} + ((filt(f) && f notin exclude) ? {f} : { })
: (filt(f) ? {f} : { })
when checkExist ==> throwNotExist(f)
;

@synopsis{Recursively lists locations of all files that end in `ext`.}
set[loc] find(loc f, str ext) = find(f, bool (loc l) { return l.extension == ext; });
@description{
* For a file to be included, it's extension must equal `ext`. All directories are traversed though, regardless of their extension.
* Using `exclude` you can avoid going into certain directories or filter specific files from the result.
* With `checkExist=true` the `f` parameter is checked to exist before the file system is crawled and a PathNotFound exception is thrown if not.
}
set[loc] find(loc f, str ext, set[loc] exclude={}, bool checkExist=false) throws PathNotFound
= find(f, bool (loc l) { return l.extension == ext; }, exclude=exclude, checkExist=checkExist);

@synopsis{Lists all files recursively ignored files and directories starting with a dot.}
set[loc] visibleFiles(loc l) {
if (/^\./ := l.file)
set[loc] visibleFiles(loc l, bool checkExist=false) throws PathNotFound {
if (checkExist) {
throwNotExist(l);
}
if (/^\./ := l.file) {
return {};
if (isDirectory(l))
return {*visibleFiles(f) | f <- l.ls};
}
if (isDirectory(l)) {
return {*visibleFiles(f, checkExist=false) | f <- l.ls};
}
return {l};
}

@synopsis{Always returns true, but shows a ((util::Monitor::jobWarning)) if `file` does not exist.}
@benefits{
* This can be used practically in comprehensions that process file locations.
* Use it to fail more transparantly, but still in case of erroneous file configuration (paths)
}
bool warnNotExist(loc file) {
if (!exists(file)) {
jobWarning("<file> does not exist.", |std:///util/FileSystem|);
}
return true;
}

@synopsis{Always returns true, except when throwing FileNotFound if `file` does not exist}
@benefits{
* This can be used practically in comprehensions that process file locations;
* Use it to fail faster and harder in case of erroneous file configuration (paths)
}
bool throwNotExist(loc file) throws PathNotFound {
if (!exists(file)) {
throw PathNotFound(file);
}
return true;
}


Loading