New build system (#4449)
parent
bb6d130b5b
commit
52a2a46b3c
|
@ -3,6 +3,7 @@
|
|||
!/tests/**/jsfmt.spec.js
|
||||
!/**/.eslintrc.js
|
||||
/test.js
|
||||
/scripts/build/shims
|
||||
/coverage/
|
||||
/dist/
|
||||
**/node_modules/**
|
||||
|
|
|
@ -10,7 +10,7 @@ module.exports = {
|
|||
collectCoverage: ENABLE_COVERAGE,
|
||||
collectCoverageFrom: ["src/**/*.js", "index.js", "!<rootDir>/node_modules/"],
|
||||
coveragePathIgnorePatterns: [
|
||||
"<rootDir>/web.js",
|
||||
"<rootDir>/standalone.js",
|
||||
"<rootDir>/src/doc/doc-debug.js",
|
||||
"<rootDir>/src/main/massage-ast.js"
|
||||
],
|
||||
|
@ -18,7 +18,7 @@ module.exports = {
|
|||
// Jest wires `fs` to `graceful-fs`, which causes a memory leak when
|
||||
// `graceful-fs` does `require('fs')`.
|
||||
// Ref: https://github.com/facebook/jest/issues/2179#issuecomment-355231418
|
||||
// If this is removed, see also rollup.bin.config.js and rollup.index.config.js.
|
||||
// If this is removed, see also scripts/build/build.js.
|
||||
"graceful-fs": "<rootDir>/tests_config/fs.js"
|
||||
},
|
||||
transform: {}
|
||||
|
|
11
package.json
11
package.json
|
@ -60,8 +60,10 @@
|
|||
"unified": "6.1.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-cli": "6.24.1",
|
||||
"babel-preset-es2015": "6.24.1",
|
||||
"@babel/cli": "7.0.0-beta.40",
|
||||
"@babel/core": "7.0.0-beta.40",
|
||||
"@babel/preset-env": "7.0.0-beta.40",
|
||||
"builtin-modules": "2.0.0",
|
||||
"codecov": "2.2.0",
|
||||
"cross-env": "5.0.5",
|
||||
"eslint": "4.18.2",
|
||||
|
@ -76,17 +78,18 @@
|
|||
"prettylint": "1.0.0",
|
||||
"rimraf": "2.6.2",
|
||||
"rollup": "0.47.6",
|
||||
"rollup-plugin-babel": "4.0.0-beta.4",
|
||||
"rollup-plugin-commonjs": "8.2.6",
|
||||
"rollup-plugin-json": "2.1.1",
|
||||
"rollup-plugin-node-builtins": "2.0.0",
|
||||
"rollup-plugin-node-globals": "1.1.0",
|
||||
"rollup-plugin-node-resolve": "2.0.0",
|
||||
"rollup-plugin-replace": "1.2.1",
|
||||
"rollup-plugin-uglify": "3.0.0",
|
||||
"shelljs": "0.8.1",
|
||||
"snapshot-diff": "0.2.2",
|
||||
"strip-ansi": "4.0.0",
|
||||
"tempy": "0.2.1",
|
||||
"uglify-es": "3.3.9",
|
||||
"webpack": "2.6.1"
|
||||
},
|
||||
"scripts": {
|
||||
|
@ -98,7 +101,7 @@
|
|||
"lint": "cross-env EFF_NO_LINK_RULES=true eslint . --format node_modules/eslint-friendly-formatter",
|
||||
"lint-docs": "prettylint {.,docs,website,website/blog}/*.md",
|
||||
"build": "node ./scripts/build/build.js",
|
||||
"build-docs": "node ./scripts/build/build-docs.js",
|
||||
"build-docs": "node ./scripts/old-build/build-docs.js",
|
||||
"check-deps": "node ./scripts/check-deps.js"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,2 @@
|
|||
overrides:
|
||||
- files: "rollup.*.config.js"
|
||||
parserOptions:
|
||||
sourceType: module
|
||||
parserOptions:
|
||||
ecmaVersion: 2017
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
"use strict";
|
||||
|
||||
//
|
||||
// BEFORE:
|
||||
// $$$r("path/to/file")
|
||||
//
|
||||
// AFTER:
|
||||
// require("./file")
|
||||
//
|
||||
|
||||
module.exports = function(babel) {
|
||||
const t = babel.types;
|
||||
return {
|
||||
visitor: {
|
||||
CallExpression: function(path) {
|
||||
const node = path.node;
|
||||
if (
|
||||
path.get("callee").isIdentifier({ name: "$$$r" }) &&
|
||||
node.arguments.length === 1 &&
|
||||
path.get("arguments.0").isStringLiteral()
|
||||
) {
|
||||
const value = node.arguments[0].value;
|
||||
const parts = value.split("/");
|
||||
path.replaceWith(
|
||||
t.callExpression(t.identifier("require"), [
|
||||
t.stringLiteral(`./${parts[parts.length - 1]}`)
|
||||
])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
|
@ -1,73 +0,0 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
"use strict";
|
||||
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const shell = require("shelljs");
|
||||
const parsers = require("./parsers");
|
||||
|
||||
const rootDir = path.join(__dirname, "..", "..");
|
||||
const docs = path.join(rootDir, "website/static/lib");
|
||||
|
||||
const stripLanguageDirectory = parserPath => parserPath.replace(/.*\//, "");
|
||||
|
||||
function pipe(string) {
|
||||
return new shell.ShellString(string);
|
||||
}
|
||||
|
||||
const isPullRequest = process.env.PULL_REQUEST === "true";
|
||||
const prettierPath = isPullRequest ? "dist" : "node_modules/prettier";
|
||||
|
||||
const parserPaths = parsers.map(stripLanguageDirectory);
|
||||
|
||||
// --- Build prettier for PR ---
|
||||
|
||||
if (isPullRequest) {
|
||||
const pkg = require("../../package.json");
|
||||
pkg.version = `999.999.999-pr.${process.env.REVIEW_ID}`;
|
||||
pipe(JSON.stringify(pkg, null, 2)).to("package.json");
|
||||
shell.exec("node scripts/build/build.js");
|
||||
}
|
||||
|
||||
// --- Docs ---
|
||||
|
||||
shell.mkdir("-p", docs);
|
||||
|
||||
shell.echo("Bundling docs index...");
|
||||
shell.cp(`${prettierPath}/index.js`, `${docs}/index.js`);
|
||||
shell.exec(
|
||||
`node_modules/babel-cli/bin/babel.js ${docs}/index.js --out-file ${docs}/index.js --presets=es2015`
|
||||
);
|
||||
|
||||
// wrap content with IIFE to avoid `assign to readonly` error on Safari
|
||||
(function(filename) {
|
||||
const content = fs.readFileSync(filename, "utf8");
|
||||
const wrapped = `"use strict";(function(){${content}}());`;
|
||||
fs.writeFileSync(filename, wrapped);
|
||||
})(`${docs}/index.js`);
|
||||
|
||||
shell.exec(
|
||||
`rollup -c scripts/build/rollup.docs.config.js --environment filepath:parser-babylon.js -i ${prettierPath}/parser-babylon.js`
|
||||
);
|
||||
shell.exec(
|
||||
`node_modules/babel-cli/bin/babel.js ${docs}/parser-babylon.js --out-file ${docs}/parser-babylon.js --presets=es2015`
|
||||
);
|
||||
|
||||
for (const parser of parserPaths) {
|
||||
if (parser.endsWith("babylon")) {
|
||||
continue;
|
||||
}
|
||||
shell.exec(
|
||||
`rollup -c scripts/build/rollup.docs.config.js --environment filepath:${parser}.js -i ${prettierPath}/${parser}.js`
|
||||
);
|
||||
}
|
||||
|
||||
// --- Site ---
|
||||
shell.cd("website");
|
||||
shell.echo("Building website...");
|
||||
shell.exec("yarn install");
|
||||
|
||||
shell.exec("yarn build");
|
||||
|
||||
shell.echo();
|
|
@ -1,108 +1,223 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
"use strict";
|
||||
|
||||
const path = require("path");
|
||||
const pkg = require("../../package.json");
|
||||
const formatMarkdown = require("../../website/playground/markdown");
|
||||
const parsers = require("./parsers");
|
||||
const shell = require("shelljs");
|
||||
const { rollup } = require("rollup");
|
||||
const webpack = require("webpack");
|
||||
const resolve = require("rollup-plugin-node-resolve");
|
||||
const commonjs = require("rollup-plugin-commonjs");
|
||||
const nodeGlobals = require("rollup-plugin-node-globals");
|
||||
const json = require("rollup-plugin-json");
|
||||
const replace = require("rollup-plugin-replace");
|
||||
const uglify = require("rollup-plugin-uglify");
|
||||
const babel = require("rollup-plugin-babel");
|
||||
const nativeShims = require("./rollup-plugins/native-shims");
|
||||
const executable = require("./rollup-plugins/executable");
|
||||
|
||||
const rootDir = path.join(__dirname, "..", "..");
|
||||
const Bundles = require("./bundles");
|
||||
const util = require("./util");
|
||||
|
||||
process.env.PATH += path.delimiter + path.join(rootDir, "node_modules", ".bin");
|
||||
const EXTERNALS = [
|
||||
"assert",
|
||||
"buffer",
|
||||
"constants",
|
||||
"crypto",
|
||||
"events",
|
||||
"fs",
|
||||
"module",
|
||||
"os",
|
||||
"path",
|
||||
"stream",
|
||||
"url",
|
||||
"util",
|
||||
"readline",
|
||||
|
||||
function pipe(string) {
|
||||
return new shell.ShellString(string);
|
||||
}
|
||||
// See comment in jest.config.js
|
||||
"graceful-fs"
|
||||
];
|
||||
|
||||
shell.set("-e");
|
||||
shell.cd(rootDir);
|
||||
|
||||
shell.rm("-Rf", "dist/");
|
||||
|
||||
// --- Lib ---
|
||||
|
||||
shell.exec("rollup -c scripts/build/rollup.index.config.js");
|
||||
|
||||
shell.exec("rollup -c scripts/build/rollup.bin.config.js");
|
||||
shell.chmod("+x", "./dist/bin-prettier.js");
|
||||
|
||||
shell.exec("rollup -c scripts/build/rollup.third-party.config.js");
|
||||
|
||||
for (const parser of parsers) {
|
||||
if (parser.endsWith("postcss")) {
|
||||
continue;
|
||||
function getBabelConfig(bundle) {
|
||||
if (bundle.type !== "core" && !bundle.transpile) {
|
||||
return;
|
||||
}
|
||||
shell.exec(
|
||||
`rollup -c scripts/build/rollup.parser.config.js --environment parser:${parser}`
|
||||
);
|
||||
if (parser.endsWith("glimmer")) {
|
||||
shell.exec(
|
||||
`node_modules/babel-cli/bin/babel.js dist/parser-glimmer.js --out-file dist/parser-glimmer.js --presets=es2015`
|
||||
|
||||
const config = {
|
||||
babelrc: false,
|
||||
plugins: []
|
||||
};
|
||||
if (bundle.type === "core") {
|
||||
config.plugins.push(
|
||||
require.resolve("./babel-plugins/transform-custom-require")
|
||||
);
|
||||
}
|
||||
if (bundle.transpile) {
|
||||
const targets = { node: 4 };
|
||||
if (bundle.target === "universal") {
|
||||
// From https://jamie.build/last-2-versions
|
||||
targets.browsers = [">0.25%", "not ie 11", "not op_mini all"];
|
||||
}
|
||||
config.presets = [
|
||||
[require.resolve("@babel/preset-env"), { targets, modules: false }]
|
||||
];
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
shell.echo("\nsrc/language-css/parser-postcss.js → dist/parser-postcss.js");
|
||||
// PostCSS has dependency cycles and won't work correctly with rollup :(
|
||||
shell.exec(
|
||||
"webpack --hide-modules src/language-css/parser-postcss.js dist/parser-postcss.js"
|
||||
);
|
||||
// Prepend module.exports =
|
||||
const content = shell.cat("dist/parser-postcss.js").stdout;
|
||||
pipe(`module.exports = ${content}`).to("dist/parser-postcss.js");
|
||||
function getRollupConfig(bundle) {
|
||||
const relative = fp => `./${path.basename(fp).replace(/\.js$/, "")}`;
|
||||
const paths = (bundle.external || []).reduce(
|
||||
(paths, filepath) =>
|
||||
Object.assign(paths, { [filepath]: relative(filepath) }),
|
||||
{ "graceful-fs": "fs" }
|
||||
);
|
||||
|
||||
shell.echo();
|
||||
const config = {
|
||||
entry: bundle.input,
|
||||
paths,
|
||||
|
||||
// --- Misc ---
|
||||
onwarn(warning) {
|
||||
if (
|
||||
// We use `eval("require")` to enable dynamic requires in the
|
||||
// custom parser API
|
||||
warning.code === "EVAL" ||
|
||||
(warning.code === "CIRCULAR_DEPENDENCY" &&
|
||||
warning.importer.startsWith("node_modules"))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
shell.echo("Remove eval");
|
||||
shell.sed(
|
||||
"-i",
|
||||
/eval\("require"\)/,
|
||||
"require",
|
||||
"dist/index.js",
|
||||
"dist/bin-prettier.js"
|
||||
);
|
||||
// web bundle can't have external requires
|
||||
if (
|
||||
warning.code === "UNRESOLVED_IMPORT" &&
|
||||
bundle.target === "universal"
|
||||
) {
|
||||
throw new Error(
|
||||
`Unresolved dependency in universal bundle: ${warning.source}`
|
||||
);
|
||||
}
|
||||
|
||||
shell.echo("Update ISSUE_TEMPLATE.md");
|
||||
const issueTemplate = shell.cat(".github/ISSUE_TEMPLATE.md").stdout;
|
||||
const newIssueTemplate = issueTemplate.replace(
|
||||
/-->[^]*$/,
|
||||
"-->\n\n" +
|
||||
formatMarkdown(
|
||||
"// code snippet",
|
||||
"// code snippet",
|
||||
"",
|
||||
pkg.version,
|
||||
"https://prettier.io/playground/#.....",
|
||||
{ parser: "babylon" },
|
||||
[["# Options (if any):", true], ["--single-quote", true]],
|
||||
true
|
||||
)
|
||||
);
|
||||
pipe(newIssueTemplate).to(".github/ISSUE_TEMPLATE.md");
|
||||
console.warn(warning);
|
||||
}
|
||||
};
|
||||
|
||||
shell.echo("Copy package.json");
|
||||
const pkgWithoutDependencies = Object.assign({}, pkg);
|
||||
pkgWithoutDependencies.bin = "./bin-prettier.js";
|
||||
delete pkgWithoutDependencies.dependencies;
|
||||
pkgWithoutDependencies.scripts = {
|
||||
prepublishOnly:
|
||||
"node -e \"assert.equal(require('.').version, require('..').version)\""
|
||||
};
|
||||
pkgWithoutDependencies.files = ["*.js"];
|
||||
pipe(JSON.stringify(pkgWithoutDependencies, null, 2)).to("dist/package.json");
|
||||
const replaceStrings = {
|
||||
"proces.env.NODE_ENV": JSON.stringify("production")
|
||||
};
|
||||
if (bundle.target === "universal") {
|
||||
// We can't reference `process` in UMD bundles and this is
|
||||
// an undocumented "feature"
|
||||
replaceStrings["process.env.PRETTIER_DEBUG"] = "global.PRETTIER_DEBUG";
|
||||
}
|
||||
Object.assign(replaceStrings, bundle.replace);
|
||||
|
||||
shell.echo("Copy README.md");
|
||||
shell.cp("README.md", "dist/README.md");
|
||||
const babelConfig = getBabelConfig(bundle);
|
||||
|
||||
shell.echo("Done!");
|
||||
shell.echo();
|
||||
shell.echo("How to test against dist:");
|
||||
shell.echo(" 1) yarn test:dist");
|
||||
shell.echo();
|
||||
shell.echo("How to publish:");
|
||||
shell.echo(" 1) IMPORTANT!!! Go to dist/");
|
||||
shell.echo(" 2) npm publish");
|
||||
config.plugins = [
|
||||
replace(replaceStrings),
|
||||
executable(),
|
||||
json(),
|
||||
bundle.target === "universal" &&
|
||||
nativeShims(path.resolve(__dirname, "shims")),
|
||||
resolve({
|
||||
extensions: [".js", ".json"],
|
||||
preferBuiltins: bundle.target === "node"
|
||||
}),
|
||||
commonjs(bundle.commonjs || {}),
|
||||
bundle.target === "universal" && nodeGlobals(),
|
||||
babelConfig && babel(babelConfig),
|
||||
bundle.type === "plugin" && uglify()
|
||||
].filter(Boolean);
|
||||
|
||||
if (bundle.target === "node") {
|
||||
config.external = EXTERNALS.concat(bundle.external);
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
function getRollupOutputOptions(bundle) {
|
||||
const options = {
|
||||
dest: `dist/${Bundles.getFileOutput(bundle)}`,
|
||||
useStrict: typeof bundle.strict === "undefined" ? true : bundle.strict
|
||||
};
|
||||
if (bundle.target === "node") {
|
||||
options.format = "cjs";
|
||||
} else if (bundle.target === "universal") {
|
||||
options.format = "umd";
|
||||
options.moduleName =
|
||||
bundle.type === "plugin" ? `prettierPlugins.${bundle.name}` : bundle.name;
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
function getWebpackConfig(bundle) {
|
||||
if (bundle.target === "node") {
|
||||
throw new Error("Unsupported webpack bundle for node");
|
||||
}
|
||||
|
||||
const root = path.resolve(__dirname, "..", "..");
|
||||
return {
|
||||
entry: path.resolve(root, bundle.input),
|
||||
output: {
|
||||
path: path.resolve(root, "dist"),
|
||||
filename: Bundles.getFileOutput(bundle),
|
||||
library:
|
||||
bundle.type === "plugin"
|
||||
? ["prettierPlugins", bundle.name]
|
||||
: bundle.name,
|
||||
libraryTarget: "umd"
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function asyncWebpack(config) {
|
||||
return new Promise((resolve, reject) => {
|
||||
webpack(config, err => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function createBundle(bundle) {
|
||||
const output = Bundles.getFileOutput(bundle);
|
||||
console.log(`BUILDING ${output}`);
|
||||
|
||||
if (bundle.bundler === "webpack") {
|
||||
await asyncWebpack(getWebpackConfig(bundle));
|
||||
} else {
|
||||
try {
|
||||
const result = await rollup(getRollupConfig(bundle));
|
||||
await result.write(getRollupOutputOptions(bundle));
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function createPackageJson() {
|
||||
const pkg = await util.readJson("package.json");
|
||||
pkg.bin = "./bin-prettier.js";
|
||||
delete pkg.dependencies;
|
||||
delete pkg.devDependencies;
|
||||
pkg.scripts = {
|
||||
prepublishOnly:
|
||||
'node -e "assert.equal(require(".").version, require("..").version)"'
|
||||
};
|
||||
await util.writeJson("dist/package.json", pkg);
|
||||
}
|
||||
|
||||
async function run() {
|
||||
await util.asyncRimRaf("dist");
|
||||
|
||||
for (const bundle of Bundles.bundles) {
|
||||
await createBundle(bundle, "node");
|
||||
}
|
||||
|
||||
await createPackageJson();
|
||||
}
|
||||
|
||||
run();
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
"use strict";
|
||||
|
||||
const path = require("path");
|
||||
|
||||
/**
|
||||
* @typedef {Object} Bundle
|
||||
* @property {string} input - input of the bundle
|
||||
* @property {string?} output - path of the output file in the `dist/` folder
|
||||
* @property {string?} name - name for the UMD bundle (for plugins, it'll be `prettierPlugins.${name}`)
|
||||
* @property {'node' | 'universal'} target - should generate a CJS only for node or UMD bundle
|
||||
* @property {'core' | 'plugin'} type - it's a plugin bundle or core part of prettier
|
||||
* @property {'rollup' | 'webpack'} [bundler='rollup'] - define which bundler to use
|
||||
* @property {CommonJSConfig} [commonjs={}] - options for `rollup-plugin-commonjs`
|
||||
* @property {string[]} external - array of paths that should not be included in the final bundle
|
||||
* @property {Object.<string, string>} replace - map of strings to replace when processing the bundle
|
||||
* @property {boolean} [transpile=false] - wether to transpile the bundle to ES2015
|
||||
|
||||
* @typedef {Object} CommonJSConfig
|
||||
* @property {Object} namedExports - for cases where rollup can't infer what's exported
|
||||
* @property {string[]} ignore - paths of CJS modules to ignore
|
||||
*/
|
||||
|
||||
/** @type {Bundle[]} */
|
||||
const parsers = [
|
||||
{
|
||||
input: "src/language-js/parser-babylon.js",
|
||||
target: "universal"
|
||||
},
|
||||
{
|
||||
input: "src/language-js/parser-flow.js",
|
||||
target: "universal",
|
||||
strict: false
|
||||
},
|
||||
{
|
||||
input: "src/language-js/parser-typescript.js",
|
||||
target: "universal"
|
||||
},
|
||||
{
|
||||
input: "src/language-css/parser-postcss.js",
|
||||
target: "universal",
|
||||
// postcss has dependency cycles that don't work with rollup
|
||||
bundler: "webpack"
|
||||
},
|
||||
{
|
||||
input: "src/language-graphql/parser-graphql.js",
|
||||
target: "universal"
|
||||
},
|
||||
{
|
||||
input: "src/language-markdown/parser-markdown.js",
|
||||
target: "universal"
|
||||
},
|
||||
{
|
||||
input: "src/language-vue/parser-vue.js",
|
||||
target: "universal"
|
||||
},
|
||||
{
|
||||
input: "src/language-handlebars/parser-glimmer.js",
|
||||
target: "node",
|
||||
commonjs: {
|
||||
namedExports: {
|
||||
"node_modules/handlebars/lib/index.js": ["parse"],
|
||||
"node_modules/@glimmer/syntax/dist/modules/es2017/index.js": "default"
|
||||
},
|
||||
ignore: ["source-map"]
|
||||
},
|
||||
transpile: true
|
||||
},
|
||||
{
|
||||
input: "src/language-html/parser-parse5.js",
|
||||
target: "node"
|
||||
}
|
||||
].map(parser => {
|
||||
const name = getFileOutput(parser)
|
||||
.replace(/\.js$/, "")
|
||||
.split("-")[1];
|
||||
return Object.assign(parser, { type: "plugin", name });
|
||||
});
|
||||
|
||||
/** @type {Bundle[]} */
|
||||
const bundles = [
|
||||
{
|
||||
input: "index.js",
|
||||
type: "core",
|
||||
target: "node",
|
||||
external: [path.resolve("src/common/third-party.js")]
|
||||
},
|
||||
{
|
||||
input: "standalone.js",
|
||||
name: "prettier",
|
||||
type: "core",
|
||||
target: "universal"
|
||||
},
|
||||
{
|
||||
input: "bin/prettier.js",
|
||||
type: "core",
|
||||
output: "bin-prettier.js",
|
||||
target: "node",
|
||||
external: [path.resolve("src/common/third-party.js")]
|
||||
},
|
||||
{
|
||||
input: "src/common/third-party.js",
|
||||
type: "core",
|
||||
target: "node",
|
||||
replace: {
|
||||
// The require-from-string module (a dependency of cosmiconfig) assumes
|
||||
// that `module.parent` exists, but it only does for `require`:ed modules.
|
||||
// Usually, require-from-string is _always_ `require`:ed, but when bundled
|
||||
// with rollup the module is turned into a plain function located directly
|
||||
// in index.js so `module.parent` does not exist. Defaulting to `module`
|
||||
// instead seems to work.
|
||||
"module.parent": "(module.parent || module)"
|
||||
}
|
||||
}
|
||||
].concat(parsers);
|
||||
|
||||
function getFileOutput(bundle) {
|
||||
return bundle.output || path.basename(bundle.input);
|
||||
}
|
||||
|
||||
module.exports = { bundles, getFileOutput };
|
|
@ -0,0 +1,43 @@
|
|||
"use strict";
|
||||
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
|
||||
module.exports = function() {
|
||||
let banner;
|
||||
let entry;
|
||||
|
||||
return {
|
||||
options(options) {
|
||||
entry = path.resolve(options.entry);
|
||||
return options;
|
||||
},
|
||||
|
||||
load(id) {
|
||||
if (id !== entry) {
|
||||
return;
|
||||
}
|
||||
const source = fs.readFileSync(id, "utf-8");
|
||||
const match = source.match(/^\s*(#!.*)/);
|
||||
if (match) {
|
||||
banner = match[1];
|
||||
return (
|
||||
source.slice(0, match.index) +
|
||||
source.slice(match.index + banner.length)
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
transformBundle(code) {
|
||||
if (banner) {
|
||||
return { code: banner + "\n" + code };
|
||||
}
|
||||
},
|
||||
|
||||
onwrite(bundle) {
|
||||
if (banner) {
|
||||
fs.chmodSync(bundle.dest, 0o755 & ~process.umask());
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
|
@ -0,0 +1,30 @@
|
|||
"use strict";
|
||||
|
||||
const builtins = require("builtin-modules");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const tempy = require("tempy");
|
||||
|
||||
module.exports = function(dir) {
|
||||
return {
|
||||
resolveId(importee, importer) {
|
||||
if (!importee || !importer || /\0/.test(importee)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!~builtins.indexOf(importee)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const newPath = path.resolve(dir, `${importee}.js`);
|
||||
if (fs.existsSync(newPath)) {
|
||||
return newPath;
|
||||
}
|
||||
|
||||
// This helps debugging when a stub in the module is needed
|
||||
const fallback = tempy.file({ name: `${importee}.js` });
|
||||
fs.writeFileSync(fallback, "module.exports = {};");
|
||||
return fallback;
|
||||
}
|
||||
};
|
||||
};
|
|
@ -1,39 +0,0 @@
|
|||
import baseConfig from "./rollup.base.config.js";
|
||||
import resolve from "rollup-plugin-node-resolve";
|
||||
import commonjs from "rollup-plugin-commonjs";
|
||||
import json from "rollup-plugin-json";
|
||||
import replace from "rollup-plugin-replace";
|
||||
import * as path from "path";
|
||||
|
||||
export default Object.assign(baseConfig, {
|
||||
entry: "bin/prettier.js",
|
||||
dest: "dist/bin-prettier.js",
|
||||
format: "cjs",
|
||||
banner: "#!/usr/bin/env node",
|
||||
plugins: [
|
||||
replace({
|
||||
"#!/usr/bin/env node": "",
|
||||
// See comment in jest.config.js
|
||||
"require('graceful-fs')": "require('fs')"
|
||||
}),
|
||||
json(),
|
||||
resolve({
|
||||
preferBuiltins: true,
|
||||
extensions: [".js", ".json"]
|
||||
}),
|
||||
commonjs()
|
||||
],
|
||||
external: [
|
||||
"fs",
|
||||
"readline",
|
||||
"path",
|
||||
"module",
|
||||
"assert",
|
||||
"util",
|
||||
"events",
|
||||
path.resolve("src/common/third-party.js")
|
||||
],
|
||||
paths: {
|
||||
[path.resolve("src/common/third-party.js")]: "./third-party"
|
||||
}
|
||||
});
|
|
@ -1,35 +0,0 @@
|
|||
import baseConfig from "./rollup.base.config.js";
|
||||
import resolve from "rollup-plugin-node-resolve";
|
||||
import commonjs from "rollup-plugin-commonjs";
|
||||
import json from "rollup-plugin-json";
|
||||
import replace from "rollup-plugin-replace";
|
||||
import * as path from "path";
|
||||
|
||||
const external = ["assert"];
|
||||
|
||||
if (process.env.BUILD_TARGET !== "website") {
|
||||
external.push(path.resolve("src/common/third-party.js"));
|
||||
}
|
||||
|
||||
export default Object.assign(baseConfig, {
|
||||
entry: "index.js",
|
||||
dest: "dist/index.js",
|
||||
format: "cjs",
|
||||
plugins: [
|
||||
replace({
|
||||
"process.env.NODE_ENV": JSON.stringify("production"),
|
||||
// See comment in jest.config.js
|
||||
"require('graceful-fs')": "require('fs')"
|
||||
}),
|
||||
json(),
|
||||
resolve({
|
||||
preferBuiltins: true,
|
||||
extensions: [".js", ".json"]
|
||||
}),
|
||||
commonjs()
|
||||
],
|
||||
external,
|
||||
paths: {
|
||||
[path.resolve("src/common/third-party.js")]: "./third-party"
|
||||
}
|
||||
});
|
|
@ -1,63 +0,0 @@
|
|||
import baseConfig from "./rollup.base.config.js";
|
||||
import resolve from "rollup-plugin-node-resolve";
|
||||
import commonjs from "rollup-plugin-commonjs";
|
||||
import json from "rollup-plugin-json";
|
||||
import replace from "rollup-plugin-replace";
|
||||
import uglify from "uglify-es";
|
||||
import path from "path";
|
||||
|
||||
const parser = process.env.parser;
|
||||
|
||||
export default Object.assign(baseConfig, {
|
||||
entry: "src/" + parser + ".js",
|
||||
dest: "dist/" + path.basename(parser) + ".js",
|
||||
format: "cjs",
|
||||
plugins: [
|
||||
parser.endsWith("typescript")
|
||||
? replace({
|
||||
"exports.Syntax =": "1,",
|
||||
include: "node_modules/typescript-eslint-parser/parser.js"
|
||||
})
|
||||
: {},
|
||||
json(),
|
||||
resolve({ preferBuiltins: true }),
|
||||
commonjs(
|
||||
parser.endsWith("glimmer")
|
||||
? {
|
||||
namedExports: {
|
||||
"node_modules/handlebars/lib/index.js": ["parse"],
|
||||
"node_modules/simple-html-tokenizer/dist/simple-html-tokenizer.js": [
|
||||
"EntityParser",
|
||||
"HTML5NamedCharRefs",
|
||||
"EventedTokenizer"
|
||||
],
|
||||
"node_modules/@glimmer/syntax/dist/modules/index.js": "default",
|
||||
"node_modules/@glimmer/syntax/dist/modules/es2017/index.js":
|
||||
"default"
|
||||
},
|
||||
ignore: ["source-map"]
|
||||
}
|
||||
: {}
|
||||
),
|
||||
{
|
||||
transformBundle(code) {
|
||||
const result = uglify.minify(code, {});
|
||||
if (result.error) {
|
||||
throw result.error;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
],
|
||||
external: [
|
||||
"fs",
|
||||
"buffer",
|
||||
"path",
|
||||
"module",
|
||||
"assert",
|
||||
"util",
|
||||
"os",
|
||||
"crypto"
|
||||
],
|
||||
useStrict: !parser.endsWith("flow")
|
||||
});
|
|
@ -1,26 +0,0 @@
|
|||
import baseConfig from "./rollup.base.config.js";
|
||||
import resolve from "rollup-plugin-node-resolve";
|
||||
import commonjs from "rollup-plugin-commonjs";
|
||||
import json from "rollup-plugin-json";
|
||||
import replace from "rollup-plugin-replace";
|
||||
|
||||
export default Object.assign(baseConfig, {
|
||||
entry: "src/common/third-party.js",
|
||||
dest: "dist/third-party.js",
|
||||
format: "cjs",
|
||||
plugins: [
|
||||
replace({
|
||||
// The require-from-string module (a dependency of cosmiconfig) assumes
|
||||
// that `module.parent` exists, but it only does for `require`:ed modules.
|
||||
// Usually, require-from-string is _always_ `require`:ed, but when bundled
|
||||
// with rollup the module is turned into a plain function located directly
|
||||
// in index.js so `module.parent` does not exist. Defaulting to `module`
|
||||
// instead seems to work.
|
||||
"module.parent": "(module.parent || module)"
|
||||
}),
|
||||
json(),
|
||||
resolve({ preferBuiltins: true }),
|
||||
commonjs()
|
||||
],
|
||||
external: ["assert"]
|
||||
});
|
|
@ -0,0 +1,4 @@
|
|||
module.exports = {
|
||||
ok() {},
|
||||
strictEqual() {}
|
||||
};
|
|
@ -0,0 +1,24 @@
|
|||
"use strict";
|
||||
|
||||
const fs = require("fs");
|
||||
const rimraf = require("rimraf");
|
||||
const promisify = require("util").promisify;
|
||||
|
||||
const readFile = promisify(fs.readFile);
|
||||
const writeFile = promisify(fs.writeFile);
|
||||
|
||||
async function readJson(file) {
|
||||
const data = await readFile(file);
|
||||
return JSON.parse(data);
|
||||
}
|
||||
|
||||
function writeJson(file, content) {
|
||||
content = JSON.stringify(content, null, 2);
|
||||
return writeFile(file, content);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
asyncRimRaf: promisify(rimraf),
|
||||
readJson,
|
||||
writeJson
|
||||
};
|
|
@ -0,0 +1,4 @@
|
|||
overrides:
|
||||
files: rollup.*.config.js
|
||||
parserOptions:
|
||||
sourceType: module
|
|
@ -0,0 +1,77 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
"use strict";
|
||||
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const shell = require("shelljs");
|
||||
const parsers = require("./parsers");
|
||||
|
||||
const rootDir = path.join(__dirname, "..", "..");
|
||||
const staticDir = path.join(rootDir, "website/static");
|
||||
const docs = path.join(rootDir, "website/static/lib");
|
||||
|
||||
const stripLanguageDirectory = parserPath => parserPath.replace(/.*\//, "");
|
||||
|
||||
function pipe(string) {
|
||||
return new shell.ShellString(string);
|
||||
}
|
||||
|
||||
const isPullRequest = process.env.PULL_REQUEST === "true";
|
||||
const prettierPath = isPullRequest ? "dist" : "node_modules/prettier";
|
||||
|
||||
const parserPaths = parsers.map(stripLanguageDirectory);
|
||||
|
||||
// --- Build prettier for PR ---
|
||||
|
||||
shell.mkdir("-p", docs);
|
||||
|
||||
if (isPullRequest) {
|
||||
const pkg = require("../../package.json");
|
||||
pkg.version = `999.999.999-pr.${process.env.REVIEW_ID}`;
|
||||
pipe(JSON.stringify(pkg, null, 2)).to("package.json");
|
||||
shell.exec("node scripts/build/build.js");
|
||||
shell.exec(`cp dist/standalone.js ${docs}/`);
|
||||
shell.exec(`cp dist/parser-*.js ${docs}/`);
|
||||
shell.exec(`cp ${staticDir}/new-worker.js ${staticDir}/worker.js`);
|
||||
}
|
||||
|
||||
// --- Docs ---
|
||||
else {
|
||||
shell.echo("Bundling docs index...");
|
||||
shell.cp(`${prettierPath}/index.js`, `${docs}/index.js`);
|
||||
shell.exec(
|
||||
`node_modules/@babel/cli/bin/babel.js ${docs}/index.js --out-file ${docs}/index.js --presets=@babel/preset-env`
|
||||
);
|
||||
|
||||
// wrap content with IIFE to avoid `assign to readonly` error on Safari
|
||||
(function(filename) {
|
||||
const content = fs.readFileSync(filename, "utf8");
|
||||
const wrapped = `"use strict";(function(){${content}}());`;
|
||||
fs.writeFileSync(filename, wrapped);
|
||||
})(`${docs}/index.js`);
|
||||
|
||||
shell.exec(
|
||||
`rollup -c scripts/old-build/rollup.docs.config.js --environment filepath:parser-babylon.js -i ${prettierPath}/parser-babylon.js`
|
||||
);
|
||||
shell.exec(
|
||||
`node_modules/@babel/cli/bin/babel.js ${docs}/parser-babylon.js --out-file ${docs}/parser-babylon.js --presets=@babel/preset-env`
|
||||
);
|
||||
|
||||
for (const parser of parserPaths) {
|
||||
if (parser.endsWith("babylon")) {
|
||||
continue;
|
||||
}
|
||||
shell.exec(
|
||||
`rollup -c scripts/old-build/rollup.docs.config.js --environment filepath:${parser}.js -i ${prettierPath}/${parser}.js`
|
||||
);
|
||||
}
|
||||
}
|
||||
// --- Site ---
|
||||
shell.cd("website");
|
||||
shell.echo("Building website...");
|
||||
shell.exec("yarn install");
|
||||
|
||||
shell.exec("yarn build");
|
||||
|
||||
shell.echo();
|
|
@ -0,0 +1,113 @@
|
|||
"use strict";
|
||||
|
||||
// We need to do this to prevent rollup from hoisting the requires. A babel
|
||||
// plugin will look for `$$$r()` and transform to `require()` in the bundle,
|
||||
// and rewrite the paths to require from the top-level.
|
||||
const $$$r = require;
|
||||
|
||||
// We need to list the parsers and getters so we can load them only when necessary.
|
||||
module.exports = [
|
||||
// JS
|
||||
require("../language-js"),
|
||||
{
|
||||
parsers: {
|
||||
// JS - Babylon
|
||||
get babylon() {
|
||||
return $$$r("../language-js/parser-babylon").parsers.babylon;
|
||||
},
|
||||
get json() {
|
||||
return $$$r("../language-js/parser-babylon").parsers.json;
|
||||
},
|
||||
get json5() {
|
||||
return $$$r("../language-js/parser-babylon").parsers.json5;
|
||||
},
|
||||
get "json-stringify"() {
|
||||
return $$$r("../language-js/parser-babylon").parsers["json-stringify"];
|
||||
},
|
||||
// JS - Flow
|
||||
get flow() {
|
||||
return $$$r("../language-js/parser-flow").parsers.flow;
|
||||
},
|
||||
// JS - TypeScript
|
||||
get typescript() {
|
||||
return $$$r("../language-js/parser-typescript").parsers.typescript;
|
||||
},
|
||||
get "typescript-eslint"() {
|
||||
return $$$r("../language-js/parser-typescript").parsers[
|
||||
"typescript-eslint"
|
||||
];
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// CSS
|
||||
require("../language-css"),
|
||||
{
|
||||
parsers: {
|
||||
// TODO: switch these to just `postcss` and use `language` instead.
|
||||
get css() {
|
||||
return $$$r("../language-css/parser-postcss").parsers.css;
|
||||
},
|
||||
get less() {
|
||||
return $$$r("../language-css/parser-postcss").parsers.css;
|
||||
},
|
||||
get scss() {
|
||||
return $$$r("../language-css/parser-postcss").parsers.css;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Handlebars
|
||||
require("../language-handlebars"),
|
||||
{
|
||||
parsers: {
|
||||
get glimmer() {
|
||||
return $$$r("../language-handlebars/parser-glimmer").parsers.glimmer;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// GraphQL
|
||||
require("../language-graphql"),
|
||||
{
|
||||
parsers: {
|
||||
get graphql() {
|
||||
return $$$r("../language-graphql/parser-graphql").parsers.graphql;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Markdown
|
||||
require("../language-markdown"),
|
||||
{
|
||||
parsers: {
|
||||
get remark() {
|
||||
return $$$r("../language-markdown/parser-markdown").parsers.remark;
|
||||
},
|
||||
// TODO: Delete this in 2.0
|
||||
get markdown() {
|
||||
return $$$r("../language-markdown/parser-markdown").parsers.remark;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// HTML
|
||||
require("../language-html"),
|
||||
{
|
||||
parsers: {
|
||||
get parse5() {
|
||||
return $$$r("../language-html/parser-parse5").parsers.parse5;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Vue
|
||||
require("../language-vue"),
|
||||
{
|
||||
parsers: {
|
||||
get vue() {
|
||||
return $$$r("../language-vue/parser-vue").parsers.vue;
|
||||
}
|
||||
}
|
||||
}
|
||||
];
|
|
@ -6,6 +6,7 @@ const globby = require("globby");
|
|||
const path = require("path");
|
||||
const resolve = require("resolve");
|
||||
const thirdParty = require("./third-party");
|
||||
const internalPlugins = require("./internal-plugins");
|
||||
|
||||
function loadPlugins(plugins, pluginSearchDirs) {
|
||||
if (!plugins) {
|
||||
|
@ -26,16 +27,6 @@ function loadPlugins(plugins, pluginSearchDirs) {
|
|||
}
|
||||
}
|
||||
|
||||
const internalPlugins = [
|
||||
require("../language-js"),
|
||||
require("../language-css"),
|
||||
require("../language-handlebars"),
|
||||
require("../language-graphql"),
|
||||
require("../language-markdown"),
|
||||
require("../language-html"),
|
||||
require("../language-vue")
|
||||
];
|
||||
|
||||
const externalManualLoadPluginInfos = plugins.map(pluginName => {
|
||||
let requirePath;
|
||||
try {
|
||||
|
|
|
@ -240,18 +240,6 @@ function hasSpaces(text, index, opts) {
|
|||
return idx !== index;
|
||||
}
|
||||
|
||||
// Super inefficient, needs to be cached.
|
||||
function lineColumnToIndex(lineColumn, text) {
|
||||
let index = 0;
|
||||
for (let i = 0; i < lineColumn.line - 1; ++i) {
|
||||
index = text.indexOf("\n", index) + 1;
|
||||
if (index === -1) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return index + lineColumn.column;
|
||||
}
|
||||
|
||||
function setLocStart(node, index) {
|
||||
if (node.range) {
|
||||
node.range[0] = index;
|
||||
|
@ -809,7 +797,6 @@ module.exports = {
|
|||
printNumber,
|
||||
hasIgnoreComment,
|
||||
hasNodeIgnoreComment,
|
||||
lineColumnToIndex,
|
||||
makeString,
|
||||
addLeadingComment,
|
||||
addDanglingComment,
|
||||
|
|
|
@ -2,10 +2,6 @@
|
|||
|
||||
const printer = require("./printer-postcss");
|
||||
const options = require("./options");
|
||||
const privateUtil = require("../common/util");
|
||||
|
||||
const lineColumnToIndex = privateUtil.lineColumnToIndex;
|
||||
const getLast = privateUtil.getLast;
|
||||
|
||||
// Based on:
|
||||
// https://github.com/github/linguist/blob/master/lib/linguist/languages.yml
|
||||
|
@ -52,36 +48,6 @@ const languages = [
|
|||
}
|
||||
];
|
||||
|
||||
const postcss = {
|
||||
get parse() {
|
||||
return eval("require")("./parser-postcss");
|
||||
},
|
||||
astFormat: "postcss",
|
||||
locEnd: function(node) {
|
||||
const endNode = node.nodes && getLast(node.nodes);
|
||||
if (endNode && node.source && !node.source.end) {
|
||||
node = endNode;
|
||||
}
|
||||
if (node.source) {
|
||||
return lineColumnToIndex(node.source.end, node.source.input.css);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
locStart: function(node) {
|
||||
if (node.source) {
|
||||
return lineColumnToIndex(node.source.start, node.source.input.css) - 1;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: switch these to just `postcss` and use `language` instead.
|
||||
const parsers = {
|
||||
css: postcss,
|
||||
less: postcss,
|
||||
scss: postcss
|
||||
};
|
||||
|
||||
const printers = {
|
||||
postcss: printer
|
||||
};
|
||||
|
@ -89,6 +55,5 @@ const printers = {
|
|||
module.exports = {
|
||||
languages,
|
||||
options,
|
||||
parsers,
|
||||
printers
|
||||
};
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
const createError = require("../common/parser-create-error");
|
||||
const parseFrontMatter = require("../utils/front-matter");
|
||||
const lineColumnToIndex = require("../utils/line-column-to-index");
|
||||
|
||||
// utils
|
||||
const utils = require("./utils");
|
||||
|
@ -539,4 +540,32 @@ function parse(text, parsers, opts) {
|
|||
}
|
||||
}
|
||||
|
||||
module.exports = parse;
|
||||
const parser = {
|
||||
parse,
|
||||
astFormat: "postcss",
|
||||
locStart(node) {
|
||||
if (node.source) {
|
||||
return lineColumnToIndex(node.source.start, node.source.input.css) - 1;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
locEnd(node) {
|
||||
const endNode = node.nodes && node.nodes[node.nodes.length - 1];
|
||||
if (endNode && node.source && !node.source.end) {
|
||||
node = endNode;
|
||||
}
|
||||
if (node.source) {
|
||||
return lineColumnToIndex(node.source.end, node.source.input.css);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
// Export as a plugin so we can reuse the same bundle for UMD loading
|
||||
module.exports = {
|
||||
parsers: {
|
||||
css: parser,
|
||||
less: parser,
|
||||
scss: parser
|
||||
}
|
||||
};
|
||||
|
|
|
@ -19,27 +19,6 @@ const languages = [
|
|||
}
|
||||
];
|
||||
|
||||
const parsers = {
|
||||
graphql: {
|
||||
get parse() {
|
||||
return eval("require")("./parser-graphql");
|
||||
},
|
||||
astFormat: "graphql",
|
||||
locStart: function(node) {
|
||||
if (typeof node.start === "number") {
|
||||
return node.start;
|
||||
}
|
||||
return node.loc && node.loc.start;
|
||||
},
|
||||
locEnd: function(node) {
|
||||
if (typeof node.end === "number") {
|
||||
return node.end;
|
||||
}
|
||||
return node.loc && node.loc.end;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const printers = {
|
||||
graphql: printer
|
||||
};
|
||||
|
@ -47,6 +26,5 @@ const printers = {
|
|||
module.exports = {
|
||||
languages,
|
||||
options,
|
||||
parsers,
|
||||
printers
|
||||
};
|
||||
|
|
|
@ -65,4 +65,23 @@ function parse(text /*, parsers, opts*/) {
|
|||
}
|
||||
}
|
||||
|
||||
module.exports = parse;
|
||||
module.exports = {
|
||||
parsers: {
|
||||
graphql: {
|
||||
parse,
|
||||
astFormat: "graphql",
|
||||
locStart(node) {
|
||||
if (typeof node.start === "number") {
|
||||
return node.start;
|
||||
}
|
||||
return node.loc && node.loc.start;
|
||||
},
|
||||
locEnd(node) {
|
||||
if (typeof node.end === "number") {
|
||||
return node.end;
|
||||
}
|
||||
return node.loc && node.loc.end;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -18,27 +18,11 @@ const languages = [
|
|||
}
|
||||
];
|
||||
|
||||
const parsers = {
|
||||
glimmer: {
|
||||
get parse() {
|
||||
return eval("require")("./parser-glimmer");
|
||||
},
|
||||
astFormat: "glimmer",
|
||||
locEnd: function(node) {
|
||||
return node.loc && node.loc.end;
|
||||
},
|
||||
locStart: function(node) {
|
||||
return node.loc && node.loc.start;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const printers = {
|
||||
glimmer: printer
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
languages,
|
||||
parsers,
|
||||
printers
|
||||
};
|
||||
|
|
|
@ -42,4 +42,18 @@ function parse(text) {
|
|||
}
|
||||
}
|
||||
}
|
||||
module.exports = parse;
|
||||
|
||||
module.exports = {
|
||||
parsers: {
|
||||
glimmer: {
|
||||
parse,
|
||||
astFormat: "glimmer",
|
||||
locStart(node) {
|
||||
return node.loc && node.loc.start;
|
||||
},
|
||||
locEnd(node) {
|
||||
return node.loc && node.loc.end;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -22,27 +22,11 @@ const languages = [
|
|||
}
|
||||
];
|
||||
|
||||
const parsers = {
|
||||
parse5: {
|
||||
get parse() {
|
||||
return eval("require")("./parser-parse5");
|
||||
},
|
||||
astFormat: "htmlparser2",
|
||||
locEnd: function(node) {
|
||||
return node.__location && node.__location.endOffset;
|
||||
},
|
||||
locStart: function(node) {
|
||||
return node.__location && node.__location.startOffset;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const printers = {
|
||||
htmlparser2: printer
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
languages,
|
||||
parsers,
|
||||
printers
|
||||
};
|
||||
|
|
|
@ -58,4 +58,17 @@ function convertAttribs(attribs) {
|
|||
});
|
||||
}
|
||||
|
||||
module.exports = parse;
|
||||
module.exports = {
|
||||
parsers: {
|
||||
parse5: {
|
||||
parse,
|
||||
astFormat: "htmlparser2",
|
||||
locStart(node) {
|
||||
return node.__location && node.__location.startOffset;
|
||||
},
|
||||
locEnd(node) {
|
||||
return node.__location && node.__location.endOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -2,68 +2,11 @@
|
|||
|
||||
const estreePrinter = require("./printer-estree");
|
||||
const estreeJsonPrinter = require("./printer-estree-json");
|
||||
const hasPragma = require("./pragma").hasPragma;
|
||||
const options = require("./options");
|
||||
const privateUtil = require("../common/util");
|
||||
|
||||
// Based on:
|
||||
// https://github.com/github/linguist/blob/master/lib/linguist/languages.yml
|
||||
|
||||
const locStart = function(node) {
|
||||
// Handle nodes with decorators. They should start at the first decorator
|
||||
if (
|
||||
node.declaration &&
|
||||
node.declaration.decorators &&
|
||||
node.declaration.decorators.length > 0
|
||||
) {
|
||||
return locStart(node.declaration.decorators[0]);
|
||||
}
|
||||
if (node.decorators && node.decorators.length > 0) {
|
||||
return locStart(node.decorators[0]);
|
||||
}
|
||||
|
||||
if (node.__location) {
|
||||
return node.__location.startOffset;
|
||||
}
|
||||
if (node.range) {
|
||||
return node.range[0];
|
||||
}
|
||||
if (typeof node.start === "number") {
|
||||
return node.start;
|
||||
}
|
||||
if (node.loc) {
|
||||
return node.loc.start;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
const locEnd = function(node) {
|
||||
const endNode = node.nodes && privateUtil.getLast(node.nodes);
|
||||
if (endNode && node.source && !node.source.end) {
|
||||
node = endNode;
|
||||
}
|
||||
|
||||
let loc;
|
||||
if (node.range) {
|
||||
loc = node.range[1];
|
||||
} else if (typeof node.end === "number") {
|
||||
loc = node.end;
|
||||
}
|
||||
|
||||
if (node.__location) {
|
||||
return node.__location.endOffset;
|
||||
}
|
||||
if (node.typeAnnotation) {
|
||||
return Math.max(loc, locEnd(node.typeAnnotation));
|
||||
}
|
||||
|
||||
if (node.loc && !loc) {
|
||||
return node.loc.end;
|
||||
}
|
||||
|
||||
return loc;
|
||||
};
|
||||
|
||||
const languages = [
|
||||
{
|
||||
name: "JavaScript",
|
||||
|
@ -179,56 +122,6 @@ const languages = [
|
|||
}
|
||||
];
|
||||
|
||||
const typescript = {
|
||||
get parse() {
|
||||
return eval("require")("./parser-typescript");
|
||||
},
|
||||
astFormat: "estree",
|
||||
hasPragma,
|
||||
locStart,
|
||||
locEnd
|
||||
};
|
||||
|
||||
const babylon = {
|
||||
get parse() {
|
||||
return eval("require")("./parser-babylon");
|
||||
},
|
||||
astFormat: "estree",
|
||||
hasPragma,
|
||||
locStart,
|
||||
locEnd
|
||||
};
|
||||
|
||||
const parsers = {
|
||||
babylon,
|
||||
json: Object.assign({}, babylon, {
|
||||
hasPragma() {
|
||||
return true;
|
||||
}
|
||||
}),
|
||||
json5: babylon,
|
||||
"json-stringify": {
|
||||
get parse() {
|
||||
return eval("require")("./parser-json-stringify");
|
||||
},
|
||||
astFormat: "estree-json",
|
||||
locStart,
|
||||
locEnd
|
||||
},
|
||||
flow: {
|
||||
get parse() {
|
||||
return eval("require")("./parser-flow");
|
||||
},
|
||||
astFormat: "estree",
|
||||
hasPragma,
|
||||
locStart,
|
||||
locEnd
|
||||
},
|
||||
"typescript-eslint": typescript,
|
||||
// TODO: Delete this in 2.0
|
||||
typescript
|
||||
};
|
||||
|
||||
const printers = {
|
||||
estree: estreePrinter,
|
||||
"estree-json": estreeJsonPrinter
|
||||
|
@ -237,6 +130,5 @@ const printers = {
|
|||
module.exports = {
|
||||
languages,
|
||||
options,
|
||||
parsers,
|
||||
printers
|
||||
};
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
"use strict";
|
||||
|
||||
const getLast = require("../utils/get-last");
|
||||
|
||||
function locStart(node) {
|
||||
// Handle nodes with decorators. They should start at the first decorator
|
||||
if (
|
||||
node.declaration &&
|
||||
node.declaration.decorators &&
|
||||
node.declaration.decorators.length > 0
|
||||
) {
|
||||
return locStart(node.declaration.decorators[0]);
|
||||
}
|
||||
if (node.decorators && node.decorators.length > 0) {
|
||||
return locStart(node.decorators[0]);
|
||||
}
|
||||
|
||||
if (node.__location) {
|
||||
return node.__location.startOffset;
|
||||
}
|
||||
if (node.range) {
|
||||
return node.range[0];
|
||||
}
|
||||
if (typeof node.start === "number") {
|
||||
return node.start;
|
||||
}
|
||||
if (node.loc) {
|
||||
return node.loc.start;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function locEnd(node) {
|
||||
const endNode = node.nodes && getLast(node.nodes);
|
||||
if (endNode && node.source && !node.source.end) {
|
||||
node = endNode;
|
||||
}
|
||||
|
||||
if (node.__location) {
|
||||
return node.__location.endOffset;
|
||||
}
|
||||
|
||||
const loc = node.range
|
||||
? node.range[1]
|
||||
: typeof node.end === "number"
|
||||
? node.end
|
||||
: null;
|
||||
|
||||
if (node.typeAnnotation) {
|
||||
return Math.max(loc, locEnd(node.typeAnnotation));
|
||||
}
|
||||
|
||||
if (node.loc && !loc) {
|
||||
return node.loc.end;
|
||||
}
|
||||
|
||||
return loc;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
locStart,
|
||||
locEnd
|
||||
};
|
|
@ -1,6 +1,8 @@
|
|||
"use strict";
|
||||
|
||||
const createError = require("../common/parser-create-error");
|
||||
const hasPragma = require("./pragma").hasPragma;
|
||||
const locFns = require("./loc");
|
||||
|
||||
function parse(text, parsers, opts) {
|
||||
// Inline the require to avoid loading all the JS if we don't use it
|
||||
|
@ -65,4 +67,94 @@ function parse(text, parsers, opts) {
|
|||
return ast;
|
||||
}
|
||||
|
||||
module.exports = parse;
|
||||
function parseJson(text, parsers, opts) {
|
||||
const ast = parse(text, parsers, Object.assign({}, opts, { parser: "json" }));
|
||||
|
||||
ast.comments.forEach(assertJsonNode);
|
||||
assertJsonNode(ast);
|
||||
|
||||
return ast;
|
||||
}
|
||||
|
||||
function assertJsonNode(node, parent) {
|
||||
switch (node.type) {
|
||||
case "ArrayExpression":
|
||||
return node.elements.forEach(assertJsonChildNode);
|
||||
case "ObjectExpression":
|
||||
return node.properties.forEach(assertJsonChildNode);
|
||||
case "ObjectProperty":
|
||||
// istanbul ignore if
|
||||
if (node.computed) {
|
||||
throw createJsonError("computed");
|
||||
}
|
||||
// istanbul ignore if
|
||||
if (node.shorthand) {
|
||||
throw createJsonError("shorthand");
|
||||
}
|
||||
return [node.key, node.value].forEach(assertJsonChildNode);
|
||||
case "UnaryExpression":
|
||||
switch (node.operator) {
|
||||
case "+":
|
||||
case "-":
|
||||
return assertJsonChildNode(node.argument);
|
||||
// istanbul ignore next
|
||||
default:
|
||||
throw createJsonError("operator");
|
||||
}
|
||||
case "Identifier":
|
||||
if (parent && parent.type === "ObjectProperty" && parent.key === node) {
|
||||
return;
|
||||
}
|
||||
throw createJsonError();
|
||||
case "NullLiteral":
|
||||
case "BooleanLiteral":
|
||||
case "NumericLiteral":
|
||||
case "StringLiteral":
|
||||
return;
|
||||
// istanbul ignore next
|
||||
default:
|
||||
throw createJsonError();
|
||||
}
|
||||
|
||||
function assertJsonChildNode(child) {
|
||||
return assertJsonNode(child, node);
|
||||
}
|
||||
|
||||
// istanbul ignore next
|
||||
function createJsonError(attribute) {
|
||||
const name = !attribute
|
||||
? node.type
|
||||
: `${node.type} with ${attribute}=${JSON.stringify(node[attribute])}`;
|
||||
return createError(`${name} is not allowed in JSON.`, {
|
||||
start: {
|
||||
line: node.loc.start.line,
|
||||
column: node.loc.start.column + 1
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const babylon = Object.assign(
|
||||
{ parse, astFormat: "estree", hasPragma },
|
||||
locFns
|
||||
);
|
||||
|
||||
// Export as a plugin so we can reuse the same bundle for UMD loading
|
||||
module.exports = {
|
||||
parsers: {
|
||||
babylon,
|
||||
json: Object.assign({}, babylon, {
|
||||
hasPragma() {
|
||||
return true;
|
||||
}
|
||||
}),
|
||||
json5: babylon,
|
||||
"json-stringify": Object.assign(
|
||||
{
|
||||
parse: parseJson,
|
||||
astFormat: "estree-json"
|
||||
},
|
||||
locFns
|
||||
)
|
||||
}
|
||||
};
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
const createError = require("../common/parser-create-error");
|
||||
const includeShebang = require("../common/parser-include-shebang");
|
||||
const hasPragma = require("./pragma").hasPragma;
|
||||
const locFns = require("./loc");
|
||||
|
||||
function parse(text /*, parsers, opts*/) {
|
||||
// Fixes Node 4 issue (#1986)
|
||||
|
@ -27,4 +29,10 @@ function parse(text /*, parsers, opts*/) {
|
|||
includeShebang(text, ast);
|
||||
return ast;
|
||||
}
|
||||
module.exports = parse;
|
||||
|
||||
// Export as a plugin so we can reuse the same bundle for UMD loading
|
||||
module.exports = {
|
||||
parsers: {
|
||||
flow: Object.assign({ parse, astFormat: "estree", hasPragma }, locFns)
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,77 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
const parserBabylon = eval("require")("./parser-babylon");
|
||||
const createError = require("../common/parser-create-error");
|
||||
|
||||
function parse(text, parsers, opts) {
|
||||
const ast = parserBabylon(
|
||||
text,
|
||||
parsers,
|
||||
Object.assign({}, opts, { parser: "json" })
|
||||
);
|
||||
|
||||
ast.comments.forEach(assertJsonNode);
|
||||
assertJsonNode(ast);
|
||||
|
||||
return ast;
|
||||
}
|
||||
|
||||
function assertJsonNode(node, parent) {
|
||||
switch (node.type) {
|
||||
case "ArrayExpression":
|
||||
return node.elements.forEach(assertJsonChildNode);
|
||||
case "ObjectExpression":
|
||||
return node.properties.forEach(assertJsonChildNode);
|
||||
case "ObjectProperty":
|
||||
// istanbul ignore if
|
||||
if (node.computed) {
|
||||
throw createJsonError("computed");
|
||||
}
|
||||
// istanbul ignore if
|
||||
if (node.shorthand) {
|
||||
throw createJsonError("shorthand");
|
||||
}
|
||||
return [node.key, node.value].forEach(assertJsonChildNode);
|
||||
case "UnaryExpression":
|
||||
switch (node.operator) {
|
||||
case "+":
|
||||
case "-":
|
||||
return assertJsonChildNode(node.argument);
|
||||
// istanbul ignore next
|
||||
default:
|
||||
throw createJsonError("operator");
|
||||
}
|
||||
case "Identifier":
|
||||
if (parent && parent.type === "ObjectProperty" && parent.key === node) {
|
||||
return;
|
||||
}
|
||||
throw createJsonError();
|
||||
case "NullLiteral":
|
||||
case "BooleanLiteral":
|
||||
case "NumericLiteral":
|
||||
case "StringLiteral":
|
||||
return;
|
||||
// istanbul ignore next
|
||||
default:
|
||||
throw createJsonError();
|
||||
}
|
||||
|
||||
function assertJsonChildNode(child) {
|
||||
return assertJsonNode(child, node);
|
||||
}
|
||||
|
||||
// istanbul ignore next
|
||||
function createJsonError(attribute) {
|
||||
const name = !attribute
|
||||
? node.type
|
||||
: `${node.type} with ${attribute}=${JSON.stringify(node[attribute])}`;
|
||||
return createError(`${name} is not allowed in JSON.`, {
|
||||
start: {
|
||||
line: node.loc.start.line,
|
||||
column: node.loc.start.column + 1
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = parse;
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
const createError = require("../common/parser-create-error");
|
||||
const includeShebang = require("../common/parser-include-shebang");
|
||||
const hasPragma = require("./pragma").hasPragma;
|
||||
const locFns = require("./loc");
|
||||
|
||||
function parse(text /*, parsers, opts*/) {
|
||||
const jsx = isProbablyJsx(text);
|
||||
|
@ -59,4 +61,12 @@ function isProbablyJsx(text) {
|
|||
).test(text);
|
||||
}
|
||||
|
||||
module.exports = parse;
|
||||
const parser = Object.assign({ parse, astFormat: "estree", hasPragma }, locFns);
|
||||
|
||||
// Export as a plugin so we can reuse the same bundle for UMD loading
|
||||
module.exports = {
|
||||
parsers: {
|
||||
typescript: parser,
|
||||
"typescript-eslint": parser
|
||||
}
|
||||
};
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
const printer = require("./printer-markdown");
|
||||
const options = require("./options");
|
||||
const pragma = require("./pragma");
|
||||
|
||||
// Based on:
|
||||
// https://github.com/github/linguist/blob/master/lib/linguist/languages.yml
|
||||
|
@ -35,22 +34,6 @@ const languages = [
|
|||
}
|
||||
];
|
||||
|
||||
const remark = {
|
||||
get parse() {
|
||||
return eval("require")("./parser-markdown");
|
||||
},
|
||||
astFormat: "mdast",
|
||||
hasPragma: pragma.hasPragma,
|
||||
locStart: node => node.position.start.offset,
|
||||
locEnd: node => node.position.end.offset
|
||||
};
|
||||
|
||||
const parsers = {
|
||||
remark,
|
||||
// TODO: Delete this in 2.0
|
||||
markdown: remark
|
||||
};
|
||||
|
||||
const printers = {
|
||||
mdast: printer
|
||||
};
|
||||
|
@ -58,6 +41,5 @@ const printers = {
|
|||
module.exports = {
|
||||
languages,
|
||||
options,
|
||||
parsers,
|
||||
printers
|
||||
};
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
const remarkParse = require("remark-parse");
|
||||
const unified = require("unified");
|
||||
const pragma = require("./pragma");
|
||||
const parseFrontMatter = require("../utils/front-matter");
|
||||
const util = require("../common/util");
|
||||
|
||||
|
@ -167,4 +168,18 @@ function liquid() {
|
|||
};
|
||||
}
|
||||
|
||||
module.exports = parse;
|
||||
const parser = {
|
||||
parse,
|
||||
astFormat: "mdast",
|
||||
hasPragma: pragma.hasPragma,
|
||||
locStart: node => node.position.start.offset,
|
||||
locEnd: node => node.position.end.offset
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
parsers: {
|
||||
remark: parser,
|
||||
// TODO: Delete this in 2.0
|
||||
markdown: parser
|
||||
}
|
||||
};
|
||||
|
|
|
@ -21,21 +21,11 @@ const languages = [
|
|||
}
|
||||
];
|
||||
|
||||
const parsers = {
|
||||
vue: {
|
||||
get parse() {
|
||||
return eval("require")("./parser-vue");
|
||||
},
|
||||
astFormat: "vue"
|
||||
}
|
||||
};
|
||||
|
||||
const printers = {
|
||||
vue: printer
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
languages,
|
||||
parsers,
|
||||
printers
|
||||
};
|
||||
|
|
|
@ -409,4 +409,11 @@ function parse(text /*, parsers, opts*/) {
|
|||
return rootObj;
|
||||
}
|
||||
|
||||
module.exports = parse;
|
||||
module.exports = {
|
||||
parsers: {
|
||||
vue: {
|
||||
parse,
|
||||
astFormat: "vue"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -87,7 +87,12 @@ function genericPrint(path, options, printPath, args) {
|
|||
if (node) {
|
||||
try {
|
||||
// Potentially switch to a different parser
|
||||
const sub = multiparser.printSubtree(path, printPath, options);
|
||||
const sub = multiparser.printSubtree(
|
||||
path,
|
||||
printPath,
|
||||
options,
|
||||
printAstToDoc
|
||||
);
|
||||
if (sub) {
|
||||
return sub;
|
||||
}
|
||||
|
|
|
@ -3,19 +3,19 @@
|
|||
const normalize = require("./options").normalize;
|
||||
const comments = require("./comments");
|
||||
|
||||
function printSubtree(path, print, options) {
|
||||
function printSubtree(path, print, options, printAstToDoc) {
|
||||
if (options.printer.embed) {
|
||||
return options.printer.embed(
|
||||
path,
|
||||
print,
|
||||
(text, partialNextOptions) =>
|
||||
textToDoc(text, partialNextOptions, options),
|
||||
textToDoc(text, partialNextOptions, options, printAstToDoc),
|
||||
options
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function textToDoc(text, partialNextOptions, parentOptions) {
|
||||
function textToDoc(text, partialNextOptions, parentOptions, printAstToDoc) {
|
||||
const nextOptions = normalize(
|
||||
Object.assign({}, parentOptions, partialNextOptions, {
|
||||
parentParser: parentOptions.parser,
|
||||
|
@ -31,7 +31,7 @@ function textToDoc(text, partialNextOptions, parentOptions) {
|
|||
const astComments = ast.comments;
|
||||
delete ast.comments;
|
||||
comments.attach(astComments, ast, text, nextOptions);
|
||||
return require("./ast-to-doc")(ast, nextOptions);
|
||||
return printAstToDoc(ast, nextOptions);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
|
|
@ -98,7 +98,7 @@ function getPlugin(options) {
|
|||
throw new Error("getPlugin() requires astFormat to be set");
|
||||
}
|
||||
const printerPlugin = options.plugins.find(
|
||||
plugin => plugin.printers[astFormat]
|
||||
plugin => plugin.printers && plugin.printers[astFormat]
|
||||
);
|
||||
if (!printerPlugin) {
|
||||
throw new Error(`Couldn't find plugin for AST format "${astFormat}"`);
|
||||
|
|
|
@ -2,16 +2,28 @@
|
|||
|
||||
const path = require("path");
|
||||
const ConfigError = require("../common/errors").ConfigError;
|
||||
const babylon = require("../language-js/index").parsers.babylon;
|
||||
const jsLoc = require("../language-js/loc");
|
||||
|
||||
const locStart = babylon.locStart;
|
||||
const locEnd = babylon.locEnd;
|
||||
const locStart = jsLoc.locStart;
|
||||
const locEnd = jsLoc.locEnd;
|
||||
|
||||
// Use defineProperties()/getOwnPropertyDescriptor() to prevent
|
||||
// triggering the parsers getters.
|
||||
const ownNames = Object.getOwnPropertyNames;
|
||||
const ownDescriptor = Object.getOwnPropertyDescriptor;
|
||||
function getParsers(options) {
|
||||
return options.plugins.reduce(
|
||||
(parsers, plugin) => Object.assign({}, parsers, plugin.parsers),
|
||||
{}
|
||||
);
|
||||
const parsers = {};
|
||||
for (const plugin of options.plugins) {
|
||||
if (!plugin.parsers) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const name of ownNames(plugin.parsers)) {
|
||||
Object.defineProperty(parsers, name, ownDescriptor(plugin.parsers, name));
|
||||
}
|
||||
}
|
||||
|
||||
return parsers;
|
||||
}
|
||||
|
||||
function resolveParser(opts, parsers) {
|
||||
|
@ -48,16 +60,16 @@ function resolveParser(opts, parsers) {
|
|||
function parse(text, opts) {
|
||||
const parsers = getParsers(opts);
|
||||
|
||||
// Copy the "parse" function from parser to a new object whose values are
|
||||
// functions. Use defineProperty()/getOwnPropertyDescriptor() such that we
|
||||
// don't invoke the parser.parse getters.
|
||||
// Create a new object {parserName: parseFn}. Uses defineProperty() to only call
|
||||
// the parsers getters when actually calling the parser `parse` function.
|
||||
const parsersForCustomParserApi = Object.keys(parsers).reduce(
|
||||
(object, parserName) =>
|
||||
Object.defineProperty(
|
||||
object,
|
||||
parserName,
|
||||
Object.getOwnPropertyDescriptor(parsers[parserName], "parse")
|
||||
),
|
||||
Object.defineProperty(object, parserName, {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return parsers[parserName].parse;
|
||||
}
|
||||
}),
|
||||
{}
|
||||
);
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ function getSupportInfo(version, opts) {
|
|||
const usePostCssParser = semver.lt(version, "1.7.1");
|
||||
|
||||
const languages = plugins
|
||||
.reduce((all, plugin) => all.concat(plugin.languages), [])
|
||||
.reduce((all, plugin) => all.concat(plugin.languages || []), [])
|
||||
.filter(
|
||||
language =>
|
||||
language.since
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = function(arr) {
|
||||
return arr.length > 0 ? arr[arr.length - 1] : null;
|
||||
};
|
|
@ -0,0 +1,13 @@
|
|||
"use strict";
|
||||
|
||||
// Super inefficient, needs to be cached.
|
||||
module.exports = function(lineColumn, text) {
|
||||
let index = 0;
|
||||
for (let i = 0; i < lineColumn.line - 1; ++i) {
|
||||
index = text.indexOf("\n", index) + 1;
|
||||
if (index === -1) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return index + lineColumn.column;
|
||||
};
|
|
@ -8,40 +8,33 @@ const getSupportInfo = require("./src/main/support").getSupportInfo;
|
|||
const internalPlugins = [
|
||||
require("./src/language-js"),
|
||||
require("./src/language-css"),
|
||||
require("./src/language-handlebars"),
|
||||
require("./src/language-graphql"),
|
||||
require("./src/language-markdown"),
|
||||
require("./src/language-html"),
|
||||
require("./src/language-vue")
|
||||
];
|
||||
const externalPlugins = {};
|
||||
|
||||
const isArray =
|
||||
Array.isArray ||
|
||||
function(arr) {
|
||||
return Object.prototype.toString.call(arr) === "[object Array]";
|
||||
};
|
||||
|
||||
// Luckily `opts` is always the 2nd argument
|
||||
function withPlugins(fn) {
|
||||
return function() {
|
||||
const args = Array.from(arguments);
|
||||
const opts = args[1] || {};
|
||||
args[1] = Object.assign({}, opts, {
|
||||
plugins: internalPlugins.concat(
|
||||
(opts.plugins || [])
|
||||
.map(
|
||||
plugin =>
|
||||
typeof plugin === "string" ? externalPlugins[plugin] : plugin
|
||||
)
|
||||
.filter(Boolean)
|
||||
)
|
||||
let plugins = (args[1] && args[1].plugins) || [];
|
||||
if (!isArray(plugins)) {
|
||||
plugins = Object.values(plugins);
|
||||
}
|
||||
args[1] = Object.assign({}, args[1], {
|
||||
plugins: internalPlugins.concat(plugins)
|
||||
});
|
||||
return fn.apply(null, args);
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
registerPlugin(pluginName, pluginBundle) {
|
||||
if (!externalPlugins.hasOwnProperty(pluginName)) {
|
||||
externalPlugins[pluginName] = pluginBundle;
|
||||
}
|
||||
},
|
||||
|
||||
format(text, opts) {
|
||||
return withPlugins(core.formatWithCursor)(text, opts).formatted;
|
||||
},
|
|
@ -0,0 +1,157 @@
|
|||
/* eslint-env worker */
|
||||
/* eslint no-var: off, strict: off */
|
||||
/* globals prettier prettierPlugins */
|
||||
|
||||
// this is required to only load parsers when we need them
|
||||
var parsers = {
|
||||
// JS - Babylon
|
||||
get babylon() {
|
||||
importScripts("lib/parser-babylon.js");
|
||||
return prettierPlugins.babylon.parsers.babylon;
|
||||
},
|
||||
get json() {
|
||||
importScripts("lib/parser-babylon.js");
|
||||
return prettierPlugins.babylon.parsers.json;
|
||||
},
|
||||
get json5() {
|
||||
importScripts("lib/parser-babylon.js");
|
||||
return prettierPlugins.babylon.parsers.json5;
|
||||
},
|
||||
get "json-stringify"() {
|
||||
importScripts("lib/parser-babylon.js");
|
||||
return prettierPlugins.babylon.parsers["json-stringify"];
|
||||
},
|
||||
// JS - Flow
|
||||
get flow() {
|
||||
importScripts("lib/parser-flow.js");
|
||||
return prettierPlugins.flow.parsers.flow;
|
||||
},
|
||||
// JS - TypeScript
|
||||
get typescript() {
|
||||
importScripts("lib/parser-typescript.js");
|
||||
return prettierPlugins.typescript.parsers.typescript;
|
||||
},
|
||||
|
||||
// CSS
|
||||
get css() {
|
||||
importScripts("lib/parser-postcss.js");
|
||||
return prettierPlugins.postcss.parsers.css;
|
||||
},
|
||||
get less() {
|
||||
importScripts("lib/parser-postcss.js");
|
||||
return prettierPlugins.postcss.parsers.css;
|
||||
},
|
||||
get scss() {
|
||||
importScripts("lib/parser-postcss.js");
|
||||
return prettierPlugins.postcss.parsers.css;
|
||||
},
|
||||
|
||||
// GraphQL
|
||||
get graphql() {
|
||||
importScripts("lib/parser-graphql.js");
|
||||
return prettierPlugins.graphql.parsers.graphql;
|
||||
},
|
||||
|
||||
// Markdown
|
||||
get markdown() {
|
||||
importScripts("lib/parser-markdown.js");
|
||||
return prettierPlugins.markdown.parsers.remark;
|
||||
},
|
||||
|
||||
// Vue
|
||||
get vue() {
|
||||
importScripts("lib/parser-vue.js");
|
||||
return prettierPlugins.vue.parsers.vue;
|
||||
}
|
||||
};
|
||||
|
||||
importScripts("lib/standalone.js");
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
var PRETTIER_DEBUG = true;
|
||||
|
||||
self.onmessage = function(event) {
|
||||
self.postMessage({
|
||||
uid: event.data.uid,
|
||||
message: handleMessage(event.data.message)
|
||||
});
|
||||
};
|
||||
|
||||
function handleMessage(message) {
|
||||
if (message.type === "meta") {
|
||||
return {
|
||||
type: "meta",
|
||||
supportInfo: JSON.parse(JSON.stringify(prettier.getSupportInfo())),
|
||||
version: prettier.version
|
||||
};
|
||||
}
|
||||
|
||||
if (message.type === "format") {
|
||||
var options = message.options || {};
|
||||
|
||||
delete options.ast;
|
||||
delete options.doc;
|
||||
delete options.output2;
|
||||
|
||||
options.plugins = [{ parsers: parsers }];
|
||||
|
||||
var response = {
|
||||
formatted: formatCode(message.code, options),
|
||||
debug: {
|
||||
ast: null,
|
||||
doc: null,
|
||||
reformatted: null
|
||||
}
|
||||
};
|
||||
|
||||
if (message.debug.ast) {
|
||||
var ast;
|
||||
var errored = false;
|
||||
try {
|
||||
ast = JSON.stringify(prettier.__debug.parse(message.code, options).ast);
|
||||
} catch (e) {
|
||||
errored = true;
|
||||
ast = String(e);
|
||||
}
|
||||
|
||||
if (!errored) {
|
||||
try {
|
||||
ast = formatCode(ast, { parser: "json" });
|
||||
} catch (e) {
|
||||
ast = JSON.stringify(ast, null, 2);
|
||||
}
|
||||
}
|
||||
response.debug.ast = ast;
|
||||
}
|
||||
|
||||
if (message.debug.doc) {
|
||||
try {
|
||||
response.debug.doc = prettier.__debug.formatDoc(
|
||||
prettier.__debug.printToDoc(message.code, options),
|
||||
{ parser: "babylon" }
|
||||
);
|
||||
} catch (e) {
|
||||
response.debug.doc = String(e);
|
||||
}
|
||||
}
|
||||
|
||||
if (message.debug.reformat) {
|
||||
response.debug.reformatted = formatCode(response.formatted, options);
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
function formatCode(text, options) {
|
||||
try {
|
||||
return prettier.format(text, options);
|
||||
} catch (e) {
|
||||
if (e.constructor && e.constructor.name === "SyntaxError") {
|
||||
// Likely something wrong with the user's code
|
||||
return String(e);
|
||||
}
|
||||
// Likely a bug in Prettier
|
||||
// Provide the whole stack for debugging
|
||||
return e.stack || String(e);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue