From c276f3e5a7769188575f4a1eaa235e4bb2fe8e6d Mon Sep 17 00:00:00 2001 From: zoweb Date: Sun, 28 Oct 2018 15:40:19 +1000 Subject: [PATCH 1/4] Add Kotlin asset support --- packages/core/parcel-bundler/src/Parser.js | 1 + .../parcel-bundler/src/assets/KotlinAsset.js | 63 +++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 packages/core/parcel-bundler/src/assets/KotlinAsset.js diff --git a/packages/core/parcel-bundler/src/Parser.js b/packages/core/parcel-bundler/src/Parser.js index e53503cb5a3..09163cb6d4a 100644 --- a/packages/core/parcel-bundler/src/Parser.js +++ b/packages/core/parcel-bundler/src/Parser.js @@ -27,6 +27,7 @@ class Parser { this.registerExtension('toml', './assets/TOMLAsset'); this.registerExtension('gql', './assets/GraphqlAsset'); this.registerExtension('graphql', './assets/GraphqlAsset'); + this.registerExtension('kt', './assets/KotlinAsset'); this.registerExtension('css', './assets/CSSAsset'); this.registerExtension('pcss', './assets/CSSAsset'); diff --git a/packages/core/parcel-bundler/src/assets/KotlinAsset.js b/packages/core/parcel-bundler/src/assets/KotlinAsset.js new file mode 100644 index 00000000000..a9c4709fc41 --- /dev/null +++ b/packages/core/parcel-bundler/src/assets/KotlinAsset.js @@ -0,0 +1,63 @@ +const Asset = require('../Asset'); +const localRequire = require('../utils/localRequire'); + +class KotlinAsset extends Asset { + constructor(name, options) { + super(name, options); + this.type = 'js'; + } + + async generate() { + // require kotlin + const kotlinCompiler = await localRequire( + '@jetbrains/kotlinc-js-api', + this.name + ); + const fs = require('fs', this.name); + + // remove extension + let fileName = this.id.substring(0, this.id.lastIndexOf('.')); + + await kotlinCompiler.compile({ + output: 'build/kt.temp/' + fileName + '.js', + sources: [this.name], + moduleKind: 'commonjs', + noStdlib: false, + metaInfo: false, + sourceMaps: this.options.sourceMaps + }); + + let source = fs.readFileSync('build/kt.temp/' + fileName + '.js', 'utf8'); + let sourceMap; + if (this.options.sourceMaps) { + sourceMap = fs.readFileSync( + 'build/kt.temp/' + fileName + '.js.map', + 'utf8' + ); + + sourceMap = JSON.parse(sourceMap); + sourceMap.sources = [this.relativeName]; + sourceMap.sourcesContent = [this.contents]; + + // remove source map url + source = source.substring(0, source.lastIndexOf('//# sourceMappingURL')); + } + + // delete old files + fs.unlinkSync('build/kt.temp/' + fileName + '.js'); + fs.unlinkSync('build/kt.temp/' + fileName + '.js.map'); + if (fs.readdirSync('build/kt.temp').length === 0) + fs.rmdirSync('build/kt.temp'); // Remove kt.temp directory if it is empty + if (fs.readdirSync('build').length === 0) fs.rmdirSync('build'); // Remove build directory if it is empty + + return [ + { + type: 'js', + value: source, + sourceMap + } + ]; + } +} + +module.exports = KotlinAsset; From 2b939190d809cf81b3242ddfb460645d8c889f79 Mon Sep 17 00:00:00 2001 From: zoweb Date: Mon, 29 Oct 2018 21:03:53 +1000 Subject: [PATCH 2/4] remove path parts to fix "../" --- packages/core/parcel-bundler/src/assets/KotlinAsset.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/core/parcel-bundler/src/assets/KotlinAsset.js b/packages/core/parcel-bundler/src/assets/KotlinAsset.js index a9c4709fc41..9137c334f07 100644 --- a/packages/core/parcel-bundler/src/assets/KotlinAsset.js +++ b/packages/core/parcel-bundler/src/assets/KotlinAsset.js @@ -15,8 +15,10 @@ class KotlinAsset extends Asset { ); const fs = require('fs', this.name); - // remove extension - let fileName = this.id.substring(0, this.id.lastIndexOf('.')); + // remove extension and path + let slashyIndex = this.id.lastIndexOf('/'); // linux/mac + if (slashyIndex === -1) slashyIndex = this.id.lastIndexOf('\\'); // windows + const fileName = this.id.substring(slashyIndex, this.id.lastIndexOf('.')); await kotlinCompiler.compile({ output: 'build/kt.temp/' + fileName + '.js', From 5e4fbd97d1798afa0956473c5a3398a6e1cc43dd Mon Sep 17 00:00:00 2001 From: Devon Govett Date: Mon, 17 Dec 2018 21:04:38 -0800 Subject: [PATCH 3/4] Add kotlin tests and use tmpdir --- packages/core/fs/package.json | 3 +- packages/core/fs/src/fs.js | 2 ++ packages/core/integration-tests/package.json | 2 ++ .../test/integration/kotlin/index.js | 3 ++ .../test/integration/kotlin/test.kt | 4 +++ .../core/integration-tests/test/kotlin.js | 17 +++++++++ .../parcel-bundler/src/assets/KotlinAsset.js | 35 +++++++++---------- 7 files changed, 47 insertions(+), 19 deletions(-) create mode 100644 packages/core/integration-tests/test/integration/kotlin/index.js create mode 100644 packages/core/integration-tests/test/integration/kotlin/test.kt create mode 100644 packages/core/integration-tests/test/kotlin.js diff --git a/packages/core/fs/package.json b/packages/core/fs/package.json index a457e82e649..587d423aa82 100644 --- a/packages/core/fs/package.json +++ b/packages/core/fs/package.json @@ -20,7 +20,8 @@ "prepublish": "yarn build" }, "dependencies": { + "@parcel/utils": "^1.10.3", "mkdirp": "^0.5.1", - "@parcel/utils": "^1.10.3" + "rimraf": "^2.6.2" } } diff --git a/packages/core/fs/src/fs.js b/packages/core/fs/src/fs.js index 2677726507a..4e6bdce13c9 100644 --- a/packages/core/fs/src/fs.js +++ b/packages/core/fs/src/fs.js @@ -1,12 +1,14 @@ const {promisify} = require('@parcel/utils'); const fs = require('fs'); const mkdirp = require('mkdirp'); +const rimraf = require('rimraf'); exports.readFile = promisify(fs.readFile); exports.writeFile = promisify(fs.writeFile); exports.stat = promisify(fs.stat); exports.readdir = promisify(fs.readdir); exports.unlink = promisify(fs.unlink); +exports.rimraf = promisify(rimraf); exports.realpath = async function(path) { const realpath = promisify(fs.realpath); try { diff --git a/packages/core/integration-tests/package.json b/packages/core/integration-tests/package.json index b41033be826..05f684ff89a 100644 --- a/packages/core/integration-tests/package.json +++ b/packages/core/integration-tests/package.json @@ -13,12 +13,14 @@ }, "devDependencies": { "@babel/core": "^7.2.0", + "@jetbrains/kotlinc-js-api": "^1.2.12", "@parcel/fs": "^1.10.3", "@parcel/test-utils": "^1.10.3", "codecov": "^3.0.0", "command-exists": "^1.2.6", "graphql-tag": "^2.6.0", "json5": "^1.0.1", + "kotlin": "^1.3.11", "mocha": "^5.1.1", "mocha-junit-reporter": "^1.18.0", "mocha-multi-reporters": "^1.1.7", diff --git a/packages/core/integration-tests/test/integration/kotlin/index.js b/packages/core/integration-tests/test/integration/kotlin/index.js new file mode 100644 index 00000000000..9b8ef8f3b67 --- /dev/null +++ b/packages/core/integration-tests/test/integration/kotlin/index.js @@ -0,0 +1,3 @@ +var test = require('./test.kt'); + +module.exports = test.sum(2, 3); diff --git a/packages/core/integration-tests/test/integration/kotlin/test.kt b/packages/core/integration-tests/test/integration/kotlin/test.kt new file mode 100644 index 00000000000..ade742be26b --- /dev/null +++ b/packages/core/integration-tests/test/integration/kotlin/test.kt @@ -0,0 +1,4 @@ +@JsName("sum") +fun sum(a: Int, b: Int): Int { + return a + b +} diff --git a/packages/core/integration-tests/test/kotlin.js b/packages/core/integration-tests/test/kotlin.js new file mode 100644 index 00000000000..037351951aa --- /dev/null +++ b/packages/core/integration-tests/test/kotlin.js @@ -0,0 +1,17 @@ +const assert = require('assert'); +const fs = require('@parcel/fs'); +const {bundle, assertBundleTree, run} = require('./utils'); + +describe('kotlin', function() { + it('should produce a basic kotlin bundle', async function() { + let b = await bundle(__dirname + '/integration/kotlin/index.js'); + + await assertBundleTree(b, { + type: 'js', + assets: ['test.kt', 'index.js', 'browser.js', 'kotlin.js'] + }); + + let output = await run(b); + assert.equal(output, 5); + }); +}); diff --git a/packages/core/parcel-bundler/src/assets/KotlinAsset.js b/packages/core/parcel-bundler/src/assets/KotlinAsset.js index 9137c334f07..4dc108b6f9d 100644 --- a/packages/core/parcel-bundler/src/assets/KotlinAsset.js +++ b/packages/core/parcel-bundler/src/assets/KotlinAsset.js @@ -1,5 +1,9 @@ const Asset = require('../Asset'); const localRequire = require('../utils/localRequire'); +const path = require('path'); +const fs = require('@parcel/fs'); +const os = require('os'); +const spawn = require('cross-spawn'); class KotlinAsset extends Asset { constructor(name, options) { @@ -13,29 +17,28 @@ class KotlinAsset extends Asset { '@jetbrains/kotlinc-js-api', this.name ); - const fs = require('fs', this.name); - // remove extension and path - let slashyIndex = this.id.lastIndexOf('/'); // linux/mac - if (slashyIndex === -1) slashyIndex = this.id.lastIndexOf('\\'); // windows - const fileName = this.id.substring(slashyIndex, this.id.lastIndexOf('.')); + let id = Math.random() + .toString(36) + .slice(3); + let dir = path.join(os.tmpdir(), id); + let filename = path.join(dir, id + '.js'); + + await fs.mkdirp(dir); await kotlinCompiler.compile({ - output: 'build/kt.temp/' + fileName + '.js', + output: filename, sources: [this.name], moduleKind: 'commonjs', noStdlib: false, - metaInfo: false, + metaInfo: true, sourceMaps: this.options.sourceMaps }); - let source = fs.readFileSync('build/kt.temp/' + fileName + '.js', 'utf8'); + let source = await fs.readFile(filename, 'utf8'); let sourceMap; if (this.options.sourceMaps) { - sourceMap = fs.readFileSync( - 'build/kt.temp/' + fileName + '.js.map', - 'utf8' - ); + sourceMap = await fs.readFile(filename + '.map', 'utf8'); sourceMap = JSON.parse(sourceMap); sourceMap.sources = [this.relativeName]; @@ -45,12 +48,8 @@ class KotlinAsset extends Asset { source = source.substring(0, source.lastIndexOf('//# sourceMappingURL')); } - // delete old files - fs.unlinkSync('build/kt.temp/' + fileName + '.js'); - fs.unlinkSync('build/kt.temp/' + fileName + '.js.map'); - if (fs.readdirSync('build/kt.temp').length === 0) - fs.rmdirSync('build/kt.temp'); // Remove kt.temp directory if it is empty - if (fs.readdirSync('build').length === 0) fs.rmdirSync('build'); // Remove build directory if it is empty + // delete temp directory + await fs.rimraf(dir); return [ { From 293323140d8c6241e290dc4259e448cf4ed8aaa4 Mon Sep 17 00:00:00 2001 From: Devon Govett Date: Mon, 17 Dec 2018 21:36:43 -0800 Subject: [PATCH 4/4] Lint --- packages/core/integration-tests/test/kotlin.js | 1 - packages/core/parcel-bundler/src/assets/KotlinAsset.js | 1 - 2 files changed, 2 deletions(-) diff --git a/packages/core/integration-tests/test/kotlin.js b/packages/core/integration-tests/test/kotlin.js index 037351951aa..0e62f88133d 100644 --- a/packages/core/integration-tests/test/kotlin.js +++ b/packages/core/integration-tests/test/kotlin.js @@ -1,5 +1,4 @@ const assert = require('assert'); -const fs = require('@parcel/fs'); const {bundle, assertBundleTree, run} = require('./utils'); describe('kotlin', function() { diff --git a/packages/core/parcel-bundler/src/assets/KotlinAsset.js b/packages/core/parcel-bundler/src/assets/KotlinAsset.js index 4dc108b6f9d..08eeabbc169 100644 --- a/packages/core/parcel-bundler/src/assets/KotlinAsset.js +++ b/packages/core/parcel-bundler/src/assets/KotlinAsset.js @@ -3,7 +3,6 @@ const localRequire = require('../utils/localRequire'); const path = require('path'); const fs = require('@parcel/fs'); const os = require('os'); -const spawn = require('cross-spawn'); class KotlinAsset extends Asset { constructor(name, options) {