diff --git a/packages/coffeescript/package.js b/packages/coffeescript/package.js index 32200f7074..97183ebb52 100644 --- a/packages/coffeescript/package.js +++ b/packages/coffeescript/package.js @@ -5,7 +5,7 @@ Package.describe({ Package.registerBuildPlugin({ name: "compileCoffeescript", - use: [], + use: ['compiler-plugin'], sources: [ 'plugin/compile-coffeescript.js' ], diff --git a/packages/coffeescript/plugin/compile-coffeescript.js b/packages/coffeescript/plugin/compile-coffeescript.js index d2e9f675fc..dad3e87831 100644 --- a/packages/coffeescript/plugin/compile-coffeescript.js +++ b/packages/coffeescript/plugin/compile-coffeescript.js @@ -120,51 +120,65 @@ var addSharedHeader = function (source, sourceMap) { }; }; -var handler = function (compileStep, isLiterate) { - var source = compileStep.read().toString('utf8'); - var outputFile = compileStep.inputPath + ".js"; +var CoffeeCompiler = function (isLiterate) { + this.isLiterate = isLiterate; +}; - var options = { - bare: true, - filename: compileStep.inputPath, - literate: !!isLiterate, - // Return a source map. - sourceMap: true, - // Include the original source in the source map (sourcesContent field). - inline: true, - // This becomes the "file" field of the source map. - generatedFile: "/" + outputFile, - // This becomes the "sources" field of the source map. - sourceFiles: [compileStep.pathForSourceMap] - }; +CoffeeCompiler.prototype.processFilesForTarget = function (inputFiles) { + var self = this; - try { - var output = coffee.compile(source, options); - } catch (e) { - // XXX better error handling, once the Plugin interface support it - throw new Error( - compileStep.inputPath + ':' + - (e.location ? (e.location.first_line + ': ') : ' ') + - e.message - ); - } + inputFiles.forEach(function (inputFile) { + var source = inputFile.getContentsAsString(); + var outputFilePath = inputFile.getPathInPackage() + ".js"; - var stripped = stripExportedVars(output.js, compileStep.declaredExports); - var sourceWithMap = addSharedHeader(stripped, output.v3SourceMap); + var options = { + bare: true, + filename: inputFile.getPathInPackage(), + literate: !!self.isLiterate, + // Return a source map. + sourceMap: true, + // Include the original source in the source map (sourcesContent field). + inline: true, + // This becomes the "file" field of the source map. + generatedFile: "/" + outputFilePath, + // This becomes the "sources" field of the source map. + sourceFiles: [inputFile.getDisplayPath()] + }; - compileStep.addJavaScript({ - path: outputFile, - sourcePath: compileStep.inputPath, - data: sourceWithMap.source, - sourceMap: sourceWithMap.sourceMap, - bare: compileStep.fileOptions.bare + var output; + try { + output = coffee.compile(source, options); + } catch (e) { + inputFile.error({ + message: e.message, + line: e.location && e.location.first_line + }); + + return; + } + + var stripped = stripExportedVars(output.js, inputFile.getDeclaredExports()); + var sourceWithMap = addSharedHeader(stripped, output.v3SourceMap); + + inputFile.addJavaScript({ + path: outputFilePath, + sourcePath: inputFile.getPathInPackage(), + data: sourceWithMap.source, + sourceMap: sourceWithMap.sourceMap, + bare: inputFile.getFileOptions().bare + }); }); }; -var literateHandler = function (compileStep) { - return handler(compileStep, true); -}; +Plugin.registerCompiler({ + extensions: ['coffee'] +}, function () { + return new CoffeeCompiler(); +}); + +Plugin.registerCompiler({ + extensions: ['litcoffee', 'coffee.md'] +}, function () { + return new CoffeeCompiler(true); +}); -Plugin.registerSourceHandler("coffee", handler); -Plugin.registerSourceHandler("litcoffee", literateHandler); -Plugin.registerSourceHandler("coffee.md", literateHandler); diff --git a/packages/less/plugin/compile-less.js b/packages/less/plugin/compile-less.js index 83da01e42f..ea8132402d 100644 --- a/packages/less/plugin/compile-less.js +++ b/packages/less/plugin/compile-less.js @@ -7,7 +7,7 @@ Plugin.registerCompiler({ extensions: ['less'], archMatching: 'web' }, function () { - return new LessCompiler; + return new LessCompiler(); }); var LessCompiler = function () { @@ -32,7 +32,7 @@ LessCompiler.prototype.processFilesForTarget = function (inputFiles) { var importPlugin = new MeteorImportLessPlugin(filesByAbsoluteImportPath); - _.each(mains, function (main) { + mains.forEach(function (main) { var inputFile = main.inputFile; var absoluteImportPath = main.absoluteImportPath; var f = new Future; @@ -120,3 +120,4 @@ _.extend(MeteorImportLessFileManager.prototype, { return; } }); + diff --git a/tools/compiler-plugin.js b/tools/compiler-plugin.js index 01c61d1f38..6cf9ff3a81 100644 --- a/tools/compiler-plugin.js +++ b/tools/compiler-plugin.js @@ -127,6 +127,29 @@ _.extend(InputFile.prototype, { var self = this; return self._resourceSlot.inputResource.path; }, + // XXX BBP document it and implement it for linting, too + getDeclaredExports: function () { + var self = this; + return self._resourceSlot.packageSourceBatch.unibuild.declaredExports; + }, + // XXX BBP document and implement for linting, too + getFileOptions: function () { + var self = this; + // XXX fileOptions only exists on some resources (of type "source"). The JS + // resources might not have this property. + return self._resourceSlot.inputResource.fileOptions; + }, + + /** + * @summary Returns a relative path that can be used to form error messages or + * other display properties. Can be used as an input to a source map. + * @memberof InputFile + * @returns {String} + */ + getDisplayPath: function () { + var self = this; + return self._resourceSlot.packageSourceBatch.unibuild.pkg._getServePath() + "/" + self.getPathInPackage(); + }, /** * @summary Web targets only. Add a stylesheet to the document. Not available