"use strict"; var Class = require("rtl.js").Class; var Code = require("js/Code.js"); var ContextHierarchy = require("js/ContextHierarchy.js"); var oc = require("oc.js"); var makeRTL = require("rtl_code.js").makeRTL; var fs = require("fs"); var path = require("path"); var ModuleGenerator = Class.extend({ init: function Nodejs$ModuleGenerator(name, imports, importDir){ this.__name = name; this.__imports = imports; this.__importDir = importDir; }, prolog: function(){ var result = ""; var modules = this.__imports; for(var name in modules){ var alias = modules[name]; var importName = this.__importDir ? this.__importDir + "/" + name : name; result += "var " + alias + " = " + (name == "this" ? "GLOBAL" : "require(\"" + importName + ".js\")") + ";\n"; } return result; }, epilog: function(exports){ var result = ""; for(var access in exports){ var e = exports[access]; var code = Code.genExport(e); if (code){ var id = Code.exportId(e); result += "exports." + id + " = " + code + ";\n"; } } return result; } }); var RtlCodeUsingWatcher = Class.extend({ init: function(){this.__used = false;}, using: function(){this.__used = true;}, used: function(){return this.__used;}, reset: function(){this.__used = false;} }); function writeCompiledModule(name, code, outDir){ var filePath = path.join(outDir, name + ".js"); fs.writeFileSync(filePath, code); } function compile(sources, language, handleErrors, includeDirs, outDir, importDir){ var rtlCodeWatcher = new RtlCodeUsingWatcher(); var rtl = new makeRTL(language.rtl, rtlCodeWatcher.using.bind(rtlCodeWatcher)); var moduleCode = function(name, imports){ return new ModuleGenerator(name, imports, importDir);}; var compiledFilesStack = []; oc.compileModules( sources, function(name){ var fileName = name; if (!path.extname(fileName).length) fileName += ".ob"; compiledFilesStack.push(fileName); var readPath = fileName; var i = 0; while (!fs.existsSync(readPath) && i < includeDirs.length){ readPath = path.join(includeDirs[i], fileName); ++i; } if (!fs.existsSync(readPath)) throw new Error("cannot find file: '" + fileName + "' in " + includeDirs); return fs.readFileSync(readPath, "utf8"); }, language.grammar, function(moduleResolver){return new ContextHierarchy.Root( { codeGenerator: language.codeGenerator.make(), moduleGenerator: moduleCode, rtl: rtl, types: language.types, stdSymbols: language.stdSymbols, moduleResolver: moduleResolver });}, function(e){handleErrors("File \"" + compiledFilesStack[compiledFilesStack.length - 1] + "\", " + e);}, function(name, code){ if (rtlCodeWatcher.used()){ code = "var " + rtl.name() + " = require(\"" + rtl.module() + "\");\n" + code; rtlCodeWatcher.reset(); } writeCompiledModule(name, code, outDir); compiledFilesStack.pop(); }); } exports.compile = compile;