List<String> todo = new LinkedList<String>();
Set<String> done = new HashSet<String>();
todo.add(getName());
IValueFactory VF = ValueFactoryFactory.getValueFactory();
IMapWriter result = VF.mapWriter();
while(!todo.isEmpty()){
String m = todo.get(0);
todo.remove(0);
if(done.contains(m))
continue;
done.add(m);
/* This allows the current module not to be loaded on the heap, for
* parsing in the IDE
*/
ModuleEnvironment env = m.equals(getName()) ? this : heap.getModule(m);
if(env != null){
ISetWriter importWriter = VF.setWriter();
for(String impname : env.getImports()){
if(!done.contains(impname)) todo.add(impname);
importWriter.insert(VF.string(impname));
}
ISetWriter extendWriter = VF.setWriter();
for(String impname : env.getExtends()){
if(!done.contains(impname)) todo.add(impname);
extendWriter.insert(VF.string(impname));
}
ISetWriter defWriter = VF.setWriter();
for(IValue def : env.productions){
defWriter.insert(def);
}
ITuple t = VF.tuple(importWriter.done(), extendWriter.done(), defWriter.done());
result.put(VF.string(m), t);
}else if(m.equals(getName())) { // This is the root scope.
ISetWriter importWriter = VF.setWriter();
for(String impname : importedModules){
if(!done.contains(impname)) todo.add(impname);
importWriter.insert(VF.string(impname));
}
ISetWriter extendWriter = VF.setWriter();
for(String impname : getExtends()){
if(!done.contains(impname)) todo.add(impname);
extendWriter.insert(VF.string(impname));
}
ISetWriter defWriter = VF.setWriter();
for(IValue def : productions){
defWriter.insert(def);
}
ITuple t = VF.tuple(importWriter.done(), extendWriter.done(), defWriter.done());
result.put(VF.string(m), t);
}
}
return result.done();
}