Skip to content
Open
Show file tree
Hide file tree
Changes from 4 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}) | 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
83 changes: 71 additions & 12 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=true) 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=true) 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=true) 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=true) 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=true) throws PathNotFound {
if (checkExist) {
throwNotExist(l);
}
if (/^\./ := l.file) {
return {};
if (isDirectory(l))
}
if (isDirectory(l)) {
return {*visibleFiles(f) | f <- l.ls};
Comment thread
jurgenvinju marked this conversation as resolved.
Outdated
}
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