From 5bbcaedc01ac74dc5cddb29270ed549eae350808 Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Mon, 13 Jul 2015 14:48:19 -0400 Subject: [PATCH] Allow source processors to be registered for .js files. We now fall back to hardcoded JS support only when no source processor is registered, instead of simply ignoring .js source processors. --- tools/build-plugin.js | 34 ++++++++++++++++++++-------- tools/compiler-plugin.js | 49 ++++++++++++++++++---------------------- tools/isopack.js | 3 ++- 3 files changed, 48 insertions(+), 38 deletions(-) diff --git a/tools/build-plugin.js b/tools/build-plugin.js index f8ffb4bc8e..2591177089 100644 --- a/tools/build-plugin.js +++ b/tools/build-plugin.js @@ -60,8 +60,11 @@ _.extend(exports.SourceProcessor.prototype, { // Represents a set of SourceProcessors available in a given package. They may // not have conflicting extensions or filenames. export class SourceProcessorSet { - constructor(myPackageDisplayName, - { hardcodeJs, singlePackage, allowConflicts }) { + constructor(myPackageDisplayName, { + hardcodeJs, + singlePackage, + allowConflicts, + } = {}) { // For error messages only. this._myPackageDisplayName = myPackageDisplayName; // If this represents the SourceProcessors *registered* by a single package @@ -206,13 +209,6 @@ export class SourceProcessorSet { // don't use iteration functions, so we can return (and start at #1) for (let i = 1; i < parts.length; i++) { const extension = parts.slice(i).join('.'); - // We specially handle 'js' in the build tool, because you can't provide a - // plugin to handle 'js' files, because the plugin would need to be built - // with JavaScript itself! Places that hardcode JS are tagged with - // #HardcodeJs. - if (this._hardcodeJs && extension === 'js') { - return new SourceClassification('extension', {extension}); - } if (this._byExtension.hasOwnProperty(extension)) { return new SourceClassification('extension', { @@ -222,6 +218,13 @@ export class SourceProcessorSet { }); } + if (this._hardcodeJs && extension === 'js') { + // If there is no special sourceProcessor for handling a .js file, + // we can still classify it as extension/js, only without any + // source processors. #HardcodeJs + return new SourceClassification('extension', {extension}); + } + if (this._legacyHandlers.hasOwnProperty(extension)) { const legacy = this._legacyHandlers[extension]; if (legacy.archMatching && @@ -251,17 +254,28 @@ export class SourceProcessorSet { appReadDirectoryOptions(arch) { const include = []; const names = []; + let addedJs = false; function addExtension(ext) { include.push(new RegExp('\\.' + utils.quotemeta(ext) + '$')); + if (ext === 'js') { + addedJs = true; + } } + _.each(this._byExtension, (sourceProcessors, ext) => { if (sourceProcessors.some(sp => sp.relevantForArch(arch))) { addExtension(ext); } }); Object.keys(this._legacyHandlers).forEach(addExtension); - this._hardcodeJs && addExtension('js'); + + if (this._hardcodeJs && ! addedJs) { + // If there is no sourceProcessor for handling .js files, we still + // want to make sure they get picked up when we're reading the + // contents of app directories. #HardcodeJs + addExtension('js'); + } _.each(this._byFilename, (sourceProcessors, filename) => { if (sourceProcessors.some(sp => sp.relevantForArch(arch))) { diff --git a/tools/compiler-plugin.js b/tools/compiler-plugin.js index f0f16ff7fd..dae30b97c6 100644 --- a/tools/compiler-plugin.js +++ b/tools/compiler-plugin.js @@ -264,29 +264,25 @@ var ResourceSlot = function (unibuildResourceInfo, self.sourceProcessor = sourceProcessor; self.packageSourceBatch = packageSourceBatch; - if (self.inputResource.type === "source" && - self.inputResource.extension === "js") { - // #HardcodeJs + if (self.inputResource.type === "source") { if (sourceProcessor) { - throw Error("sourceProcessor found for js source? " + - JSON.stringify(unibuildResourceInfo)); - } - self.addJavaScript({ - // XXX it's a shame to keep converting between Buffer and string, but - // files.convertToStandardLineEndings only works on strings for now - data: self.inputResource.data.toString('utf8'), - path: self.inputResource.path, - hash: self.inputResource.hash, - bare: self.inputResource.fileOptions && - (self.inputResource.fileOptions.bare || - // XXX eventually get rid of backward-compatibility "raw" name - // XXX COMPAT WITH 0.6.4 - self.inputResource.fileOptions.raw) - }); - } else if (self.inputResource.type === "source") { - if (! sourceProcessor) { - throw Error("no sourceProcessor for source? " + - JSON.stringify(unibuildResourceInfo)); + // If we have a sourceProcessor, it will handle the adding of the + // final processed JavaScript. + } else if (self.inputResource.extension === "js") { + // If there is no sourceProcessor for a .js file, add the source + // directly to the output. #HardcodeJs + self.addJavaScript({ + // XXX it's a shame to keep converting between Buffer and string, but + // files.convertToStandardLineEndings only works on strings for now + data: self.inputResource.data.toString('utf8'), + path: self.inputResource.path, + hash: self.inputResource.hash, + bare: self.inputResource.fileOptions && + (self.inputResource.fileOptions.bare || + // XXX eventually get rid of backward-compatibility "raw" name + // XXX COMPAT WITH 0.6.4 + self.inputResource.fileOptions.raw) + }); } } else { if (sourceProcessor) { @@ -395,10 +391,7 @@ var PackageSourceBatch = function (unibuild, processor) { let sourceProcessor = null; if (resource.type === "source") { var extension = resource.extension; - if (extension === 'js') { - // #HardcodeJs In this case, we just leave buildPlugin null; it is - // specially handled by ResourceSlot too. - } else if (extension === null) { + if (extension === null) { const filename = files.pathBasename(resource.path); sourceProcessor = sourceProcessorSet.getByFilename(filename); if (! sourceProcessor) { @@ -411,7 +404,9 @@ var PackageSourceBatch = function (unibuild, processor) { } } else { sourceProcessor = sourceProcessorSet.getByExtension(extension); - if (! sourceProcessor) { + // If resource.extension === 'js', it's ok for there to be no + // sourceProcessor, since we #HardcodeJs in ResourceSlot. + if (! sourceProcessor && extension !== 'js') { buildmessage.error( `no plugin found for ${ resource.path } in ` + `${ unibuild.pkg.displayName() }; a plugin for *.${ extension } ` + diff --git a/tools/isopack.js b/tools/isopack.js index f19a08d786..ad3f280a6b 100644 --- a/tools/isopack.js +++ b/tools/isopack.js @@ -1149,7 +1149,8 @@ _.extend(Isopack.prototype, { // If we're going to write a legacy prelink file later, track the // original form of the resource object (with the source in a Buffer, // etc) instead of the later version. #HardcodeJs - if (writeLegacyBuilds && resource.type === "source" && + if (writeLegacyBuilds && + resource.type === "source" && resource.extension == "js") { jsResourcesForLegacyPrelink.push({ data: resource.data,