UNPKG

gulp-traceur-compiler

Version:
168 lines (118 loc) 5.16 kB
// Copyright 2012 Traceur Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. 'use strict'; var fs = require('fs'); var path = require('path'); var nodeLoader = require('./nodeLoader'); module.exports = function (traceur, compiler) { var TraceurLoader = traceur.runtime.TraceurLoader; var InlineLoaderCompiler = traceur.runtime.InlineLoaderCompiler; var Options = traceur.util.Options; function normalizePath(s) { return path.sep == '\\' ? s.replace(/\\/g, '/') : s; } function recursiveModuleCompileToSingleFile(includes, options, filePath, callback) { var outputDir = path.resolve(process.cwd(), path.dirname(filePath)); process.chdir(outputDir); // Make includes relative to output dir so that sourcemap paths are correct. var resolvedIncludes = includes.map(function(include) { include.name = normalizePath(path.relative(outputDir, include.name)); return include; }); function error(err) { callback(err); } recursiveModuleCompile(resolvedIncludes, options, function (tree) { var compiled; compiled = compiler.write(tree, filePath); callback(null, compiled); }, error); } /** * Compiles the files in "fileNamesAndTypes" along with any associated modules, * into a single js file, in module dependency order. * TODO: Make this function also use a promise * * @param {Array.<Object>} fileNamesAndTypes The list of {name, type} * to compile and concat; type is 'module' or 'script' * @param {Object} options A container for misc options. 'depTarget' is the * only currently available option, which results in the dependencies for * 'fileNamesAndTypes' being printed to stdout, with 'depTarget' as the target. * @param {Function} callback Callback used to return the result. A null result * indicates that recursiveModuleCompile has returned successfully from a * non-compile request. * @param {Function} errback Callback used to return errors. */ function recursiveModuleCompile(fileNamesAndTypes, options, callback, errback) { var depTarget = options && options.depTarget; var referrerName = options && options.referrer; var basePath = path.resolve('./') + '/'; basePath = basePath.replace(/\\/g, '/'); var loadCount = 0; var elements = []; var loaderCompiler = new InlineLoaderCompiler(elements); var loader = new TraceurLoader(nodeLoader, basePath, loaderCompiler); function appendEvaluateModule(name, referrerName) { var normalizedName = traceur.ModuleStore.normalize(name, referrerName); // Create tree for System.get('normalizedName'); var moduleModule = traceur.codegeneration.module; var tree = moduleModule.createModuleEvaluationStatement(normalizedName); elements.push(tree); } function loadNext() { var doEvaluateModule = false; var loadFunction = loader.import; var input = fileNamesAndTypes[loadCount]; var name = input.name; var optionsCopy = new Options(options); // Give each load a copy of options. if (input.type === 'script') { loadFunction = loader.loadAsScript; } else { name = name.replace(/\.js$/,''); if (input.format === 'inline') optionsCopy.modules = 'inline'; else if (optionsCopy.modules === 'register') doEvaluateModule = true; } var loadOptions = { referrerName: referrerName, metadata: {traceurOptions: optionsCopy} }; var codeUnit = loadFunction.call(loader, name, loadOptions).then( function() { if (doEvaluateModule) appendEvaluateModule(name, referrerName); loadCount++; if (loadCount < fileNamesAndTypes.length) { loadNext(); } else if (depTarget) { callback(null); } else { var tree = loaderCompiler.toTree(basePath, elements); callback(tree); } }, function(err) { errback(err); }).catch(function(ex) { console.error('' + (ex.stack || ex)); }); } loadNext(); } return { recursiveModuleCompile: recursiveModuleCompile, recursiveModuleCompileToSingleFile: recursiveModuleCompileToSingleFile } }