Prettier Plugin API (#3536)
* Move files around in preparation for refactor * Update paths in build script * Extract generic printing logic from the JavaScript printer * Conform printer API * Fixup decorator handling * Fix multiparser * Create plugin entry for markdown * Create plugin entry for javascript/typescript * Create plugin entry for html * Create plugin entry for graphql * Create plugin entry for css/less/scss * Move JSON to JS plugin entry * Integrate plugins into getSupportInfo() * Move astFormat to parser definition * Move util to common * Implement parser loading * remark -> mdast * Rename cli/cli -> cli/index * Rename builder -> doc package, fix printer resolution * Fix doc shape assumption in CSS-in-JS logic * Fix third-party.js prod resolution * Fixup build-docs script * Distribute multiparser code * Remove requirement to forward options * Flatten closure * Remove debug directory * Expose doc * Add external plugins * Pass options to loadPlugins * Export getParsers * Pin resolve version * Use getSupportInfo in Markdown embed * Document plugin API * Update build-docs * Add CLI for plugins * Lint docs * Fixup build.js * Add vue language * Fixup multiparser for vue * Upgrade rollup and rollup-plugin-commonjs * Fixup third-party build * Change AST format in docsmaster
parent
62bfcac4c5
commit
4c9d4061da
|
@ -0,0 +1,155 @@
|
|||
---
|
||||
id: plugins
|
||||
title: Plugins
|
||||
---
|
||||
|
||||
# IN DEVELOPMENT
|
||||
|
||||
> The plugin API is unreleased and the API may change!
|
||||
|
||||
Plugins are ways of adding new languages to Prettier. Prettier's own implementations of all languages are expressed using the plugin API. The core `prettier` package contains JavaScript and other web-focussed languages built in. For additional languages you'll need to install a plugin.
|
||||
|
||||
## Using Plugins
|
||||
|
||||
There are three ways to add plugins to Prettier:
|
||||
|
||||
* Via the CLI.
|
||||
* Via the API.
|
||||
* With a configuration file.
|
||||
|
||||
### Configuration File (Recommended)
|
||||
|
||||
In your [configuration file](./configuration.md), add the `plugins` property:
|
||||
|
||||
```json
|
||||
{
|
||||
"plugins": ["prettier-python"]
|
||||
}
|
||||
```
|
||||
|
||||
### CLI
|
||||
|
||||
With the [CLI](./cli.md), pass the `--plugin` flag:
|
||||
|
||||
```bash
|
||||
prettier --write main.py --plugin prettier-python
|
||||
```
|
||||
|
||||
> Tip: You can pass multiple `--plugin` flags.
|
||||
|
||||
## Official Plugins
|
||||
|
||||
* [`prettier-python`](https://github.com/prettier/prettier-python)
|
||||
* [`prettier-php`](https://github.com/prettier/prettier-php)
|
||||
|
||||
## Developing Plugins
|
||||
|
||||
Prettier plugins are regular JavaScript modules with three exports, `languages`, `parsers` and `printers`.
|
||||
|
||||
### `languages`
|
||||
|
||||
Languages is an array of language definitions that your plugin will contribute to Prettier. It can include all of the fields specified in [`prettier.getSupportInfo()`](./api.md#prettiergetsupportinfo-version).
|
||||
|
||||
It **must** include `name` and `parsers`.
|
||||
|
||||
```js
|
||||
export const languages = [
|
||||
{
|
||||
// The language name
|
||||
name: "InterpretedDanceScript",
|
||||
// Parsers that can parse this language.
|
||||
// This can be built-in parsers, or parsers you have contributed via this plugin.
|
||||
parsers: ["dance-parse"]
|
||||
}
|
||||
];
|
||||
```
|
||||
|
||||
### `parsers`
|
||||
|
||||
Parsers convert code as a string into an [AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree).
|
||||
|
||||
The key must match the name in the `parsers` array from `languages`. The value contains a parse function and an AST format name.
|
||||
|
||||
```js
|
||||
export const parsers = {
|
||||
"dance-parse": {
|
||||
parse,
|
||||
// The name of the AST that
|
||||
astFormat: "dance-ast"
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
The signature of the `parse` function is:
|
||||
|
||||
```ts
|
||||
function parse(text: string, parsers: object, options: object): AST;
|
||||
```
|
||||
|
||||
### `printers`
|
||||
|
||||
Printers convert ASTs into a Prettier intermediate representation, also known as a Doc.
|
||||
|
||||
The key must match the `astFormat` that the parser produces. The value contains an object with a `print` function and (optionally) an `embed` function.
|
||||
|
||||
```js
|
||||
export const printers = {
|
||||
"dance-ast": {
|
||||
print,
|
||||
embed
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
Printing is a recursive process of coverting an AST node (represented by a path to that node) into a doc. The doc is constructed using the [builder commands](https://github.com/prettier/prettier/blob/master/commands.md):
|
||||
|
||||
```js
|
||||
const { concat, join, line, ifBreak, group } = require("prettier").doc.builders;
|
||||
```
|
||||
|
||||
The signature of the `print` function is:
|
||||
|
||||
```ts
|
||||
function print(
|
||||
// Path to the AST node to print
|
||||
path: FastPath,
|
||||
options: object,
|
||||
// Recursively print a child node
|
||||
print: (path: FastPath) => Doc
|
||||
): Doc;
|
||||
```
|
||||
|
||||
Check out [prettier-python's printer](https://github.com/prettier/prettier-python/blob/034ba8a9551f3fa22cead41b323be0b28d06d13b/src/printer.js#L174) as an example.
|
||||
|
||||
Embedding refers to printing one language inside another. Examples of this are CSS-in-JS and Markdown code blocks. Plugins can switch to alternate languages using the `embed` function. Its signature is:
|
||||
|
||||
```ts
|
||||
function embed(
|
||||
// Path to the current AST node
|
||||
path: FastPath,
|
||||
// Print a node with the current printer
|
||||
print: (path: FastPath) => Doc,
|
||||
// Parse and print some text using a different parser.
|
||||
// You should set `options.parser` to specify which parser to use.
|
||||
textToDoc: (text: string, options: object) => Doc,
|
||||
// Current options
|
||||
options: object
|
||||
): Doc | null;
|
||||
```
|
||||
|
||||
If you don't want to switch to a different parser, simply return `null` or `undefined`.
|
||||
|
||||
## Testing Plugins
|
||||
|
||||
Since plugins can be resolved using relative paths, when working on one you can do:
|
||||
|
||||
```js
|
||||
const prettier = require("prettier");
|
||||
const code = "(add 1 2)";
|
||||
prettier.format(code, {
|
||||
parser: "lisp",
|
||||
plugins: ["."]
|
||||
});
|
||||
```
|
||||
|
||||
This will resolve a plugin relative to the current working direcrory.
|
21
index.js
21
index.js
|
@ -1,15 +1,16 @@
|
|||
"use strict";
|
||||
|
||||
const comments = require("./src/comments");
|
||||
const comments = require("./src/main/comments");
|
||||
const version = require("./package.json").version;
|
||||
const printAstToDoc = require("./src/printer").printAstToDoc;
|
||||
const util = require("./src/util");
|
||||
const printDocToString = require("./src/doc-printer").printDocToString;
|
||||
const normalizeOptions = require("./src/options").normalize;
|
||||
const parser = require("./src/parser");
|
||||
const printDocToDebug = require("./src/doc-debug").printDocToDebug;
|
||||
const config = require("./src/resolve-config");
|
||||
const getSupportInfo = require("./src/support").getSupportInfo;
|
||||
const printAstToDoc = require("./src/main/ast-to-doc");
|
||||
const util = require("./src/common/util");
|
||||
const doc = require("./src/doc");
|
||||
const printDocToString = doc.printer.printDocToString;
|
||||
const printDocToDebug = doc.debug.printDocToDebug;
|
||||
const normalizeOptions = require("./src/common/options").normalize;
|
||||
const parser = require("./src/main/parser");
|
||||
const config = require("./src/config/resolve-config");
|
||||
const getSupportInfo = require("./src/common/support").getSupportInfo;
|
||||
const docblock = require("jest-docblock");
|
||||
|
||||
function guessLineEnding(text) {
|
||||
|
@ -385,6 +386,8 @@ module.exports = {
|
|||
}
|
||||
},
|
||||
|
||||
doc,
|
||||
|
||||
resolveConfig: config.resolveConfig,
|
||||
clearConfigCache: config.clearCache,
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
"postcss-values-parser": "1.3.1",
|
||||
"remark-frontmatter": "1.1.0",
|
||||
"remark-parse": "4.0.0",
|
||||
"resolve": "1.5.0",
|
||||
"semver": "5.4.1",
|
||||
"string-width": "2.1.1",
|
||||
"typescript": "2.6.2",
|
||||
|
@ -70,8 +71,8 @@
|
|||
"prettier": "1.9.2",
|
||||
"prettylint": "1.0.0",
|
||||
"rimraf": "2.6.2",
|
||||
"rollup": "0.41.6",
|
||||
"rollup-plugin-commonjs": "7.0.2",
|
||||
"rollup": "0.47.6",
|
||||
"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",
|
||||
|
|
|
@ -4,19 +4,12 @@
|
|||
|
||||
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 parsers = [
|
||||
"babylon",
|
||||
"flow",
|
||||
"typescript",
|
||||
"graphql",
|
||||
"postcss",
|
||||
"parse5",
|
||||
"markdown",
|
||||
"vue"
|
||||
];
|
||||
|
||||
const stripLanguageDirectory = parserPath => parserPath.replace(/.*\//, "");
|
||||
|
||||
function pipe(string) {
|
||||
return new shell.ShellString(string);
|
||||
|
@ -25,6 +18,8 @@ function pipe(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) {
|
||||
|
@ -44,7 +39,6 @@ shell.exec(
|
|||
`node_modules/babel-cli/bin/babel.js ${docs}/index.js --out-file ${docs}/index.js --presets=es2015`
|
||||
);
|
||||
|
||||
shell.echo("Bundling docs babylon...");
|
||||
shell.exec(
|
||||
`rollup -c scripts/build/rollup.docs.config.js --environment filepath:parser-babylon.js -i ${prettierPath}/parser-babylon.js`
|
||||
);
|
||||
|
@ -52,13 +46,12 @@ 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 parsers) {
|
||||
if (parser === "babylon") {
|
||||
for (const parser of parserPaths) {
|
||||
if (parser.endsWith("babylon")) {
|
||||
continue;
|
||||
}
|
||||
shell.echo(`Bundling docs ${parser}...`);
|
||||
shell.exec(
|
||||
`rollup -c scripts/build/rollup.docs.config.js --environment filepath:parser-${parser}.js -i ${prettierPath}/parser-${parser}.js`
|
||||
`rollup -c scripts/build/rollup.docs.config.js --environment filepath:${parser}.js -i ${prettierPath}/${parser}.js`
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,19 +5,10 @@
|
|||
const path = require("path");
|
||||
const pkg = require("../../package.json");
|
||||
const formatMarkdown = require("../../website/static/markdown");
|
||||
const parsers = require("./parsers");
|
||||
const shell = require("shelljs");
|
||||
|
||||
const rootDir = path.join(__dirname, "..", "..");
|
||||
const parsers = [
|
||||
"babylon",
|
||||
"flow",
|
||||
"typescript",
|
||||
"graphql",
|
||||
"postcss",
|
||||
"parse5",
|
||||
"markdown",
|
||||
"vue"
|
||||
];
|
||||
|
||||
process.env.PATH += path.delimiter + path.join(rootDir, "node_modules", ".bin");
|
||||
|
||||
|
@ -32,30 +23,26 @@ shell.rm("-Rf", "dist/");
|
|||
|
||||
// --- Lib ---
|
||||
|
||||
shell.echo("Bundling lib index...");
|
||||
shell.exec("rollup -c scripts/build/rollup.index.config.js");
|
||||
|
||||
shell.echo("Bundling lib bin...");
|
||||
shell.exec("rollup -c scripts/build/rollup.bin.config.js");
|
||||
shell.chmod("+x", "./dist/bin/prettier.js");
|
||||
|
||||
shell.echo("Bundling lib third-party...");
|
||||
shell.exec("rollup -c scripts/build/rollup.third-party.config.js");
|
||||
|
||||
for (const parser of parsers) {
|
||||
if (parser === "postcss") {
|
||||
if (parser.endsWith("postcss")) {
|
||||
continue;
|
||||
}
|
||||
shell.echo(`Bundling lib ${parser}...`);
|
||||
shell.exec(
|
||||
`rollup -c scripts/build/rollup.parser.config.js --environment parser:${parser}`
|
||||
);
|
||||
}
|
||||
|
||||
shell.echo("Bundling lib postcss...");
|
||||
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/parser-postcss.js dist/parser-postcss.js"
|
||||
"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;
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = [
|
||||
"language-js/parser-babylon",
|
||||
"language-js/parser-flow",
|
||||
"language-js/parser-typescript",
|
||||
"language-graphql/parser-graphql",
|
||||
"language-css/parser-postcss",
|
||||
"language-html/parser-parse5",
|
||||
"language-markdown/parser-markdown",
|
||||
"language-vue/parser-vue"
|
||||
];
|
|
@ -24,9 +24,9 @@ export default Object.assign(baseConfig, {
|
|||
"assert",
|
||||
"util",
|
||||
"events",
|
||||
path.resolve("src/third-party.js")
|
||||
path.resolve("src/common/third-party.js")
|
||||
],
|
||||
paths: {
|
||||
[path.resolve("src/third-party.js")]: "../third-party"
|
||||
[path.resolve("src/common/third-party.js")]: "../third-party"
|
||||
}
|
||||
});
|
||||
|
|
|
@ -8,7 +8,7 @@ import * as path from "path";
|
|||
const external = ["assert"];
|
||||
|
||||
if (process.env.BUILD_TARGET !== "website") {
|
||||
external.push(path.resolve("src/third-party.js"));
|
||||
external.push(path.resolve("src/common/third-party.js"));
|
||||
}
|
||||
|
||||
export default Object.assign(baseConfig, {
|
||||
|
@ -25,6 +25,6 @@ export default Object.assign(baseConfig, {
|
|||
],
|
||||
external,
|
||||
paths: {
|
||||
[path.resolve("src/third-party.js")]: "./third-party"
|
||||
[path.resolve("src/common/third-party.js")]: "./third-party"
|
||||
}
|
||||
});
|
||||
|
|
|
@ -4,15 +4,16 @@ 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-" + parser + ".js",
|
||||
dest: "dist/parser-" + parser + ".js",
|
||||
entry: "src/" + parser + ".js",
|
||||
dest: "dist/" + path.basename(parser) + ".js",
|
||||
format: "cjs",
|
||||
plugins: [
|
||||
parser === "typescript"
|
||||
parser.endsWith("typescript")
|
||||
? replace({
|
||||
"exports.Syntax =": "1,",
|
||||
include: "node_modules/typescript-eslint-parser/parser.js"
|
||||
|
@ -21,7 +22,7 @@ export default Object.assign(baseConfig, {
|
|||
// In flow-parser 0.59.0 there's a dynamic require: `require(s8)` which not
|
||||
// supported by rollup-plugin-commonjs, so we have to replace the variable
|
||||
// by its value before bundling.
|
||||
parser === "flow"
|
||||
parser.endsWith("flow")
|
||||
? replace({
|
||||
"require(s8)": 'require("fs")',
|
||||
include: "node_modules/flow-parser/flow_parser.js"
|
||||
|
@ -50,5 +51,5 @@ export default Object.assign(baseConfig, {
|
|||
"os",
|
||||
"crypto"
|
||||
],
|
||||
useStrict: parser !== "flow"
|
||||
useStrict: !parser.endsWith("flow")
|
||||
});
|
||||
|
|
|
@ -5,7 +5,7 @@ import json from "rollup-plugin-json";
|
|||
import replace from "rollup-plugin-replace";
|
||||
|
||||
export default Object.assign(baseConfig, {
|
||||
entry: "src/third-party.js",
|
||||
entry: "src/common/third-party.js",
|
||||
dest: "dist/third-party.js",
|
||||
format: "cjs",
|
||||
plugins: [
|
||||
|
|
|
@ -47,6 +47,9 @@ const categoryOrder = [
|
|||
* // string: use this value as the API option name.
|
||||
* forwardToApi?: boolean | string;
|
||||
*
|
||||
* // Indicate that a CLI flag should be an array when forwarded to the API.
|
||||
* array?: boolean;
|
||||
*
|
||||
* // Specify available choices for validation. They will also be displayed
|
||||
* // in --help as <a|b|c>.
|
||||
* // Use an object instead of a string if a choice is deprecated and should
|
||||
|
@ -238,6 +241,14 @@ const detailedOptions = normalizeDetailedOptions({
|
|||
description: "Which parser to use.",
|
||||
getter: (value, argv) => (argv["flow-parser"] ? "flow" : value)
|
||||
},
|
||||
plugin: {
|
||||
type: "path",
|
||||
category: CATEGORY_CONFIG,
|
||||
description:
|
||||
"Add a plugin. Multiple plugins can be passed as separate `--plugin`s.",
|
||||
forwardToApi: "plugins",
|
||||
array: true
|
||||
},
|
||||
"print-width": {
|
||||
type: "int",
|
||||
category: CATEGORY_FORMAT,
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
const minimist = require("minimist");
|
||||
|
||||
const prettier = eval("require")("../index");
|
||||
const constant = require("./cli-constant");
|
||||
const util = require("./cli-util");
|
||||
const validator = require("./cli-validator");
|
||||
const logger = require("./cli-logger");
|
||||
const prettier = eval("require")("../../index");
|
||||
const constant = require("./constant");
|
||||
const util = require("./util");
|
||||
const validator = require("./validator");
|
||||
const logger = require("./logger");
|
||||
|
||||
function run(args) {
|
||||
const rawArgv = minimist(args, constant.minimistOptions);
|
|
@ -11,28 +11,30 @@ const chalk = require("chalk");
|
|||
const readline = require("readline");
|
||||
const leven = require("leven");
|
||||
|
||||
const prettier = eval("require")("../index");
|
||||
const cleanAST = require("./clean-ast").cleanAST;
|
||||
const resolver = require("./resolve-config");
|
||||
const constant = require("./cli-constant");
|
||||
const validator = require("./cli-validator");
|
||||
const apiDefaultOptions = require("./options").defaults;
|
||||
const errors = require("./errors");
|
||||
const logger = require("./cli-logger");
|
||||
const thirdParty = require("./third-party");
|
||||
const prettier = eval("require")("../../index");
|
||||
const cleanAST = require("../common/clean-ast").cleanAST;
|
||||
const resolver = require("../config/resolve-config");
|
||||
const constant = require("./constant");
|
||||
const validator = require("./validator");
|
||||
const apiDefaultOptions = require("../common/options").defaults;
|
||||
const errors = require("../common/errors");
|
||||
const logger = require("./logger");
|
||||
const thirdParty = require("../common/third-party");
|
||||
|
||||
const OPTION_USAGE_THRESHOLD = 25;
|
||||
const CHOICE_USAGE_MARGIN = 3;
|
||||
const CHOICE_USAGE_INDENTATION = 2;
|
||||
|
||||
function getOptions(argv) {
|
||||
return constant.detailedOptions
|
||||
.filter(option => option.forwardToApi)
|
||||
.reduce(
|
||||
(current, option) =>
|
||||
Object.assign(current, { [option.forwardToApi]: argv[option.name] }),
|
||||
{}
|
||||
);
|
||||
return constant.detailedOptions.filter(option => option.forwardToApi).reduce(
|
||||
(current, option) =>
|
||||
Object.assign(current, {
|
||||
[option.forwardToApi]: option.array
|
||||
? [].concat(argv[option.name] || [])
|
||||
: argv[option.name]
|
||||
}),
|
||||
{}
|
||||
);
|
||||
}
|
||||
|
||||
function dashifyObject(object) {
|
|
@ -1,7 +1,7 @@
|
|||
"use strict";
|
||||
|
||||
const camelCase = require("camelcase");
|
||||
const logger = require("./cli-logger");
|
||||
const logger = require("./logger");
|
||||
|
||||
function validateArgv(argv) {
|
||||
if (argv["write"] && argv["debug-check"]) {
|
|
@ -1,7 +1,7 @@
|
|||
"use strict";
|
||||
|
||||
const assert = require("assert");
|
||||
const util = require("./util");
|
||||
const util = require("../common/util");
|
||||
const startsWithNoLookaheadToken = util.startsWithNoLookaheadToken;
|
||||
|
||||
function FastPath(value) {
|
|
@ -0,0 +1,25 @@
|
|||
"use strict";
|
||||
|
||||
const resolve = require("resolve");
|
||||
|
||||
function loadPlugins(options) {
|
||||
options = Object.assign({ plugins: [] }, options);
|
||||
|
||||
const internalPlugins = [
|
||||
require("../language-js"),
|
||||
require("../language-css"),
|
||||
require("../language-graphql"),
|
||||
require("../language-markdown"),
|
||||
require("../language-html"),
|
||||
require("../language-vue")
|
||||
];
|
||||
|
||||
const externalPlugins = options.plugins.map(plugin => {
|
||||
const pluginPath = resolve.sync(plugin, { basedir: process.cwd() });
|
||||
return eval("require")(pluginPath);
|
||||
});
|
||||
|
||||
return internalPlugins.concat(externalPlugins);
|
||||
}
|
||||
|
||||
module.exports = loadPlugins;
|
|
@ -4,7 +4,7 @@ const path = require("path");
|
|||
|
||||
const validate = require("jest-validate").validate;
|
||||
const deprecatedConfig = require("./deprecated");
|
||||
const supportTable = require("./support").supportTable;
|
||||
const getSupportInfo = require("./support").getSupportInfo;
|
||||
|
||||
const defaults = {
|
||||
cursorOffset: -1,
|
||||
|
@ -22,7 +22,8 @@ const defaults = {
|
|||
requirePragma: false,
|
||||
semi: true,
|
||||
proseWrap: "preserve",
|
||||
arrowParens: "avoid"
|
||||
arrowParens: "avoid",
|
||||
plugins: []
|
||||
};
|
||||
|
||||
const exampleConfig = Object.assign({}, defaults, {
|
||||
|
@ -43,7 +44,7 @@ function normalize(options) {
|
|||
const extension = path.extname(filepath);
|
||||
const filename = path.basename(filepath).toLowerCase();
|
||||
|
||||
const language = supportTable.find(
|
||||
const language = getSupportInfo().languages.find(
|
||||
language =>
|
||||
typeof language.since === "string" &&
|
||||
(language.extensions.indexOf(extension) > -1 ||
|
|
@ -0,0 +1,43 @@
|
|||
"use strict";
|
||||
|
||||
const semver = require("semver");
|
||||
const currentVersion = require("../../package.json").version;
|
||||
const loadPlugins = require("./load-plugins");
|
||||
|
||||
function getSupportInfo(version, options) {
|
||||
if (!version) {
|
||||
version = currentVersion;
|
||||
}
|
||||
|
||||
const usePostCssParser = semver.lt(version, "1.7.1");
|
||||
|
||||
const languages = loadPlugins(options)
|
||||
.reduce((all, plugin) => all.concat(plugin.languages), [])
|
||||
.filter(language => language.since && semver.gte(version, language.since))
|
||||
.map(language => {
|
||||
// Prevent breaking changes
|
||||
if (language.name === "Markdown") {
|
||||
return Object.assign({}, language, {
|
||||
parsers: ["markdown"]
|
||||
});
|
||||
}
|
||||
if (language.name === "TypeScript") {
|
||||
return Object.assign({}, language, {
|
||||
parsers: ["typescript"]
|
||||
});
|
||||
}
|
||||
|
||||
if (usePostCssParser && language.group === "CSS") {
|
||||
return Object.assign({}, language, {
|
||||
parsers: ["postcss"]
|
||||
});
|
||||
}
|
||||
return language;
|
||||
});
|
||||
|
||||
return { languages };
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getSupportInfo
|
||||
};
|
|
@ -791,6 +791,20 @@ function getStringWidth(text) {
|
|||
return stringWidth(text.replace(emojiRegex, " "));
|
||||
}
|
||||
|
||||
function hasIgnoreComment(path) {
|
||||
const node = path.getValue();
|
||||
return hasNodeIgnoreComment(node);
|
||||
}
|
||||
|
||||
function hasNodeIgnoreComment(node) {
|
||||
return (
|
||||
node &&
|
||||
node.comments &&
|
||||
node.comments.length > 0 &&
|
||||
node.comments.some(comment => comment.value.trim() === "prettier-ignore")
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
punctuationRegex,
|
||||
punctuationCharRange,
|
||||
|
@ -827,5 +841,7 @@ module.exports = {
|
|||
getAlignmentSize,
|
||||
getIndentSize,
|
||||
printString,
|
||||
printNumber
|
||||
printNumber,
|
||||
hasIgnoreComment,
|
||||
hasNodeIgnoreComment
|
||||
};
|
|
@ -1,6 +1,6 @@
|
|||
"use strict";
|
||||
|
||||
const thirdParty = require("./third-party");
|
||||
const thirdParty = require("../common/third-party");
|
||||
const minimatch = require("minimatch");
|
||||
const path = require("path");
|
||||
const mem = require("mem");
|
|
@ -1,6 +1,6 @@
|
|||
"use strict";
|
||||
|
||||
const util = require("./util");
|
||||
const util = require("../common/util");
|
||||
const docBuilders = require("./doc-builders");
|
||||
const concat = docBuilders.concat;
|
||||
const fill = docBuilders.fill;
|
|
@ -167,6 +167,21 @@ function removeLines(doc) {
|
|||
});
|
||||
}
|
||||
|
||||
function stripTrailingHardline(doc) {
|
||||
// HACK remove ending hardline, original PR: #1984
|
||||
if (
|
||||
doc.type === "concat" &&
|
||||
doc.parts.length === 2 &&
|
||||
doc.parts[1].type === "concat" &&
|
||||
doc.parts[1].parts.length === 2 &&
|
||||
doc.parts[1].parts[0].hard &&
|
||||
doc.parts[1].parts[1].type === "break-parent"
|
||||
) {
|
||||
return doc.parts[0];
|
||||
}
|
||||
return doc;
|
||||
}
|
||||
|
||||
function rawText(node) {
|
||||
return node.extra ? node.extra.raw : node.raw;
|
||||
}
|
||||
|
@ -179,5 +194,6 @@ module.exports = {
|
|||
mapDoc,
|
||||
propagateBreaks,
|
||||
removeLines,
|
||||
stripTrailingHardline,
|
||||
rawText
|
||||
};
|
|
@ -0,0 +1,8 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
builders: require("./doc-builders"),
|
||||
printer: require("./doc-printer"),
|
||||
utils: require("./doc-utils"),
|
||||
debug: require("./doc-debug")
|
||||
};
|
|
@ -0,0 +1,72 @@
|
|||
"use strict";
|
||||
|
||||
const printer = require("./printer-postcss");
|
||||
|
||||
// Based on:
|
||||
// https://github.com/github/linguist/blob/master/lib/linguist/languages.yml
|
||||
|
||||
const languages = [
|
||||
{
|
||||
name: "CSS",
|
||||
since: "1.4.0",
|
||||
parsers: ["css"],
|
||||
group: "CSS",
|
||||
tmScope: "source.css",
|
||||
aceMode: "css",
|
||||
codemirrorMode: "css",
|
||||
codemirrorMimeType: "text/css",
|
||||
extensions: [".css", ".pcss", ".postcss"],
|
||||
liguistLanguageId: 50,
|
||||
vscodeLanguageIds: ["css", "postcss"]
|
||||
},
|
||||
{
|
||||
name: "Less",
|
||||
since: "1.4.0",
|
||||
parsers: ["less"],
|
||||
group: "CSS",
|
||||
extensions: [".less"],
|
||||
tmScope: "source.css.less",
|
||||
aceMode: "less",
|
||||
codemirrorMode: "css",
|
||||
codemirrorMimeType: "text/css",
|
||||
liguistLanguageId: 198,
|
||||
vscodeLanguageIds: ["less"]
|
||||
},
|
||||
{
|
||||
name: "SCSS",
|
||||
since: "1.4.0",
|
||||
parsers: ["scss"],
|
||||
group: "CSS",
|
||||
tmScope: "source.scss",
|
||||
aceMode: "scss",
|
||||
codemirrorMode: "css",
|
||||
codemirrorMimeType: "text/x-scss",
|
||||
extensions: [".scss"],
|
||||
liguistLanguageId: 329,
|
||||
vscodeLanguageIds: ["scss"]
|
||||
}
|
||||
];
|
||||
|
||||
const postcss = {
|
||||
get parse() {
|
||||
return eval("require")("./parser-postcss");
|
||||
},
|
||||
astFormat: "postcss"
|
||||
};
|
||||
|
||||
// TODO: switch these to just `postcss` and use `language` instead.
|
||||
const parsers = {
|
||||
css: postcss,
|
||||
less: postcss,
|
||||
scss: postcss
|
||||
};
|
||||
|
||||
const printers = {
|
||||
postcss: printer
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
languages,
|
||||
parsers,
|
||||
printers
|
||||
};
|
|
@ -1,6 +1,6 @@
|
|||
"use strict";
|
||||
|
||||
const createError = require("./parser-create-error");
|
||||
const createError = require("../common/parser-create-error");
|
||||
|
||||
function parseSelector(selector) {
|
||||
const selectorParser = require("postcss-selector-parser");
|
|
@ -1,7 +1,8 @@
|
|||
"use strict";
|
||||
|
||||
const util = require("./util");
|
||||
const docBuilders = require("./doc-builders");
|
||||
const util = require("../common/util");
|
||||
const doc = require("../doc");
|
||||
const docBuilders = doc.builders;
|
||||
const concat = docBuilders.concat;
|
||||
const join = docBuilders.join;
|
||||
const line = docBuilders.line;
|
||||
|
@ -11,8 +12,7 @@ const group = docBuilders.group;
|
|||
const fill = docBuilders.fill;
|
||||
const indent = docBuilders.indent;
|
||||
|
||||
const docUtils = require("./doc-utils");
|
||||
const removeLines = docUtils.removeLines;
|
||||
const removeLines = doc.utils.removeLines;
|
||||
|
||||
function genericPrint(path, options, print) {
|
||||
const n = path.getValue();
|
||||
|
@ -533,4 +533,7 @@ function maybeToLowerCase(value) {
|
|||
: value.toLowerCase();
|
||||
}
|
||||
|
||||
module.exports = genericPrint;
|
||||
module.exports = {
|
||||
print: genericPrint,
|
||||
hasPrettierIgnore: util.hasIgnoreComment
|
||||
};
|
|
@ -0,0 +1,38 @@
|
|||
"use strict";
|
||||
|
||||
const printer = require("./printer-graphql");
|
||||
|
||||
// Based on:
|
||||
// https://github.com/github/linguist/blob/master/lib/linguist/languages.yml
|
||||
|
||||
const languages = [
|
||||
{
|
||||
name: "GraphQL",
|
||||
since: "1.5.0",
|
||||
parsers: ["graphql"],
|
||||
extensions: [".graphql", ".gql"],
|
||||
tmScope: "source.graphql",
|
||||
aceMode: "text",
|
||||
liguistLanguageId: 139,
|
||||
vscodeLanguageIds: ["graphql"]
|
||||
}
|
||||
];
|
||||
|
||||
const parsers = {
|
||||
graphql: {
|
||||
get parse() {
|
||||
return eval("require")("./parser-graphql");
|
||||
},
|
||||
astFormat: "graphql"
|
||||
}
|
||||
};
|
||||
|
||||
const printers = {
|
||||
graphql: printer
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
languages,
|
||||
parsers,
|
||||
printers
|
||||
};
|
|
@ -1,6 +1,6 @@
|
|||
"use strict";
|
||||
|
||||
const createError = require("./parser-create-error");
|
||||
const createError = require("../common/parser-create-error");
|
||||
|
||||
function parseComments(ast) {
|
||||
const comments = [];
|
|
@ -1,6 +1,6 @@
|
|||
"use strict";
|
||||
|
||||
const docBuilders = require("./doc-builders");
|
||||
const docBuilders = require("../doc").builders;
|
||||
const concat = docBuilders.concat;
|
||||
const join = docBuilders.join;
|
||||
const hardline = docBuilders.hardline;
|
||||
|
@ -10,7 +10,7 @@ const group = docBuilders.group;
|
|||
const indent = docBuilders.indent;
|
||||
const ifBreak = docBuilders.ifBreak;
|
||||
|
||||
const util = require("./util");
|
||||
const util = require("../common/util");
|
||||
|
||||
function genericPrint(path, options, print) {
|
||||
const n = path.getValue();
|
||||
|
@ -539,4 +539,7 @@ function printSequence(sequencePath, options, print) {
|
|||
});
|
||||
}
|
||||
|
||||
module.exports = genericPrint;
|
||||
module.exports = {
|
||||
print: genericPrint,
|
||||
hasPrettierIgnore: util.hasIgnoreComment
|
||||
};
|
|
@ -0,0 +1,93 @@
|
|||
"use strict";
|
||||
|
||||
const util = require("../common/util");
|
||||
const doc = require("../doc");
|
||||
const docUtils = doc.utils;
|
||||
const docBuilders = doc.builders;
|
||||
const hardline = docBuilders.hardline;
|
||||
const concat = docBuilders.concat;
|
||||
|
||||
function embed(path, print, textToDoc, options) {
|
||||
const node = path.getValue();
|
||||
|
||||
switch (node.type) {
|
||||
case "text": {
|
||||
const parent = path.getParentNode();
|
||||
// Inline JavaScript
|
||||
if (
|
||||
parent.type === "script" &&
|
||||
((!parent.attribs.lang && !parent.attribs.lang) ||
|
||||
parent.attribs.type === "text/javascript" ||
|
||||
parent.attribs.type === "application/javascript")
|
||||
) {
|
||||
const parser = options.parser === "flow" ? "flow" : "babylon";
|
||||
const doc = textToDoc(getText(options, node), { parser });
|
||||
return concat([hardline, doc]);
|
||||
}
|
||||
|
||||
// Inline TypeScript
|
||||
if (
|
||||
parent.type === "script" &&
|
||||
(parent.attribs.type === "application/x-typescript" ||
|
||||
parent.attribs.lang === "ts")
|
||||
) {
|
||||
const doc = textToDoc(
|
||||
getText(options, node),
|
||||
{ parser: "typescript" },
|
||||
options
|
||||
);
|
||||
return concat([hardline, doc]);
|
||||
}
|
||||
|
||||
// Inline Styles
|
||||
if (parent.type === "style") {
|
||||
const doc = textToDoc(getText(options, node), { parser: "css" });
|
||||
return concat([hardline, docUtils.stripTrailingHardline(doc)]);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case "attribute": {
|
||||
/*
|
||||
* Vue binding sytax: JS expressions
|
||||
* :class="{ 'some-key': value }"
|
||||
* v-bind:id="'list-' + id"
|
||||
* v-if="foo && !bar"
|
||||
* @click="someFunction()"
|
||||
*/
|
||||
if (/(^@)|(^v-)|:/.test(node.key) && !/^\w+$/.test(node.value)) {
|
||||
const doc = textToDoc(node.value, {
|
||||
parser: parseJavaScriptExpression,
|
||||
// Use singleQuote since HTML attributes use double-quotes.
|
||||
// TODO(azz): We still need to do an entity escape on the attribute.
|
||||
singleQuote: true
|
||||
});
|
||||
return concat([
|
||||
node.key,
|
||||
'="',
|
||||
util.hasNewlineInRange(node.value, 0, node.value.length)
|
||||
? doc
|
||||
: docUtils.removeLines(doc),
|
||||
'"'
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function parseJavaScriptExpression(text, parsers) {
|
||||
// Force parsing as an expression
|
||||
const ast = parsers.babylon(`(${text})`);
|
||||
// Extract expression from the declaration
|
||||
return {
|
||||
type: "File",
|
||||
program: ast.program.body[0].expression
|
||||
};
|
||||
}
|
||||
|
||||
function getText(options, node) {
|
||||
return options.originalText.slice(util.locStart(node), util.locEnd(node));
|
||||
}
|
||||
|
||||
module.exports = embed;
|
|
@ -0,0 +1,42 @@
|
|||
"use strict";
|
||||
|
||||
const printer = require("./printer-htmlparser2");
|
||||
|
||||
// Based on:
|
||||
// https://github.com/github/linguist/blob/master/lib/linguist/languages.yml
|
||||
|
||||
const languages = [
|
||||
{
|
||||
name: "HTML",
|
||||
since: undefined, // unreleased
|
||||
parsers: ["parse5"],
|
||||
group: "HTML",
|
||||
tmScope: "text.html.basic",
|
||||
aceMode: "html",
|
||||
codemirrorMode: "htmlmixed",
|
||||
codemirrorMimeType: "text/html",
|
||||
aliases: ["xhtml"],
|
||||
extensions: [".html", ".htm", ".html.hl", ".inc", ".st", ".xht", ".xhtml"],
|
||||
linguistLanguageId: 146,
|
||||
vscodeLanguageIds: ["html"]
|
||||
}
|
||||
];
|
||||
|
||||
const parsers = {
|
||||
parse5: {
|
||||
get parse() {
|
||||
return eval("require")("./parser-parse5");
|
||||
},
|
||||
astFormat: "htmlparser2"
|
||||
}
|
||||
};
|
||||
|
||||
const printers = {
|
||||
htmlparser2: printer
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
languages,
|
||||
parsers,
|
||||
printers
|
||||
};
|
|
@ -1,7 +1,8 @@
|
|||
"use strict";
|
||||
|
||||
const util = require("./util");
|
||||
const docBuilders = require("./doc-builders");
|
||||
const embed = require("./embed");
|
||||
const util = require("../common/util");
|
||||
const docBuilders = require("../doc").builders;
|
||||
const concat = docBuilders.concat;
|
||||
const join = docBuilders.join;
|
||||
const hardline = docBuilders.hardline;
|
||||
|
@ -114,4 +115,8 @@ function printChildren(path, print) {
|
|||
return concat(children);
|
||||
}
|
||||
|
||||
module.exports = genericPrint;
|
||||
module.exports = {
|
||||
print: genericPrint,
|
||||
embed,
|
||||
hasPrettierIgnore: util.hasIgnoreComment
|
||||
};
|
|
@ -1,139 +1,16 @@
|
|||
"use strict";
|
||||
|
||||
const util = require("./util");
|
||||
const docUtils = require("./doc-utils");
|
||||
const docBuilders = require("./doc-builders");
|
||||
const comments = require("./comments");
|
||||
const util = require("../common/util");
|
||||
const doc = require("../doc");
|
||||
const docUtils = doc.utils;
|
||||
const docBuilders = doc.builders;
|
||||
const indent = docBuilders.indent;
|
||||
const join = docBuilders.join;
|
||||
const hardline = docBuilders.hardline;
|
||||
const softline = docBuilders.softline;
|
||||
const concat = docBuilders.concat;
|
||||
|
||||
function printSubtree(path, print, options) {
|
||||
switch (options.parser) {
|
||||
case "parse5":
|
||||
return fromHtmlParser2(path, print, options);
|
||||
case "babylon":
|
||||
case "flow":
|
||||
case "typescript":
|
||||
return fromBabylonFlowOrTypeScript(path, print, options);
|
||||
case "markdown":
|
||||
return fromMarkdown(path, print, options);
|
||||
case "vue":
|
||||
return fromVue(path, print, options);
|
||||
}
|
||||
}
|
||||
|
||||
function parseAndPrint(text, partialNextOptions, parentOptions) {
|
||||
const nextOptions = Object.assign({}, parentOptions, partialNextOptions, {
|
||||
parentParser: parentOptions.parser,
|
||||
originalText: text
|
||||
});
|
||||
if (nextOptions.parser === "json") {
|
||||
nextOptions.trailingComma = "none";
|
||||
}
|
||||
const ast = require("./parser").parse(text, nextOptions);
|
||||
const astComments = ast.comments;
|
||||
delete ast.comments;
|
||||
comments.attach(astComments, ast, text, nextOptions);
|
||||
return require("./printer").printAstToDoc(ast, nextOptions);
|
||||
}
|
||||
|
||||
function fromVue(path, print, options) {
|
||||
const node = path.getValue();
|
||||
const parent = path.getParentNode();
|
||||
if (!parent || parent.tag !== "root") {
|
||||
return null;
|
||||
}
|
||||
|
||||
let parser;
|
||||
|
||||
if (node.tag === "style") {
|
||||
const langAttr = node.attrs.find(attr => attr.name === "lang");
|
||||
if (!langAttr) {
|
||||
parser = "css";
|
||||
} else if (langAttr.value === "scss") {
|
||||
parser = "scss";
|
||||
} else if (langAttr.value === "less") {
|
||||
parser = "less";
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if (node.tag === "script") {
|
||||
const langAttr = node.attrs.find(attr => attr.name === "lang");
|
||||
if (!langAttr) {
|
||||
parser = "babylon";
|
||||
} else if (langAttr.value === "ts") {
|
||||
parser = "typescript";
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return concat([
|
||||
options.originalText.slice(node.start, node.contentStart),
|
||||
hardline,
|
||||
parseAndPrint(
|
||||
options.originalText.slice(node.contentStart, node.contentEnd),
|
||||
parser,
|
||||
options
|
||||
),
|
||||
options.originalText.slice(node.contentEnd, node.end)
|
||||
]);
|
||||
}
|
||||
|
||||
function fromMarkdown(path, print, options) {
|
||||
const node = path.getValue();
|
||||
|
||||
if (node.type === "code") {
|
||||
const parser = getParserName(node.lang);
|
||||
if (parser) {
|
||||
const styleUnit = options.__inJsTemplate ? "~" : "`";
|
||||
const style = styleUnit.repeat(
|
||||
Math.max(3, util.getMaxContinuousCount(node.value, styleUnit) + 1)
|
||||
);
|
||||
const doc = parseAndPrint(node.value, { parser }, options);
|
||||
return concat([style, node.lang, hardline, doc, style]);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
function getParserName(lang) {
|
||||
switch (lang) {
|
||||
case "js":
|
||||
case "jsx":
|
||||
case "javascript":
|
||||
return "babylon";
|
||||
case "ts":
|
||||
case "tsx":
|
||||
case "typescript":
|
||||
return "typescript";
|
||||
case "gql":
|
||||
case "graphql":
|
||||
return "graphql";
|
||||
case "css":
|
||||
return "css";
|
||||
case "less":
|
||||
return "less";
|
||||
case "scss":
|
||||
return "scss";
|
||||
case "json":
|
||||
case "json5":
|
||||
return "json";
|
||||
case "md":
|
||||
case "markdown":
|
||||
return "markdown";
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function fromBabylonFlowOrTypeScript(path, print, options) {
|
||||
function embed(path, print, textToDoc /*, options */) {
|
||||
const node = path.getValue();
|
||||
const parent = path.getParentNode();
|
||||
const parentParent = path.getParentNode(1);
|
||||
|
@ -148,7 +25,7 @@ function fromBabylonFlowOrTypeScript(path, print, options) {
|
|||
// Get full template literal with expressions replaced by placeholders
|
||||
const rawQuasis = node.quasis.map(q => q.value.raw);
|
||||
const text = rawQuasis.join("@prettier-placeholder");
|
||||
const doc = parseAndPrint(text, { parser: "css" }, options);
|
||||
const doc = textToDoc(text, { parser: "css" });
|
||||
return transformCssDoc(doc, path, print);
|
||||
}
|
||||
|
||||
|
@ -213,8 +90,8 @@ function fromBabylonFlowOrTypeScript(path, print, options) {
|
|||
doc = printGraphqlComments(lines);
|
||||
} else {
|
||||
try {
|
||||
doc = stripTrailingHardline(
|
||||
parseAndPrint(text, { parser: "graphql" }, options)
|
||||
doc = docUtils.stripTrailingHardline(
|
||||
textToDoc(text, { parser: "graphql" })
|
||||
);
|
||||
} catch (_error) {
|
||||
// Bail if any part fails to parse.
|
||||
|
@ -263,18 +140,20 @@ function fromBabylonFlowOrTypeScript(path, print, options) {
|
|||
(parentParent.tag.name === "md" ||
|
||||
parentParent.tag.name === "markdown")))
|
||||
) {
|
||||
const doc = parseAndPrint(
|
||||
const doc = textToDoc(
|
||||
// leading whitespaces matter in markdown
|
||||
dedent(parent.quasis[0].value.cooked),
|
||||
{
|
||||
parser: "markdown",
|
||||
__inJsTemplate: true
|
||||
},
|
||||
options
|
||||
}
|
||||
);
|
||||
return concat([
|
||||
indent(
|
||||
concat([softline, stripTrailingHardline(escapeBackticks(doc))])
|
||||
concat([
|
||||
softline,
|
||||
docUtils.stripTrailingHardline(escapeBackticks(doc))
|
||||
])
|
||||
),
|
||||
softline
|
||||
]);
|
||||
|
@ -285,32 +164,6 @@ function fromBabylonFlowOrTypeScript(path, print, options) {
|
|||
}
|
||||
}
|
||||
|
||||
function printGraphqlComments(lines) {
|
||||
const parts = [];
|
||||
let seenComment = false;
|
||||
|
||||
lines.map(textLine => textLine.trim()).forEach((textLine, i, array) => {
|
||||
// Lines are either whitespace only, or a comment (with poential whitespace
|
||||
// around it). Drop whitespace-only lines.
|
||||
if (textLine === "") {
|
||||
return;
|
||||
}
|
||||
|
||||
if (array[i - 1] === "" && seenComment) {
|
||||
// If a non-first comment is preceded by a blank (whitespace only) line,
|
||||
// add in a blank line.
|
||||
parts.push(concat([hardline, textLine]));
|
||||
} else {
|
||||
parts.push(textLine);
|
||||
}
|
||||
|
||||
seenComment = true;
|
||||
});
|
||||
|
||||
// If `lines` was whitespace only, return `null`.
|
||||
return parts.length === 0 ? null : join(hardline, parts);
|
||||
}
|
||||
|
||||
function dedent(str) {
|
||||
const firstMatchedIndent = str.match(/\n^( *)/m);
|
||||
const spaces = firstMatchedIndent === null ? 0 : firstMatchedIndent[1].length;
|
||||
|
@ -337,83 +190,6 @@ function escapeBackticks(doc) {
|
|||
});
|
||||
}
|
||||
|
||||
function fromHtmlParser2(path, print, options) {
|
||||
const node = path.getValue();
|
||||
|
||||
switch (node.type) {
|
||||
case "text": {
|
||||
const parent = path.getParentNode();
|
||||
// Inline JavaScript
|
||||
if (
|
||||
parent.type === "script" &&
|
||||
((!parent.attribs.lang && !parent.attribs.lang) ||
|
||||
parent.attribs.type === "text/javascript" ||
|
||||
parent.attribs.type === "application/javascript")
|
||||
) {
|
||||
const parser = options.parser === "flow" ? "flow" : "babylon";
|
||||
const doc = parseAndPrint(getText(options, node), { parser }, options);
|
||||
return concat([hardline, doc]);
|
||||
}
|
||||
|
||||
// Inline TypeScript
|
||||
if (
|
||||
parent.type === "script" &&
|
||||
(parent.attribs.type === "application/x-typescript" ||
|
||||
parent.attribs.lang === "ts")
|
||||
) {
|
||||
const doc = parseAndPrint(
|
||||
getText(options, node),
|
||||
{ parser: "typescript" },
|
||||
options
|
||||
);
|
||||
return concat([hardline, doc]);
|
||||
}
|
||||
|
||||
// Inline Styles
|
||||
if (parent.type === "style") {
|
||||
const doc = parseAndPrint(
|
||||
getText(options, node),
|
||||
{ parser: "css" },
|
||||
options
|
||||
);
|
||||
return concat([hardline, stripTrailingHardline(doc)]);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case "attribute": {
|
||||
/*
|
||||
* Vue binding sytax: JS expressions
|
||||
* :class="{ 'some-key': value }"
|
||||
* v-bind:id="'list-' + id"
|
||||
* v-if="foo && !bar"
|
||||
* @click="someFunction()"
|
||||
*/
|
||||
if (/(^@)|(^v-)|:/.test(node.key) && !/^\w+$/.test(node.value)) {
|
||||
const doc = parseAndPrint(
|
||||
node.value,
|
||||
{
|
||||
parser: parseJavaScriptExpression,
|
||||
// Use singleQuote since HTML attributes use double-quotes.
|
||||
// TODO(azz): We still need to do an entity escape on the attribute.
|
||||
singleQuote: true
|
||||
},
|
||||
options
|
||||
);
|
||||
return concat([
|
||||
node.key,
|
||||
'="',
|
||||
util.hasNewlineInRange(node.value, 0, node.value.length)
|
||||
? doc
|
||||
: docUtils.removeLines(doc),
|
||||
'"'
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function transformCssDoc(quasisDoc, path, print) {
|
||||
const parentNode = path.getValue();
|
||||
|
||||
|
@ -433,7 +209,7 @@ function transformCssDoc(quasisDoc, path, print) {
|
|||
}
|
||||
return concat([
|
||||
"`",
|
||||
indent(concat([hardline, stripTrailingHardline(newDoc)])),
|
||||
indent(concat([hardline, docUtils.stripTrailingHardline(newDoc)])),
|
||||
softline,
|
||||
"`"
|
||||
]);
|
||||
|
@ -454,31 +230,39 @@ function replacePlaceholders(quasisDoc, expressionDocs) {
|
|||
return doc;
|
||||
}
|
||||
let parts = doc.parts;
|
||||
const atIndex = parts.indexOf("@");
|
||||
const placeholderIndex = atIndex + 1;
|
||||
if (
|
||||
parts.length > 1 &&
|
||||
parts[0] === "@" &&
|
||||
typeof parts[1] === "string" &&
|
||||
parts[1].startsWith("prettier-placeholder")
|
||||
atIndex > -1 &&
|
||||
typeof parts[placeholderIndex] === "string" &&
|
||||
parts[placeholderIndex].startsWith("prettier-placeholder")
|
||||
) {
|
||||
// If placeholder is split, join it
|
||||
const at = parts[0];
|
||||
const placeholder = parts[1];
|
||||
const rest = parts.slice(2);
|
||||
parts = [at + placeholder].concat(rest);
|
||||
const at = parts[atIndex];
|
||||
const placeholder = parts[placeholderIndex];
|
||||
const rest = parts.slice(placeholderIndex + 1);
|
||||
parts = parts
|
||||
.slice(0, atIndex)
|
||||
.concat([at + placeholder])
|
||||
.concat(rest);
|
||||
}
|
||||
if (
|
||||
typeof parts[0] === "string" &&
|
||||
parts[0].startsWith("@prettier-placeholder")
|
||||
) {
|
||||
const placeholder = parts[0];
|
||||
const rest = parts.slice(1);
|
||||
const atPlaceholderIndex = parts.findIndex(
|
||||
part =>
|
||||
typeof part === "string" && part.startsWith("@prettier-placeholder")
|
||||
);
|
||||
if (atPlaceholderIndex > -1) {
|
||||
const placeholder = parts[atPlaceholderIndex];
|
||||
const rest = parts.slice(atPlaceholderIndex + 1);
|
||||
|
||||
// When the expression has a suffix appended, like:
|
||||
// animation: linear ${time}s ease-out;
|
||||
const suffix = placeholder.slice("@prettier-placeholder".length);
|
||||
|
||||
const expression = expressions.shift();
|
||||
parts = ["${", expression, "}" + suffix].concat(rest);
|
||||
parts = parts
|
||||
.slice(0, atPlaceholderIndex)
|
||||
.concat(["${", expression, "}" + suffix])
|
||||
.concat(rest);
|
||||
}
|
||||
return Object.assign({}, doc, {
|
||||
parts: parts
|
||||
|
@ -488,35 +272,30 @@ function replacePlaceholders(quasisDoc, expressionDocs) {
|
|||
return expressions.length === 0 ? newDoc : null;
|
||||
}
|
||||
|
||||
function parseJavaScriptExpression(text, parsers) {
|
||||
// Force parsing as an expression
|
||||
const ast = parsers.babylon(`(${text})`);
|
||||
// Extract expression from the declaration
|
||||
return {
|
||||
type: "File",
|
||||
program: ast.program.body[0].expression
|
||||
};
|
||||
}
|
||||
function printGraphqlComments(lines) {
|
||||
const parts = [];
|
||||
let seenComment = false;
|
||||
|
||||
function getText(options, node) {
|
||||
return options.originalText.slice(util.locStart(node), util.locEnd(node));
|
||||
}
|
||||
lines.map(textLine => textLine.trim()).forEach((textLine, i, array) => {
|
||||
// Lines are either whitespace only, or a comment (with poential whitespace
|
||||
// around it). Drop whitespace-only lines.
|
||||
if (textLine === "") {
|
||||
return;
|
||||
}
|
||||
|
||||
function stripTrailingHardline(doc) {
|
||||
// HACK remove ending hardline, original PR: #1984
|
||||
if (
|
||||
doc.type === "concat" &&
|
||||
doc.parts[0].type === "concat" &&
|
||||
doc.parts[0].parts.length === 2 &&
|
||||
// doc.parts[0].parts[1] === hardline :
|
||||
doc.parts[0].parts[1].type === "concat" &&
|
||||
doc.parts[0].parts[1].parts.length === 2 &&
|
||||
doc.parts[0].parts[1].parts[0].hard &&
|
||||
doc.parts[0].parts[1].parts[1].type === "break-parent"
|
||||
) {
|
||||
return doc.parts[0].parts[0];
|
||||
}
|
||||
return doc;
|
||||
if (array[i - 1] === "" && seenComment) {
|
||||
// If a non-first comment is preceded by a blank (whitespace only) line,
|
||||
// add in a blank line.
|
||||
parts.push(concat([hardline, textLine]));
|
||||
} else {
|
||||
parts.push(textLine);
|
||||
}
|
||||
|
||||
seenComment = true;
|
||||
});
|
||||
|
||||
// If `lines` was whitespace only, return `null`.
|
||||
return parts.length === 0 ? null : join(hardline, parts);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -601,6 +380,4 @@ function isStyledIdentifier(node) {
|
|||
return node.type === "Identifier" && node.name === "styled";
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
printSubtree
|
||||
};
|
||||
module.exports = embed;
|
|
@ -0,0 +1,138 @@
|
|||
"use strict";
|
||||
|
||||
const printer = require("./printer-estree");
|
||||
|
||||
// Based on:
|
||||
// https://github.com/github/linguist/blob/master/lib/linguist/languages.yml
|
||||
|
||||
const languages = [
|
||||
{
|
||||
name: "JavaScript",
|
||||
since: "0.0.0",
|
||||
parsers: ["babylon", "flow"],
|
||||
group: "JavaScript",
|
||||
tmScope: "source.js",
|
||||
aceMode: "javascript",
|
||||
codemirrorMode: "javascript",
|
||||
codemirrorMimeType: "text/javascript",
|
||||
aliases: ["js", "node"],
|
||||
extensions: [
|
||||
".js",
|
||||
"._js",
|
||||
".bones",
|
||||
".es",
|
||||
".es6",
|
||||
".frag",
|
||||
".gs",
|
||||
".jake",
|
||||
".jsb",
|
||||
".jscad",
|
||||
".jsfl",
|
||||
".jsm",
|
||||
".jss",
|
||||
".mjs",
|
||||
".njs",
|
||||
".pac",
|
||||
".sjs",
|
||||
".ssjs",
|
||||
".xsjs",
|
||||
".xsjslib"
|
||||
],
|
||||
filenames: ["Jakefile"],
|
||||
linguistLanguageId: 183,
|
||||
vscodeLanguageIds: ["javascript"]
|
||||
},
|
||||
{
|
||||
name: "JSX",
|
||||
since: "0.0.0",
|
||||
parsers: ["babylon", "flow"],
|
||||
group: "JavaScript",
|
||||
extensions: [".jsx"],
|
||||
tmScope: "source.js.jsx",
|
||||
aceMode: "javascript",
|
||||
codemirrorMode: "jsx",
|
||||
codemirrorMimeType: "text/jsx",
|
||||
liguistLanguageId: 178,
|
||||
vscodeLanguageIds: ["javascriptreact"]
|
||||
},
|
||||
{
|
||||
name: "TypeScript",
|
||||
since: "1.4.0",
|
||||
parsers: ["typescript-eslint"],
|
||||
group: "JavaScript",
|
||||
aliases: ["ts"],
|
||||
extensions: [".ts", ".tsx"],
|
||||
tmScope: "source.ts",
|
||||
aceMode: "typescript",
|
||||
codemirrorMode: "javascript",
|
||||
codemirrorMimeType: "application/typescript",
|
||||
liguistLanguageId: 378,
|
||||
vscodeLanguageIds: ["typescript", "typescriptreact"]
|
||||
},
|
||||
{
|
||||
name: "JSON",
|
||||
since: "1.5.0",
|
||||
parsers: ["json"],
|
||||
group: "JavaScript",
|
||||
tmScope: "source.json",
|
||||
aceMode: "json",
|
||||
codemirrorMode: "javascript",
|
||||
codemirrorMimeType: "application/json",
|
||||
extensions: [
|
||||
".json",
|
||||
".json5",
|
||||
".geojson",
|
||||
".JSON-tmLanguage",
|
||||
".topojson"
|
||||
],
|
||||
filenames: [
|
||||
".arcconfig",
|
||||
".jshintrc",
|
||||
".babelrc",
|
||||
".eslintrc",
|
||||
".prettierrc",
|
||||
"composer.lock",
|
||||
"mcmod.info"
|
||||
],
|
||||
linguistLanguageId: 174,
|
||||
vscodeLanguageIds: ["json", "jsonc"]
|
||||
}
|
||||
];
|
||||
|
||||
const typescript = {
|
||||
get parse() {
|
||||
return eval("require")("./parser-typescript");
|
||||
},
|
||||
astFormat: "estree"
|
||||
};
|
||||
|
||||
const babylon = {
|
||||
get parse() {
|
||||
return eval("require")("./parser-babylon");
|
||||
},
|
||||
astFormat: "estree"
|
||||
};
|
||||
|
||||
const parsers = {
|
||||
babylon,
|
||||
json: babylon,
|
||||
flow: {
|
||||
get parse() {
|
||||
return eval("require")("./parser-flow");
|
||||
},
|
||||
astFormat: "estree"
|
||||
},
|
||||
"typescript-eslint": typescript,
|
||||
// TODO: Delete this in 2.0
|
||||
typescript
|
||||
};
|
||||
|
||||
const printers = {
|
||||
estree: printer
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
languages,
|
||||
parsers,
|
||||
printers
|
||||
};
|
|
@ -1,6 +1,6 @@
|
|||
"use strict";
|
||||
|
||||
const createError = require("./parser-create-error");
|
||||
const createError = require("../common/parser-create-error");
|
||||
|
||||
function parse(text, parsers, opts) {
|
||||
// Inline the require to avoid loading all the JS if we don't use it
|
|
@ -1,7 +1,7 @@
|
|||
"use strict";
|
||||
|
||||
const createError = require("./parser-create-error");
|
||||
const includeShebang = require("./parser-include-shebang");
|
||||
const createError = require("../common/parser-create-error");
|
||||
const includeShebang = require("../common/parser-include-shebang");
|
||||
|
||||
function parse(text /*, parsers, opts*/) {
|
||||
// Fixes Node 4 issue (#1986)
|
|
@ -1,7 +1,7 @@
|
|||
"use strict";
|
||||
|
||||
const createError = require("./parser-create-error");
|
||||
const includeShebang = require("./parser-include-shebang");
|
||||
const createError = require("../common/parser-create-error");
|
||||
const includeShebang = require("../common/parser-include-shebang");
|
||||
|
||||
function parse(text /*, parsers, opts*/) {
|
||||
const jsx = isProbablyJsx(text);
|
|
@ -1,13 +1,14 @@
|
|||
"use strict";
|
||||
|
||||
const assert = require("assert");
|
||||
const comments = require("./comments");
|
||||
const FastPath = require("./fast-path");
|
||||
const multiparser = require("./multiparser");
|
||||
const util = require("./util");
|
||||
// TODO(azz): anything that imports from main shouldn't be in a `language-*` dir.
|
||||
const comments = require("../main/comments");
|
||||
const util = require("../common/util");
|
||||
const isIdentifierName = require("esutils").keyword.isIdentifierNameES6;
|
||||
const embed = require("./embed");
|
||||
|
||||
const docBuilders = require("./doc-builders");
|
||||
const doc = require("../doc");
|
||||
const docBuilders = doc.builders;
|
||||
const concat = docBuilders.concat;
|
||||
const join = docBuilders.join;
|
||||
const line = docBuilders.line;
|
||||
|
@ -24,7 +25,7 @@ const breakParent = docBuilders.breakParent;
|
|||
const lineSuffixBoundary = docBuilders.lineSuffixBoundary;
|
||||
const addAlignmentToDoc = docBuilders.addAlignmentToDoc;
|
||||
|
||||
const docUtils = require("./doc-utils");
|
||||
const docUtils = doc.utils;
|
||||
const willBreak = docUtils.willBreak;
|
||||
const isLineNext = docUtils.isLineNext;
|
||||
const isEmpty = docUtils.isEmpty;
|
||||
|
@ -50,102 +51,10 @@ function shouldPrintComma(options, level) {
|
|||
}
|
||||
}
|
||||
|
||||
function getPrintFunction(options) {
|
||||
switch (options.parser) {
|
||||
case "graphql":
|
||||
return require("./printer-graphql");
|
||||
case "parse5":
|
||||
return require("./printer-htmlparser2");
|
||||
case "vue":
|
||||
return require("./printer-vue");
|
||||
case "css":
|
||||
case "less":
|
||||
case "scss":
|
||||
return require("./printer-postcss");
|
||||
case "markdown":
|
||||
return require("./printer-markdown");
|
||||
default:
|
||||
return genericPrintNoParens;
|
||||
}
|
||||
}
|
||||
|
||||
function hasIgnoreComment(path) {
|
||||
const node = path.getValue();
|
||||
return hasNodeIgnoreComment(node) || hasJsxIgnoreComment(path);
|
||||
}
|
||||
|
||||
function hasNodeIgnoreComment(node) {
|
||||
return (
|
||||
node &&
|
||||
node.comments &&
|
||||
node.comments.length > 0 &&
|
||||
node.comments.some(comment => comment.value.trim() === "prettier-ignore")
|
||||
);
|
||||
}
|
||||
|
||||
function hasJsxIgnoreComment(path) {
|
||||
const node = path.getValue();
|
||||
const parent = path.getParentNode();
|
||||
if (!parent || !node || !isJSXNode(node) || !isJSXNode(parent)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Lookup the previous sibling, ignoring any empty JSXText elements
|
||||
const index = parent.children.indexOf(node);
|
||||
let prevSibling = null;
|
||||
for (let i = index; i > 0; i--) {
|
||||
const candidate = parent.children[i - 1];
|
||||
if (candidate.type === "JSXText" && !isMeaningfulJSXText(candidate)) {
|
||||
continue;
|
||||
}
|
||||
prevSibling = candidate;
|
||||
break;
|
||||
}
|
||||
|
||||
return (
|
||||
prevSibling &&
|
||||
prevSibling.type === "JSXExpressionContainer" &&
|
||||
prevSibling.expression.type === "JSXEmptyExpression" &&
|
||||
prevSibling.expression.comments &&
|
||||
prevSibling.expression.comments.find(
|
||||
comment => comment.value.trim() === "prettier-ignore"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function genericPrint(path, options, printPath, args) {
|
||||
assert.ok(path instanceof FastPath);
|
||||
|
||||
const node = path.getValue();
|
||||
|
||||
// Escape hatch
|
||||
if (hasIgnoreComment(path)) {
|
||||
return options.originalText.slice(util.locStart(node), util.locEnd(node));
|
||||
}
|
||||
|
||||
if (node) {
|
||||
try {
|
||||
// Potentially switch to a different parser
|
||||
const sub = multiparser.printSubtree(path, printPath, options);
|
||||
if (sub) {
|
||||
return sub;
|
||||
}
|
||||
} catch (error) {
|
||||
/* istanbul ignore if */
|
||||
if (process.env.PRETTIER_DEBUG) {
|
||||
throw error;
|
||||
}
|
||||
// Continue with current parser
|
||||
}
|
||||
}
|
||||
|
||||
let needsParens = false;
|
||||
const linesWithoutParens = getPrintFunction(options)(
|
||||
path,
|
||||
options,
|
||||
printPath,
|
||||
args
|
||||
);
|
||||
const linesWithoutParens = printPathNoParens(path, options, printPath, args);
|
||||
|
||||
if (!node || isEmpty(linesWithoutParens)) {
|
||||
return linesWithoutParens;
|
||||
|
@ -226,7 +135,41 @@ function genericPrint(path, options, printPath, args) {
|
|||
return concat(parts);
|
||||
}
|
||||
|
||||
function genericPrintNoParens(path, options, print, args) {
|
||||
function hasPrettierIgnore(path) {
|
||||
return util.hasIgnoreComment(path) || hasJsxIgnoreComment(path);
|
||||
}
|
||||
|
||||
function hasJsxIgnoreComment(path) {
|
||||
const node = path.getValue();
|
||||
const parent = path.getParentNode();
|
||||
if (!parent || !node || !isJSXNode(node) || !isJSXNode(parent)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Lookup the previous sibling, ignoring any empty JSXText elements
|
||||
const index = parent.children.indexOf(node);
|
||||
let prevSibling = null;
|
||||
for (let i = index; i > 0; i--) {
|
||||
const candidate = parent.children[i - 1];
|
||||
if (candidate.type === "JSXText" && !isMeaningfulJSXText(candidate)) {
|
||||
continue;
|
||||
}
|
||||
prevSibling = candidate;
|
||||
break;
|
||||
}
|
||||
|
||||
return (
|
||||
prevSibling &&
|
||||
prevSibling.type === "JSXExpressionContainer" &&
|
||||
prevSibling.expression.type === "JSXEmptyExpression" &&
|
||||
prevSibling.expression.comments &&
|
||||
prevSibling.expression.comments.find(
|
||||
comment => comment.value.trim() === "prettier-ignore"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function printPathNoParens(path, options, print, args) {
|
||||
const n = path.getValue();
|
||||
const semi = options.semi ? ";" : "";
|
||||
|
||||
|
@ -988,8 +931,8 @@ function genericPrintNoParens(path, options, print, args) {
|
|||
const result = concat(separatorParts.concat(group(prop.printed)));
|
||||
separatorParts = [separator, line];
|
||||
if (
|
||||
hasNodeIgnoreComment(prop.node) &&
|
||||
prop.node.type === "TSPropertySignature"
|
||||
prop.node.type === "TSPropertySignature" &&
|
||||
util.hasNodeIgnoreComment(prop.node)
|
||||
) {
|
||||
separatorParts.shift();
|
||||
}
|
||||
|
@ -1006,7 +949,7 @@ function genericPrintNoParens(path, options, print, args) {
|
|||
(lastElem.type === "RestProperty" ||
|
||||
lastElem.type === "RestElement" ||
|
||||
lastElem.type === "ExperimentalRestProperty" ||
|
||||
hasNodeIgnoreComment(lastElem))
|
||||
util.hasNodeIgnoreComment(lastElem))
|
||||
);
|
||||
|
||||
let content;
|
||||
|
@ -4765,7 +4708,7 @@ function hasTrailingComment(node) {
|
|||
|
||||
function hasLeadingOwnLineComment(text, node) {
|
||||
if (isJSXNode(node)) {
|
||||
return hasNodeIgnoreComment(node);
|
||||
return util.hasNodeIgnoreComment(node);
|
||||
}
|
||||
|
||||
const res =
|
||||
|
@ -5190,71 +5133,6 @@ function isTestCall(n) {
|
|||
);
|
||||
}
|
||||
|
||||
function printAstToDoc(ast, options, addAlignmentSize) {
|
||||
addAlignmentSize = addAlignmentSize || 0;
|
||||
|
||||
const cache = new Map();
|
||||
|
||||
function printGenerically(path, args) {
|
||||
const node = path.getValue();
|
||||
|
||||
const shouldCache = node && typeof node === "object" && args === undefined;
|
||||
if (shouldCache && cache.has(node)) {
|
||||
return cache.get(node);
|
||||
}
|
||||
|
||||
const parent = path.getParentNode(0);
|
||||
// We let JSXElement print its comments itself because it adds () around
|
||||
// UnionTypeAnnotation has to align the child without the comments
|
||||
let res;
|
||||
if (
|
||||
((node && isJSXNode(node)) ||
|
||||
(parent &&
|
||||
(parent.type === "JSXSpreadAttribute" ||
|
||||
parent.type === "JSXSpreadChild" ||
|
||||
parent.type === "UnionTypeAnnotation" ||
|
||||
parent.type === "TSUnionType" ||
|
||||
((parent.type === "ClassDeclaration" ||
|
||||
parent.type === "ClassExpression") &&
|
||||
parent.superClass === node)))) &&
|
||||
!hasIgnoreComment(path)
|
||||
) {
|
||||
res = genericPrint(path, options, printGenerically, args);
|
||||
} else {
|
||||
res = comments.printComments(
|
||||
path,
|
||||
p => genericPrint(p, options, printGenerically, args),
|
||||
options,
|
||||
args && args.needsSemi
|
||||
);
|
||||
}
|
||||
|
||||
if (shouldCache) {
|
||||
cache.set(node, res);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
let doc = printGenerically(new FastPath(ast));
|
||||
if (addAlignmentSize > 0) {
|
||||
// Add a hardline to make the indents take effect
|
||||
// It should be removed in index.js format()
|
||||
doc = addAlignmentToDoc(
|
||||
docUtils.removeLines(concat([hardline, doc])),
|
||||
addAlignmentSize,
|
||||
options.tabWidth
|
||||
);
|
||||
}
|
||||
docUtils.propagateBreaks(doc);
|
||||
|
||||
if (options.parser === "json") {
|
||||
doc = concat([doc, hardline]);
|
||||
}
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
||||
function isTheOnlyJSXElementInMarkdown(options, path) {
|
||||
if (options.parentParser !== "markdown") {
|
||||
return false;
|
||||
|
@ -5271,4 +5149,27 @@ function isTheOnlyJSXElementInMarkdown(options, path) {
|
|||
return parent.type === "Program" && parent.body.length == 1;
|
||||
}
|
||||
|
||||
module.exports = { printAstToDoc };
|
||||
function willPrintOwnComments(path) {
|
||||
const node = path.getValue();
|
||||
const parent = path.getParentNode();
|
||||
|
||||
return (
|
||||
((node && isJSXNode(node)) ||
|
||||
(parent &&
|
||||
(parent.type === "JSXSpreadAttribute" ||
|
||||
parent.type === "JSXSpreadChild" ||
|
||||
parent.type === "UnionTypeAnnotation" ||
|
||||
parent.type === "TSUnionType" ||
|
||||
((parent.type === "ClassDeclaration" ||
|
||||
parent.type === "ClassExpression") &&
|
||||
parent.superClass === node)))) &&
|
||||
!util.hasIgnoreComment(path)
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
print: genericPrint,
|
||||
embed,
|
||||
hasPrettierIgnore,
|
||||
willPrintOwnComments
|
||||
};
|
|
@ -0,0 +1,43 @@
|
|||
"use strict";
|
||||
|
||||
const util = require("../common/util");
|
||||
const support = require("../common/support");
|
||||
const doc = require("../doc");
|
||||
const docBuilders = doc.builders;
|
||||
const hardline = docBuilders.hardline;
|
||||
const concat = docBuilders.concat;
|
||||
|
||||
function embed(path, print, textToDoc, options) {
|
||||
const node = path.getValue();
|
||||
|
||||
if (node.type === "code") {
|
||||
const parser = getParserName(node.lang);
|
||||
if (parser) {
|
||||
const styleUnit = options.__inJsTemplate ? "~" : "`";
|
||||
const style = styleUnit.repeat(
|
||||
Math.max(3, util.getMaxContinuousCount(node.value, styleUnit) + 1)
|
||||
);
|
||||
const doc = textToDoc(node.value, { parser });
|
||||
return concat([style, node.lang, hardline, doc, style]);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
function getParserName(lang) {
|
||||
const supportInfo = support.getSupportInfo(undefined, options);
|
||||
const language = supportInfo.languages.find(
|
||||
language =>
|
||||
language.name.toLowerCase() === lang ||
|
||||
(language.extensions &&
|
||||
language.extensions.find(ext => ext.substring(1) === lang))
|
||||
);
|
||||
if (language) {
|
||||
return language.parsers[0];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = embed;
|
|
@ -0,0 +1,57 @@
|
|||
"use strict";
|
||||
|
||||
const printer = require("./printer-markdown");
|
||||
|
||||
// Based on:
|
||||
// https://github.com/github/linguist/blob/master/lib/linguist/languages.yml
|
||||
|
||||
const languages = [
|
||||
{
|
||||
name: "Markdown",
|
||||
since: "1.8.0",
|
||||
parsers: ["remark"],
|
||||
aliases: ["pandoc"],
|
||||
aceMode: "markdown",
|
||||
codemirrorMode: "gfm",
|
||||
codemirrorMimeType: "text/x-gfm",
|
||||
wrap: true,
|
||||
extensions: [
|
||||
".md",
|
||||
".markdown",
|
||||
".mdown",
|
||||
".mdwn",
|
||||
".mkd",
|
||||
".mkdn",
|
||||
".mkdown",
|
||||
".ron",
|
||||
".workbook"
|
||||
],
|
||||
filenames: ["README"],
|
||||
tmScope: "source.gfm",
|
||||
linguistLanguageId: 222,
|
||||
vscodeLanguageIds: ["markdown"]
|
||||
}
|
||||
];
|
||||
|
||||
const remark = {
|
||||
get parse() {
|
||||
return eval("require")("./parser-markdown");
|
||||
},
|
||||
astFormat: "mdast"
|
||||
};
|
||||
|
||||
const parsers = {
|
||||
remark,
|
||||
// TODO: Delete this in 2.0
|
||||
markdown: remark
|
||||
};
|
||||
|
||||
const printers = {
|
||||
mdast: printer
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
languages,
|
||||
parsers,
|
||||
printers
|
||||
};
|
|
@ -3,7 +3,7 @@
|
|||
const remarkFrontmatter = require("remark-frontmatter");
|
||||
const remarkParse = require("remark-parse");
|
||||
const unified = require("unified");
|
||||
const util = require("./util");
|
||||
const util = require("../common/util");
|
||||
|
||||
/**
|
||||
* based on [MDAST](https://github.com/syntax-tree/mdast) with following modifications:
|
|
@ -1,7 +1,9 @@
|
|||
"use strict";
|
||||
|
||||
const util = require("./util");
|
||||
const docBuilders = require("./doc-builders");
|
||||
const util = require("../common/util");
|
||||
const embed = require("./embed");
|
||||
const doc = require("../doc");
|
||||
const docBuilders = doc.builders;
|
||||
const concat = docBuilders.concat;
|
||||
const join = docBuilders.join;
|
||||
const line = docBuilders.line;
|
||||
|
@ -9,8 +11,7 @@ const hardline = docBuilders.hardline;
|
|||
const softline = docBuilders.softline;
|
||||
const fill = docBuilders.fill;
|
||||
const align = docBuilders.align;
|
||||
const docPrinter = require("./doc-printer");
|
||||
const printDocToString = docPrinter.printDocToString;
|
||||
const printDocToString = doc.printer.printDocToString;
|
||||
|
||||
const SINGLE_LINE_NODE_TYPES = [
|
||||
"heading",
|
||||
|
@ -657,4 +658,8 @@ function normalizeParts(parts) {
|
|||
}, []);
|
||||
}
|
||||
|
||||
module.exports = genericPrint;
|
||||
module.exports = {
|
||||
print: genericPrint,
|
||||
embed,
|
||||
hasPrettierIgnore: util.hasIgnoreComment
|
||||
};
|
|
@ -0,0 +1,50 @@
|
|||
"use strict";
|
||||
|
||||
const docBuilders = require("../doc").builders;
|
||||
const concat = docBuilders.concat;
|
||||
const hardline = docBuilders.hardline;
|
||||
|
||||
function embed(path, print, textToDoc, options) {
|
||||
const node = path.getValue();
|
||||
const parent = path.getParentNode();
|
||||
if (!parent || parent.tag !== "root") {
|
||||
return null;
|
||||
}
|
||||
|
||||
let parser;
|
||||
|
||||
if (node.tag === "style") {
|
||||
const langAttr = node.attrs.find(attr => attr.name === "lang");
|
||||
if (!langAttr) {
|
||||
parser = "css";
|
||||
} else if (langAttr.value === "scss") {
|
||||
parser = "scss";
|
||||
} else if (langAttr.value === "less") {
|
||||
parser = "less";
|
||||
}
|
||||
}
|
||||
|
||||
if (node.tag === "script") {
|
||||
const langAttr = node.attrs.find(attr => attr.name === "lang");
|
||||
if (!langAttr) {
|
||||
parser = "babylon";
|
||||
} else if (langAttr.value === "ts") {
|
||||
parser = "typescript";
|
||||
}
|
||||
}
|
||||
|
||||
if (!parser) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return concat([
|
||||
options.originalText.slice(node.start, node.contentStart),
|
||||
hardline,
|
||||
textToDoc(options.originalText.slice(node.contentStart, node.contentEnd), {
|
||||
parser
|
||||
}),
|
||||
options.originalText.slice(node.contentEnd, node.end)
|
||||
]);
|
||||
}
|
||||
|
||||
module.exports = embed;
|
|
@ -0,0 +1,41 @@
|
|||
"use strict";
|
||||
|
||||
const printer = require("./printer-vue");
|
||||
|
||||
// Based on:
|
||||
// https://github.com/github/linguist/blob/master/lib/linguist/languages.yml
|
||||
|
||||
const languages = [
|
||||
{
|
||||
name: "Vue",
|
||||
since: "1.10.0",
|
||||
parsers: ["vue"],
|
||||
group: "HTML",
|
||||
tmScope: "text.html.vue",
|
||||
aceMode: "html",
|
||||
codemirrorMode: "htmlmixed",
|
||||
codemirrorMimeType: "text/html",
|
||||
extensions: [".vue"],
|
||||
linguistLanguageId: 146,
|
||||
vscodeLanguageIds: ["vue"]
|
||||
}
|
||||
];
|
||||
|
||||
const parsers = {
|
||||
vue: {
|
||||
get parse() {
|
||||
return eval("require")("./parser-vue");
|
||||
},
|
||||
astFormat: "vue"
|
||||
}
|
||||
};
|
||||
|
||||
const printers = {
|
||||
vue: printer
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
languages,
|
||||
parsers,
|
||||
printers
|
||||
};
|
|
@ -1,6 +1,7 @@
|
|||
"use strict";
|
||||
|
||||
const docBuilders = require("./doc-builders");
|
||||
const embed = require("./embed");
|
||||
const docBuilders = require("../doc").builders;
|
||||
const concat = docBuilders.concat;
|
||||
|
||||
function genericPrint(path, options, print) {
|
||||
|
@ -19,4 +20,7 @@ function genericPrint(path, options, print) {
|
|||
return concat(res);
|
||||
}
|
||||
|
||||
module.exports = genericPrint;
|
||||
module.exports = {
|
||||
print: genericPrint,
|
||||
embed
|
||||
};
|
|
@ -0,0 +1,100 @@
|
|||
"use strict";
|
||||
|
||||
const assert = require("assert");
|
||||
const comments = require("./comments");
|
||||
const FastPath = require("../common/fast-path");
|
||||
const multiparser = require("./multiparser");
|
||||
const util = require("../common/util");
|
||||
|
||||
const doc = require("../doc");
|
||||
const docBuilders = doc.builders;
|
||||
const concat = docBuilders.concat;
|
||||
const hardline = docBuilders.hardline;
|
||||
const addAlignmentToDoc = docBuilders.addAlignmentToDoc;
|
||||
const docUtils = doc.utils;
|
||||
const getPrinter = require("./get-printer");
|
||||
|
||||
function printAstToDoc(ast, options, addAlignmentSize) {
|
||||
addAlignmentSize = addAlignmentSize || 0;
|
||||
|
||||
const printer = getPrinter(options);
|
||||
const cache = new Map();
|
||||
|
||||
function printGenerically(path, args) {
|
||||
const node = path.getValue();
|
||||
|
||||
const shouldCache = node && typeof node === "object" && args === undefined;
|
||||
if (shouldCache && cache.has(node)) {
|
||||
return cache.get(node);
|
||||
}
|
||||
|
||||
// We let JSXElement print its comments itself because it adds () around
|
||||
// UnionTypeAnnotation has to align the child without the comments
|
||||
let res;
|
||||
if (printer.willPrintOwnComments && printer.willPrintOwnComments(path)) {
|
||||
res = genericPrint(path, options, printer, printGenerically, args);
|
||||
} else {
|
||||
res = comments.printComments(
|
||||
path,
|
||||
p => genericPrint(p, options, printer, printGenerically, args),
|
||||
options,
|
||||
args && args.needsSemi
|
||||
);
|
||||
}
|
||||
|
||||
if (shouldCache) {
|
||||
cache.set(node, res);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
let doc = printGenerically(new FastPath(ast));
|
||||
if (addAlignmentSize > 0) {
|
||||
// Add a hardline to make the indents take effect
|
||||
// It should be removed in index.js format()
|
||||
doc = addAlignmentToDoc(
|
||||
docUtils.removeLines(concat([hardline, doc])),
|
||||
addAlignmentSize,
|
||||
options.tabWidth
|
||||
);
|
||||
}
|
||||
docUtils.propagateBreaks(doc);
|
||||
|
||||
if (options.parser === "json") {
|
||||
doc = concat([doc, hardline]);
|
||||
}
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
||||
function genericPrint(path, options, printer, printPath, args) {
|
||||
assert.ok(path instanceof FastPath);
|
||||
|
||||
const node = path.getValue();
|
||||
|
||||
// Escape hatch
|
||||
if (printer.hasPrettierIgnore && printer.hasPrettierIgnore(path)) {
|
||||
return options.originalText.slice(util.locStart(node), util.locEnd(node));
|
||||
}
|
||||
|
||||
if (node) {
|
||||
try {
|
||||
// Potentially switch to a different parser
|
||||
const sub = multiparser.printSubtree(printer, path, printPath, options);
|
||||
if (sub) {
|
||||
return sub;
|
||||
}
|
||||
} catch (error) {
|
||||
/* istanbul ignore if */
|
||||
if (process.env.PRETTIER_DEBUG) {
|
||||
throw error;
|
||||
}
|
||||
// Continue with current parser
|
||||
}
|
||||
}
|
||||
|
||||
return printer.print(path, options, printPath, args);
|
||||
}
|
||||
|
||||
module.exports = printAstToDoc;
|
|
@ -1,7 +1,7 @@
|
|||
"use strict";
|
||||
|
||||
const assert = require("assert");
|
||||
const docBuilders = require("./doc-builders");
|
||||
const docBuilders = require("../doc").builders;
|
||||
const concat = docBuilders.concat;
|
||||
const hardline = docBuilders.hardline;
|
||||
const breakParent = docBuilders.breakParent;
|
||||
|
@ -9,7 +9,7 @@ const indent = docBuilders.indent;
|
|||
const lineSuffix = docBuilders.lineSuffix;
|
||||
const join = docBuilders.join;
|
||||
const cursor = docBuilders.cursor;
|
||||
const util = require("./util");
|
||||
const util = require("../common/util");
|
||||
const childNodesCacheKey = Symbol("child-nodes");
|
||||
const locStart = util.locStart;
|
||||
const locEnd = util.locEnd;
|
|
@ -0,0 +1,20 @@
|
|||
"use strict";
|
||||
|
||||
const loadPlugins = require("../common/load-plugins");
|
||||
const parser = require("./parser");
|
||||
|
||||
function getPrinter(options) {
|
||||
const plugins = loadPlugins(options);
|
||||
const parsers = parser.getParsers(plugins, options);
|
||||
const astFormat = parser.resolveParser(parsers, options).astFormat;
|
||||
const printerPlugin = plugins.find(plugin => plugin.printers[astFormat]);
|
||||
if (!printerPlugin) {
|
||||
throw new Error(
|
||||
`Couldn't find printer plugin for AST format "${astFormat}"`
|
||||
);
|
||||
}
|
||||
|
||||
return printerPlugin.printers[astFormat];
|
||||
}
|
||||
|
||||
module.exports = getPrinter;
|
|
@ -0,0 +1,35 @@
|
|||
"use strict";
|
||||
|
||||
const comments = require("./comments");
|
||||
|
||||
function printSubtree(printer, path, print, options) {
|
||||
if (printer.embed) {
|
||||
return printer.embed(
|
||||
path,
|
||||
print,
|
||||
(text, partialNextOptions) =>
|
||||
textToDoc(text, partialNextOptions, options),
|
||||
options
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function textToDoc(text, partialNextOptions, parentOptions) {
|
||||
const nextOptions = Object.assign({}, parentOptions, partialNextOptions, {
|
||||
parentParser: parentOptions.parser,
|
||||
originalText: text
|
||||
});
|
||||
if (nextOptions.parser === "json") {
|
||||
nextOptions.trailingComma = "none";
|
||||
}
|
||||
|
||||
const ast = require("./parser").parse(text, nextOptions);
|
||||
const astComments = ast.comments;
|
||||
delete ast.comments;
|
||||
comments.attach(astComments, ast, text, nextOptions);
|
||||
return require("./ast-to-doc")(ast, nextOptions);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
printSubtree
|
||||
};
|
|
@ -0,0 +1,78 @@
|
|||
"use strict";
|
||||
|
||||
const path = require("path");
|
||||
const ConfigError = require("../common/errors").ConfigError;
|
||||
const loadPlugins = require("../common/load-plugins");
|
||||
|
||||
function getParsers(plugins) {
|
||||
return plugins.reduce(
|
||||
(parsers, plugin) => Object.assign({}, parsers, plugin.parsers),
|
||||
{}
|
||||
);
|
||||
}
|
||||
|
||||
function resolveParser(parsers, opts) {
|
||||
if (typeof opts.parser === "function") {
|
||||
// Custom parser API always works with JavaScript.
|
||||
return {
|
||||
parse: opts.parser,
|
||||
astFormat: "estree"
|
||||
};
|
||||
}
|
||||
|
||||
if (typeof opts.parser === "string") {
|
||||
if (parsers.hasOwnProperty(opts.parser)) {
|
||||
return parsers[opts.parser];
|
||||
}
|
||||
try {
|
||||
return {
|
||||
parse: eval("require")(path.resolve(process.cwd(), opts.parser)),
|
||||
astFormat: "estree"
|
||||
};
|
||||
} catch (err) {
|
||||
/* istanbul ignore next */
|
||||
throw new ConfigError(`Couldn't resolve parser "${opts.parser}"`);
|
||||
}
|
||||
}
|
||||
/* istanbul ignore next */
|
||||
return parsers.babylon;
|
||||
}
|
||||
|
||||
function parse(text, opts) {
|
||||
const parsers = getParsers(loadPlugins(opts), 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.
|
||||
const parsersForCustomParserApi = Object.keys(parsers).reduce(
|
||||
(object, parserName) =>
|
||||
Object.defineProperty(
|
||||
object,
|
||||
parserName,
|
||||
Object.getOwnPropertyDescriptor(parsers[parserName], "parse")
|
||||
),
|
||||
{}
|
||||
);
|
||||
|
||||
const parser = resolveParser(parsers, opts);
|
||||
|
||||
try {
|
||||
return parser.parse(text, parsersForCustomParserApi, opts);
|
||||
} catch (error) {
|
||||
const loc = error.loc;
|
||||
|
||||
if (loc) {
|
||||
const codeFrame = require("@babel/code-frame");
|
||||
error.codeFrame = codeFrame.codeFrameColumns(text, loc, {
|
||||
highlightCode: true
|
||||
});
|
||||
error.message += "\n" + error.codeFrame;
|
||||
throw error;
|
||||
}
|
||||
|
||||
/* istanbul ignore next */
|
||||
throw error.stack;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { getParsers, parse, resolveParser };
|
|
@ -1,83 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
const path = require("path");
|
||||
const ConfigError = require("./errors").ConfigError;
|
||||
|
||||
const parsers = {
|
||||
get flow() {
|
||||
return eval("require")("./parser-flow");
|
||||
},
|
||||
get graphql() {
|
||||
return eval("require")("./parser-graphql");
|
||||
},
|
||||
get parse5() {
|
||||
return eval("require")("./parser-parse5");
|
||||
},
|
||||
get babylon() {
|
||||
return eval("require")("./parser-babylon");
|
||||
},
|
||||
get typescript() {
|
||||
return eval("require")("./parser-typescript");
|
||||
},
|
||||
get css() {
|
||||
return eval("require")("./parser-postcss");
|
||||
},
|
||||
get less() {
|
||||
return eval("require")("./parser-postcss");
|
||||
},
|
||||
get scss() {
|
||||
return eval("require")("./parser-postcss");
|
||||
},
|
||||
get json() {
|
||||
return eval("require")("./parser-babylon");
|
||||
},
|
||||
get markdown() {
|
||||
return eval("require")("./parser-markdown");
|
||||
},
|
||||
get vue() {
|
||||
return eval("require")("./parser-vue");
|
||||
}
|
||||
};
|
||||
|
||||
function resolveParseFunction(opts) {
|
||||
if (typeof opts.parser === "function") {
|
||||
return opts.parser;
|
||||
}
|
||||
if (typeof opts.parser === "string") {
|
||||
if (parsers.hasOwnProperty(opts.parser)) {
|
||||
return parsers[opts.parser];
|
||||
}
|
||||
try {
|
||||
return eval("require")(path.resolve(process.cwd(), opts.parser));
|
||||
} catch (err) {
|
||||
/* istanbul ignore next */
|
||||
throw new ConfigError(`Couldn't resolve parser "${opts.parser}"`);
|
||||
}
|
||||
}
|
||||
/* istanbul ignore next */
|
||||
return parsers.babylon;
|
||||
}
|
||||
|
||||
function parse(text, opts) {
|
||||
const parseFunction = resolveParseFunction(opts);
|
||||
|
||||
try {
|
||||
return parseFunction(text, parsers, opts);
|
||||
} catch (error) {
|
||||
const loc = error.loc;
|
||||
|
||||
if (loc) {
|
||||
const codeFrame = require("@babel/code-frame");
|
||||
error.codeFrame = codeFrame.codeFrameColumns(text, loc, {
|
||||
highlightCode: true
|
||||
});
|
||||
error.message += "\n" + error.codeFrame;
|
||||
throw error;
|
||||
}
|
||||
|
||||
/* istanbul ignore next */
|
||||
throw error.stack;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { parse };
|
229
src/support.js
229
src/support.js
|
@ -1,229 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
const semver = require("semver");
|
||||
const currentVersion = require("../package.json").version;
|
||||
|
||||
// Based on:
|
||||
// https://github.com/github/linguist/blob/master/lib/linguist/languages.yml
|
||||
|
||||
const supportTable = [
|
||||
{
|
||||
name: "JavaScript",
|
||||
since: "0.0.0",
|
||||
parsers: ["babylon", "flow"],
|
||||
group: "JavaScript",
|
||||
tmScope: "source.js",
|
||||
aceMode: "javascript",
|
||||
codemirrorMode: "javascript",
|
||||
codemirrorMimeType: "text/javascript",
|
||||
aliases: ["js", "node"],
|
||||
extensions: [
|
||||
".js",
|
||||
"._js",
|
||||
".bones",
|
||||
".es",
|
||||
".es6",
|
||||
".frag",
|
||||
".gs",
|
||||
".jake",
|
||||
".jsb",
|
||||
".jscad",
|
||||
".jsfl",
|
||||
".jsm",
|
||||
".jss",
|
||||
".mjs",
|
||||
".njs",
|
||||
".pac",
|
||||
".sjs",
|
||||
".ssjs",
|
||||
".xsjs",
|
||||
".xsjslib"
|
||||
],
|
||||
filenames: ["Jakefile"],
|
||||
linguistLanguageId: 183,
|
||||
vscodeLanguageIds: ["javascript"]
|
||||
},
|
||||
{
|
||||
name: "JSX",
|
||||
since: "0.0.0",
|
||||
parsers: ["babylon", "flow"],
|
||||
group: "JavaScript",
|
||||
extensions: [".jsx"],
|
||||
tmScope: "source.js.jsx",
|
||||
aceMode: "javascript",
|
||||
codemirrorMode: "jsx",
|
||||
codemirrorMimeType: "text/jsx",
|
||||
liguistLanguageId: 178,
|
||||
vscodeLanguageIds: ["javascriptreact"]
|
||||
},
|
||||
{
|
||||
name: "TypeScript",
|
||||
since: "1.4.0",
|
||||
parsers: ["typescript"],
|
||||
group: "JavaScript",
|
||||
aliases: ["ts"],
|
||||
extensions: [".ts", ".tsx"],
|
||||
tmScope: "source.ts",
|
||||
aceMode: "typescript",
|
||||
codemirrorMode: "javascript",
|
||||
codemirrorMimeType: "application/typescript",
|
||||
liguistLanguageId: 378,
|
||||
vscodeLanguageIds: ["typescript", "typescriptreact"]
|
||||
},
|
||||
{
|
||||
name: "CSS",
|
||||
since: "1.4.0",
|
||||
parsers: ["css"],
|
||||
group: "CSS",
|
||||
tmScope: "source.css",
|
||||
aceMode: "css",
|
||||
codemirrorMode: "css",
|
||||
codemirrorMimeType: "text/css",
|
||||
extensions: [".css", ".pcss", ".postcss"],
|
||||
liguistLanguageId: 50,
|
||||
vscodeLanguageIds: ["css", "postcss"]
|
||||
},
|
||||
{
|
||||
name: "Less",
|
||||
since: "1.4.0",
|
||||
parsers: ["less"],
|
||||
group: "CSS",
|
||||
extensions: [".less"],
|
||||
tmScope: "source.css.less",
|
||||
aceMode: "less",
|
||||
codemirrorMode: "css",
|
||||
codemirrorMimeType: "text/css",
|
||||
liguistLanguageId: 198,
|
||||
vscodeLanguageIds: ["less"]
|
||||
},
|
||||
{
|
||||
name: "SCSS",
|
||||
since: "1.4.0",
|
||||
parsers: ["scss"],
|
||||
group: "CSS",
|
||||
tmScope: "source.scss",
|
||||
aceMode: "scss",
|
||||
codemirrorMode: "css",
|
||||
codemirrorMimeType: "text/x-scss",
|
||||
extensions: [".scss"],
|
||||
liguistLanguageId: 329,
|
||||
vscodeLanguageIds: ["scss"]
|
||||
},
|
||||
{
|
||||
name: "GraphQL",
|
||||
since: "1.5.0",
|
||||
parsers: ["graphql"],
|
||||
extensions: [".graphql", ".gql"],
|
||||
tmScope: "source.graphql",
|
||||
aceMode: "text",
|
||||
liguistLanguageId: 139,
|
||||
vscodeLanguageIds: ["graphql"]
|
||||
},
|
||||
{
|
||||
name: "JSON",
|
||||
since: "1.5.0",
|
||||
parsers: ["json"],
|
||||
group: "JavaScript",
|
||||
tmScope: "source.json",
|
||||
aceMode: "json",
|
||||
codemirrorMode: "javascript",
|
||||
codemirrorMimeType: "application/json",
|
||||
extensions: [
|
||||
".json",
|
||||
".json5",
|
||||
".geojson",
|
||||
".JSON-tmLanguage",
|
||||
".topojson"
|
||||
],
|
||||
filenames: [
|
||||
".arcconfig",
|
||||
".jshintrc",
|
||||
".babelrc",
|
||||
".eslintrc",
|
||||
".prettierrc",
|
||||
"composer.lock",
|
||||
"mcmod.info"
|
||||
],
|
||||
linguistLanguageId: 174,
|
||||
vscodeLanguageIds: ["json", "jsonc"]
|
||||
},
|
||||
|
||||
{
|
||||
name: "Markdown",
|
||||
since: "1.8.0",
|
||||
parsers: ["markdown"],
|
||||
aliases: ["pandoc"],
|
||||
aceMode: "markdown",
|
||||
codemirrorMode: "gfm",
|
||||
codemirrorMimeType: "text/x-gfm",
|
||||
wrap: true,
|
||||
extensions: [
|
||||
".md",
|
||||
".markdown",
|
||||
".mdown",
|
||||
".mdwn",
|
||||
".mkd",
|
||||
".mkdn",
|
||||
".mkdown",
|
||||
".ron",
|
||||
".workbook"
|
||||
],
|
||||
filenames: ["README"],
|
||||
tmScope: "source.gfm",
|
||||
linguistLanguageId: 222,
|
||||
vscodeLanguageIds: ["markdown"]
|
||||
},
|
||||
{
|
||||
name: "Vue",
|
||||
since: "1.10.0",
|
||||
parsers: ["vue"],
|
||||
group: "HTML",
|
||||
tmScope: "text.html.vue",
|
||||
aceMode: "html",
|
||||
codemirrorMode: "htmlmixed",
|
||||
codemirrorMimeType: "text/html",
|
||||
extensions: [".vue"],
|
||||
linguistLanguageId: 146,
|
||||
vscodeLanguageIds: ["vue"]
|
||||
},
|
||||
{
|
||||
name: "HTML",
|
||||
since: undefined, // unreleased
|
||||
parsers: ["parse5"],
|
||||
group: "HTML",
|
||||
tmScope: "text.html.basic",
|
||||
aceMode: "html",
|
||||
codemirrorMode: "htmlmixed",
|
||||
codemirrorMimeType: "text/html",
|
||||
aliases: ["xhtml"],
|
||||
extensions: [".html", ".htm", ".html.hl", ".inc", ".st", ".xht", ".xhtml"],
|
||||
linguistLanguageId: 146,
|
||||
vscodeLanguageIds: ["html"]
|
||||
}
|
||||
];
|
||||
|
||||
function getSupportInfo(version) {
|
||||
if (!version) {
|
||||
version = currentVersion;
|
||||
}
|
||||
|
||||
const usePostCssParser = semver.lt(version, "1.7.1");
|
||||
|
||||
const languages = supportTable
|
||||
.filter(language => language.since && semver.gte(version, language.since))
|
||||
.map(language => {
|
||||
if (usePostCssParser && language.group === "CSS") {
|
||||
return Object.assign({}, language, {
|
||||
parsers: ["postcss"]
|
||||
});
|
||||
}
|
||||
return language;
|
||||
});
|
||||
|
||||
return { languages };
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
supportTable,
|
||||
getSupportInfo
|
||||
};
|
|
@ -10,15 +10,10 @@ exports[`template-bind.vue 1`] = `
|
|||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
<template>
|
||||
|
||||
<div v-bind:id=" 'list-' + id ">
|
||||
</div>
|
||||
<div v-bind:id=" rawId | formatId ">
|
||||
</div>
|
||||
<div v-bind:id=" ok ? 'YES' : 'NO' ">
|
||||
</div>
|
||||
<button @click=" foo ( arg, 'string' ) ">
|
||||
</button>
|
||||
<div v-bind:id=" 'list-' + id "></div>
|
||||
<div v-bind:id=" rawId | formatId "></div>
|
||||
<div v-bind:id=" ok ? 'YES' : 'NO' "></div>
|
||||
<button @click=" foo ( arg, 'string' ) "></button>
|
||||
</template>
|
||||
`;
|
||||
|
||||
|
@ -34,14 +29,12 @@ exports[`template-class.vue 1`] = `
|
|||
</template>
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
<template>
|
||||
|
||||
<h2
|
||||
class="title"
|
||||
:class="{ 'issue-realtime-pre-pulse': preAnimation,
|
||||
'issue-realtime-trigger-pulse': pulseAnimation}"
|
||||
v-html="titleHtml"
|
||||
>
|
||||
|
||||
</h2>
|
||||
</template>
|
||||
`;
|
||||
|
@ -66,25 +59,24 @@ p { font-size : 2em ; text-align : center ; }
|
|||
</style >
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
<template >
|
||||
|
||||
<h1 >
|
||||
{{greeting}} world</h1 >
|
||||
<script>
|
||||
kikoo ( ) </script>
|
||||
<h1 >{{greeting}} world</h1 >
|
||||
<script>kikoo ( ) </script>
|
||||
</template >
|
||||
|
||||
<script>
|
||||
|
||||
module . exports =
|
||||
{data : function () {return {
|
||||
greeting: "Hello"
|
||||
}}
|
||||
}
|
||||
module.exports = {
|
||||
data: function() {
|
||||
return {
|
||||
greeting: "Hello"
|
||||
};
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped >
|
||||
|
||||
p { font-size : 2em ; text-align : center ; }
|
||||
|
||||
</style >
|
||||
p {
|
||||
font-size: 2em;
|
||||
text-align: center;
|
||||
}
|
||||
</style >
|
||||
`;
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
const fs = require("fs");
|
||||
const extname = require("path").extname;
|
||||
const prettier = require("./require_prettier");
|
||||
const parser = require("../src/parser");
|
||||
const massageAST = require("../src/clean-ast.js").massageAST;
|
||||
const parser = require("../src/main/parser");
|
||||
const massageAST = require("../src/common/clean-ast.js").massageAST;
|
||||
|
||||
const AST_COMPARE = process.env["AST_COMPARE"];
|
||||
const VERIFY_ALL_PARSERS = process.env["VERIFY_ALL_PARSERS"] || false;
|
||||
|
|
|
@ -288,6 +288,17 @@ Default: babylon
|
|||
|
||||
exports[`show detailed usage with --help parser (write) 1`] = `Array []`;
|
||||
|
||||
exports[`show detailed usage with --help plugin (stderr) 1`] = `""`;
|
||||
|
||||
exports[`show detailed usage with --help plugin (stdout) 1`] = `
|
||||
"--plugin <path>
|
||||
|
||||
Add a plugin. Multiple plugins can be passed as separate \`--plugin\`s.
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`show detailed usage with --help plugin (write) 1`] = `Array []`;
|
||||
|
||||
exports[`show detailed usage with --help print-width (stderr) 1`] = `""`;
|
||||
|
||||
exports[`show detailed usage with --help print-width (stdout) 1`] = `
|
||||
|
@ -553,6 +564,7 @@ Config options:
|
|||
Find and print the path to a configuration file for the given input file.
|
||||
--ignore-path <path> Path to a file with patterns describing files to ignore.
|
||||
Defaults to .prettierignore.
|
||||
--plugin <path> Add a plugin. Multiple plugins can be passed as separate \`--plugin\`s.
|
||||
--with-node-modules Process files inside 'node_modules' directory.
|
||||
|
||||
Editor options:
|
||||
|
@ -693,6 +705,7 @@ Config options:
|
|||
Find and print the path to a configuration file for the given input file.
|
||||
--ignore-path <path> Path to a file with patterns describing files to ignore.
|
||||
Defaults to .prettierignore.
|
||||
--plugin <path> Add a plugin. Multiple plugins can be passed as separate \`--plugin\`s.
|
||||
--with-node-modules Process files inside 'node_modules' directory.
|
||||
|
||||
Editor options:
|
||||
|
|
|
@ -93,6 +93,39 @@ Object {
|
|||
"typescriptreact",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"aceMode": "json",
|
||||
"codemirrorMimeType": "application/json",
|
||||
"codemirrorMode": "javascript",
|
||||
"extensions": Array [
|
||||
".json",
|
||||
".json5",
|
||||
".geojson",
|
||||
".JSON-tmLanguage",
|
||||
".topojson",
|
||||
],
|
||||
"filenames": Array [
|
||||
".arcconfig",
|
||||
".jshintrc",
|
||||
".babelrc",
|
||||
".eslintrc",
|
||||
".prettierrc",
|
||||
"composer.lock",
|
||||
"mcmod.info",
|
||||
],
|
||||
"group": "JavaScript",
|
||||
"linguistLanguageId": 174,
|
||||
"name": "JSON",
|
||||
"parsers": Array [
|
||||
"json",
|
||||
],
|
||||
"since": "1.5.0",
|
||||
"tmScope": "source.json",
|
||||
"vscodeLanguageIds": Array [
|
||||
"json",
|
||||
"jsonc",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"aceMode": "css",
|
||||
"codemirrorMimeType": "text/css",
|
||||
|
@ -170,39 +203,6 @@ Object {
|
|||
"graphql",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"aceMode": "json",
|
||||
"codemirrorMimeType": "application/json",
|
||||
"codemirrorMode": "javascript",
|
||||
"extensions": Array [
|
||||
".json",
|
||||
".json5",
|
||||
".geojson",
|
||||
".JSON-tmLanguage",
|
||||
".topojson",
|
||||
],
|
||||
"filenames": Array [
|
||||
".arcconfig",
|
||||
".jshintrc",
|
||||
".babelrc",
|
||||
".eslintrc",
|
||||
".prettierrc",
|
||||
"composer.lock",
|
||||
"mcmod.info",
|
||||
],
|
||||
"group": "JavaScript",
|
||||
"linguistLanguageId": 174,
|
||||
"name": "JSON",
|
||||
"parsers": Array [
|
||||
"json",
|
||||
],
|
||||
"since": "1.5.0",
|
||||
"tmScope": "source.json",
|
||||
"vscodeLanguageIds": Array [
|
||||
"json",
|
||||
"jsonc",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"aceMode": "markdown",
|
||||
"aliases": Array [
|
||||
|
@ -455,6 +455,34 @@ exports[`CLI --support-info (stdout) 1`] = `
|
|||
\\"liguistLanguageId\\": 378,
|
||||
\\"vscodeLanguageIds\\": [\\"typescript\\", \\"typescriptreact\\"]
|
||||
},
|
||||
{
|
||||
\\"name\\": \\"JSON\\",
|
||||
\\"since\\": \\"1.5.0\\",
|
||||
\\"parsers\\": [\\"json\\"],
|
||||
\\"group\\": \\"JavaScript\\",
|
||||
\\"tmScope\\": \\"source.json\\",
|
||||
\\"aceMode\\": \\"json\\",
|
||||
\\"codemirrorMode\\": \\"javascript\\",
|
||||
\\"codemirrorMimeType\\": \\"application/json\\",
|
||||
\\"extensions\\": [
|
||||
\\".json\\",
|
||||
\\".json5\\",
|
||||
\\".geojson\\",
|
||||
\\".JSON-tmLanguage\\",
|
||||
\\".topojson\\"
|
||||
],
|
||||
\\"filenames\\": [
|
||||
\\".arcconfig\\",
|
||||
\\".jshintrc\\",
|
||||
\\".babelrc\\",
|
||||
\\".eslintrc\\",
|
||||
\\".prettierrc\\",
|
||||
\\"composer.lock\\",
|
||||
\\"mcmod.info\\"
|
||||
],
|
||||
\\"linguistLanguageId\\": 174,
|
||||
\\"vscodeLanguageIds\\": [\\"json\\", \\"jsonc\\"]
|
||||
},
|
||||
{
|
||||
\\"name\\": \\"CSS\\",
|
||||
\\"since\\": \\"1.4.0\\",
|
||||
|
@ -504,34 +532,6 @@ exports[`CLI --support-info (stdout) 1`] = `
|
|||
\\"liguistLanguageId\\": 139,
|
||||
\\"vscodeLanguageIds\\": [\\"graphql\\"]
|
||||
},
|
||||
{
|
||||
\\"name\\": \\"JSON\\",
|
||||
\\"since\\": \\"1.5.0\\",
|
||||
\\"parsers\\": [\\"json\\"],
|
||||
\\"group\\": \\"JavaScript\\",
|
||||
\\"tmScope\\": \\"source.json\\",
|
||||
\\"aceMode\\": \\"json\\",
|
||||
\\"codemirrorMode\\": \\"javascript\\",
|
||||
\\"codemirrorMimeType\\": \\"application/json\\",
|
||||
\\"extensions\\": [
|
||||
\\".json\\",
|
||||
\\".json5\\",
|
||||
\\".geojson\\",
|
||||
\\".JSON-tmLanguage\\",
|
||||
\\".topojson\\"
|
||||
],
|
||||
\\"filenames\\": [
|
||||
\\".arcconfig\\",
|
||||
\\".jshintrc\\",
|
||||
\\".babelrc\\",
|
||||
\\".eslintrc\\",
|
||||
\\".prettierrc\\",
|
||||
\\"composer.lock\\",
|
||||
\\"mcmod.info\\"
|
||||
],
|
||||
\\"linguistLanguageId\\": 174,
|
||||
\\"vscodeLanguageIds\\": [\\"json\\", \\"jsonc\\"]
|
||||
},
|
||||
{
|
||||
\\"name\\": \\"Markdown\\",
|
||||
\\"since\\": \\"1.8.0\\",
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
const prettier = require("../../tests_config/require_prettier");
|
||||
const runPrettier = require("../runPrettier");
|
||||
const constant = require("../../src/cli-constant");
|
||||
const constant = require("../../src/cli/constant");
|
||||
|
||||
describe("show version with --version", () => {
|
||||
runPrettier("cli/with-shebang", ["--version"]).test({
|
||||
|
|
|
@ -3,11 +3,13 @@
|
|||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const stripAnsi = require("strip-ansi");
|
||||
const ENV_LOG_LEVEL = require("../src/cli-logger").ENV_LOG_LEVEL;
|
||||
const ENV_LOG_LEVEL = require("../src/cli/logger").ENV_LOG_LEVEL;
|
||||
|
||||
const isProduction = process.env.NODE_ENV === "production";
|
||||
const prettierCli = isProduction ? "../dist/bin/prettier" : "../bin/prettier";
|
||||
const thirdParty = isProduction ? "../dist/third-party" : "../src/third-party";
|
||||
const thirdParty = isProduction
|
||||
? "../dist/third-party"
|
||||
: "../src/common/third-party";
|
||||
|
||||
function runPrettier(dir, args, options) {
|
||||
args = args || [];
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
"Usage": [
|
||||
"install",
|
||||
"cli",
|
||||
"plugins",
|
||||
"precommit",
|
||||
"watching-files",
|
||||
"eslint",
|
||||
|
|
56
yarn.lock
56
yarn.lock
|
@ -52,6 +52,10 @@ acorn@^5.0.0, acorn@^5.0.1:
|
|||
version "5.0.3"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.0.3.tgz#c460df08491463f028ccb82eab3730bf01087b3d"
|
||||
|
||||
acorn@^5.2.1:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.2.1.tgz#317ac7821826c22c702d66189ab8359675f135d7"
|
||||
|
||||
ajv-keywords@^1.0.0, ajv-keywords@^1.1.1:
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c"
|
||||
|
@ -1635,6 +1639,10 @@ estree-walker@^0.3.0:
|
|||
version "0.3.1"
|
||||
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.3.1.tgz#e6b1a51cf7292524e7237c312e5fe6660c1ce1aa"
|
||||
|
||||
estree-walker@^0.5.0:
|
||||
version "0.5.1"
|
||||
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.5.1.tgz#64fc375053abc6f57d73e9bd2f004644ad3c5854"
|
||||
|
||||
esutils@2.0.2, esutils@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b"
|
||||
|
@ -2921,12 +2929,6 @@ magic-string@^0.16.0:
|
|||
dependencies:
|
||||
vlq "^0.2.1"
|
||||
|
||||
magic-string@^0.19.0:
|
||||
version "0.19.1"
|
||||
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.19.1.tgz#14d768013caf2ec8fdea16a49af82fc377e75201"
|
||||
dependencies:
|
||||
vlq "^0.2.1"
|
||||
|
||||
magic-string@^0.22.4:
|
||||
version "0.22.4"
|
||||
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.22.4.tgz#31039b4e40366395618c1d6cf8193c53917475ff"
|
||||
|
@ -3847,7 +3849,13 @@ resolve@1.1.7:
|
|||
version "1.1.7"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b"
|
||||
|
||||
resolve@^1.1.6, resolve@^1.1.7, resolve@^1.2.0:
|
||||
resolve@1.5.0, resolve@^1.4.0:
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36"
|
||||
dependencies:
|
||||
path-parse "^1.0.5"
|
||||
|
||||
resolve@^1.1.6, resolve@^1.2.0:
|
||||
version "1.3.3"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.3.tgz#655907c3469a8680dc2de3a275a8fdd69691f0e5"
|
||||
dependencies:
|
||||
|
@ -3885,14 +3893,14 @@ ripemd160@^2.0.0, ripemd160@^2.0.1:
|
|||
hash-base "^2.0.0"
|
||||
inherits "^2.0.1"
|
||||
|
||||
rollup-plugin-commonjs@7.0.2:
|
||||
version "7.0.2"
|
||||
resolved "https://registry.yarnpkg.com/rollup-plugin-commonjs/-/rollup-plugin-commonjs-7.0.2.tgz#d8778939570d1cb8c1d02fe62533bc2e454f329a"
|
||||
rollup-plugin-commonjs@8.2.6:
|
||||
version "8.2.6"
|
||||
resolved "https://registry.yarnpkg.com/rollup-plugin-commonjs/-/rollup-plugin-commonjs-8.2.6.tgz#27e5b9069ff94005bb01e01bb46a1e4873784677"
|
||||
dependencies:
|
||||
acorn "^4.0.1"
|
||||
estree-walker "^0.3.0"
|
||||
magic-string "^0.19.0"
|
||||
resolve "^1.1.7"
|
||||
acorn "^5.2.1"
|
||||
estree-walker "^0.5.0"
|
||||
magic-string "^0.22.4"
|
||||
resolve "^1.4.0"
|
||||
rollup-pluginutils "^2.0.1"
|
||||
|
||||
rollup-plugin-json@2.1.1:
|
||||
|
@ -3950,11 +3958,9 @@ rollup-pluginutils@^2.0.1:
|
|||
estree-walker "^0.3.0"
|
||||
micromatch "^2.3.11"
|
||||
|
||||
rollup@0.41.6:
|
||||
version "0.41.6"
|
||||
resolved "https://registry.yarnpkg.com/rollup/-/rollup-0.41.6.tgz#e0d05497877a398c104d816d2733a718a7a94e2a"
|
||||
dependencies:
|
||||
source-map-support "^0.4.0"
|
||||
rollup@0.47.6:
|
||||
version "0.47.6"
|
||||
resolved "https://registry.yarnpkg.com/rollup/-/rollup-0.47.6.tgz#83b90a1890dd3321a3f8d0b2bd216e88483f33de"
|
||||
|
||||
run-async@^2.2.0:
|
||||
version "2.3.0"
|
||||
|
@ -4072,18 +4078,18 @@ source-list-map@^1.1.1:
|
|||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-1.1.2.tgz#9889019d1024cce55cdc069498337ef6186a11a1"
|
||||
|
||||
source-map-support@^0.4.0, source-map-support@^0.4.2:
|
||||
version "0.4.15"
|
||||
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.15.tgz#03202df65c06d2bd8c7ec2362a193056fef8d3b1"
|
||||
dependencies:
|
||||
source-map "^0.5.6"
|
||||
|
||||
source-map-support@^0.4.15:
|
||||
version "0.4.18"
|
||||
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f"
|
||||
dependencies:
|
||||
source-map "^0.5.6"
|
||||
|
||||
source-map-support@^0.4.2:
|
||||
version "0.4.15"
|
||||
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.15.tgz#03202df65c06d2bd8c7ec2362a193056fef8d3b1"
|
||||
dependencies:
|
||||
source-map "^0.5.6"
|
||||
|
||||
source-map@^0.4.4:
|
||||
version "0.4.4"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b"
|
||||
|
|
Loading…
Reference in New Issue