From 1a3248bbc297148f908993d28d887d250ce88407 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Tue, 26 Dec 2017 00:04:02 -0500 Subject: [PATCH 01/12] Change the changelog link to link to prettier/prettier (#3564) * Change the changelog link to link to prettier/prettier * Fix changelog links * Double quotes --- website/static/playground.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/static/playground.js b/website/static/playground.js index 60f5d882..ff287540 100644 --- a/website/static/playground.js +++ b/website/static/playground.js @@ -96,8 +96,8 @@ window.onload = function() { prettierVersion; } else { link.href = - "https://github.com/j-f1/forked-prettier/blob/master/CHANGELOG.md#" + - prettierVersion; + "https://github.com/prettier/prettier/blob/master/CHANGELOG.md#" + + prettierVersion.replace(/\./g, ""); } link.textContent = "v" + prettierVersion; } From 7b211eab24f29148496a885e5d6c87073738710f Mon Sep 17 00:00:00 2001 From: Joseph Frazier <1212jtraceur@gmail.com> Date: Tue, 26 Dec 2017 02:16:09 -0500 Subject: [PATCH 02/12] editorconfig: Only search for .editorconfig up to the VCS directory (#3559) * editorconfig: Only search for .editorconfig up to $PWD This addresses https://github.com/prettier/prettier/issues/3558 I'm not sure if this is the best way to find the "project root", but it seems better than before. * editorconfig: Search for `.editorconfig` up to the VCS directory This uses [find-project-root] to find the nearest directory containing `.git` or `.hg` See here for context: https://github.com/prettier/prettier/pull/3559#issuecomment-353756948 [find-project-root]: https://github.com/kirstein/find-project-root * editorconfig: Add test for finding VCS directory It's a little hacky in that the .hg file isn't really a Mercurial repository, but it's enough to illustrate the intent. See here for context: https://github.com/prettier/prettier/pull/3559#issuecomment-353857109 --- package.json | 2 +- src/config/resolve-config-editorconfig.js | 6 ++++-- .../__snapshots__/config-resolution.js.snap | 10 ++++++++++ .../__snapshots__/with-config-precedence.js.snap | 10 ++++++++++ .../cli/config/editorconfig/repo-root/.hg | 2 ++ .../cli/config/editorconfig/repo-root/file.js | 3 +++ yarn.lock | 14 ++++---------- 7 files changed, 34 insertions(+), 13 deletions(-) create mode 100644 tests_integration/cli/config/editorconfig/repo-root/.hg create mode 100644 tests_integration/cli/config/editorconfig/repo-root/file.js diff --git a/package.json b/package.json index 834d2fb6..395609e2 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "emoji-regex": "6.5.1", "escape-string-regexp": "1.0.5", "esutils": "2.0.2", + "find-project-root": "1.1.1", "flow-parser": "0.59.0", "get-stream": "3.0.0", "globby": "6.1.0", @@ -39,7 +40,6 @@ "minimatch": "3.0.4", "minimist": "1.2.0", "parse5": "3.0.3", - "path-root": "0.1.1", "postcss-less": "1.1.3", "postcss-media-query-parser": "0.2.3", "postcss-scss": "1.0.2", diff --git a/src/config/resolve-config-editorconfig.js b/src/config/resolve-config-editorconfig.js index 26f28aeb..e113469b 100644 --- a/src/config/resolve-config-editorconfig.js +++ b/src/config/resolve-config-editorconfig.js @@ -1,12 +1,14 @@ "use strict"; +const path = require("path"); + const editorconfig = require("editorconfig"); const mem = require("mem"); -const pathRoot = require("path-root"); const editorConfigToPrettier = require("editorconfig-to-prettier"); +const findProjectRoot = require("find-project-root"); const maybeParse = (filePath, config, parse) => { - const root = filePath && pathRoot(filePath); + const root = findProjectRoot(path.dirname(path.resolve(filePath))); return filePath && !config && parse(filePath, { root }); }; diff --git a/tests_integration/__tests__/__snapshots__/config-resolution.js.snap b/tests_integration/__tests__/__snapshots__/config-resolution.js.snap index 7f05743b..ebbb570a 100644 --- a/tests_integration/__tests__/__snapshots__/config-resolution.js.snap +++ b/tests_integration/__tests__/__snapshots__/config-resolution.js.snap @@ -18,6 +18,11 @@ function f() { \\"should have space width 8\\" ) } +function f() { + console.log( + \\"should have space width 2 despite ../.editorconfig specifying 8, because ./.hg is present\\" + ) +} console.log( \\"jest/__best-tests__/file.js should have semi\\" ); @@ -108,6 +113,11 @@ function f() { function f() { console.log(\\"should have space width 8\\") } +function f() { + console.log( + \\"should have space width 2 despite ../.editorconfig specifying 8, because ./.hg is present\\" + ) +} console.log(\\"jest/__best-tests__/file.js should have semi\\"); console.log(\\"jest/Component.js should not have semi\\") console.log(\\"jest/Component.test.js should have semi\\"); diff --git a/tests_integration/__tests__/__snapshots__/with-config-precedence.js.snap b/tests_integration/__tests__/__snapshots__/with-config-precedence.js.snap index 907521e3..b6de0cab 100644 --- a/tests_integration/__tests__/__snapshots__/with-config-precedence.js.snap +++ b/tests_integration/__tests__/__snapshots__/with-config-precedence.js.snap @@ -95,6 +95,11 @@ function f() { \\"should have space width 8\\" ) } +function f() { + console.log( + \\"should have space width 2 despite ../.editorconfig specifying 8, because ./.hg is present\\" + ) +} console.log( \\"jest/__best-tests__/file.js should have semi\\" ); @@ -167,6 +172,11 @@ function f() { \\"should have space width 8\\" ) } +function f() { + console.log( + \\"should have space width 2 despite ../.editorconfig specifying 8, because ./.hg is present\\" + ) +} console.log( \\"jest/__best-tests__/file.js should have semi\\" ); diff --git a/tests_integration/cli/config/editorconfig/repo-root/.hg b/tests_integration/cli/config/editorconfig/repo-root/.hg new file mode 100644 index 00000000..e8eb2dc6 --- /dev/null +++ b/tests_integration/cli/config/editorconfig/repo-root/.hg @@ -0,0 +1,2 @@ +This isn't really a Mercurial repo, but we want to pretend it is for testing purposes. +See https://github.com/prettier/prettier/pull/3559#issuecomment-353857109 diff --git a/tests_integration/cli/config/editorconfig/repo-root/file.js b/tests_integration/cli/config/editorconfig/repo-root/file.js new file mode 100644 index 00000000..0fb15fee --- /dev/null +++ b/tests_integration/cli/config/editorconfig/repo-root/file.js @@ -0,0 +1,3 @@ +function f() { + console.log("should have space width 2 despite ../.editorconfig specifying 8, because ./.hg is present"); +} diff --git a/yarn.lock b/yarn.lock index e01a669d..000e374e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1774,6 +1774,10 @@ fill-range@^2.1.0: repeat-element "^1.1.2" repeat-string "^1.5.2" +find-project-root@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/find-project-root/-/find-project-root-1.1.1.tgz#d242727a2d904725df5714f23dfdcdedda0b6ef8" + find-up@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" @@ -3363,16 +3367,6 @@ path-parse@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" -path-root-regex@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/path-root-regex/-/path-root-regex-0.1.2.tgz#bfccdc8df5b12dc52c8b43ec38d18d72c04ba96d" - -path-root@0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/path-root/-/path-root-0.1.1.tgz#9a4a6814cac1c0cd73360a95f32083c8ea4745b7" - dependencies: - path-root-regex "^0.1.0" - path-to-regexp@^1.0.1: version "1.7.0" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.7.0.tgz#59fde0f435badacba103a84e9d3bc64e96b9937d" From 358984ef0c3daa7db0b3012cfef26467277a3b3e Mon Sep 17 00:00:00 2001 From: Josh Unger Date: Tue, 26 Dec 2017 00:26:09 -0700 Subject: [PATCH 03/12] add an example .prettierrc.js config (#3570) * add an example .prettierrc.js config * Update configuration.md --- docs/configuration.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/configuration.md b/docs/configuration.md index 4a3f7482..3944240a 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -24,6 +24,16 @@ JSON: } ``` +JS: + +```js +// .prettierrc.js +module.exports = { + printWidth: 100, + parser: "flow" +}; +``` + YAML: ```yaml From ee148bfdeda373445ac9b67338cbae3df10a6576 Mon Sep 17 00:00:00 2001 From: Lucas Azzola Date: Wed, 27 Dec 2017 00:04:09 +1100 Subject: [PATCH 04/12] Split up comment printing (#3575) * Split up comment printing * Refactor plugin handling * Allow multiparser to use options normalization * Rename to canAttachComment * Add inline comment * Format code * Use prettier.__debug to get AST --- index.js | 45 +++++++++----- src/cli/util.js | 2 +- src/common/load-plugins.js | 8 ++- src/language-graphql/printer-graphql.js | 19 +++++- src/language-js/printer-estree.js | 70 +++++++++++++++++++++- src/main/ast-to-doc.js | 12 ++-- src/main/comments.js | 78 +++---------------------- src/{common => main}/deprecated.js | 0 src/main/get-printer.js | 15 ++--- src/main/multiparser.js | 20 +++---- src/{common => main}/options.js | 16 ++++- src/main/parser.js | 15 ++--- tests_config/run_spec.js | 3 +- 13 files changed, 182 insertions(+), 121 deletions(-) rename src/{common => main}/deprecated.js (100%) rename src/{common => main}/options.js (86%) diff --git a/index.js b/index.js index ea23ffb0..677e1c21 100644 --- a/index.js +++ b/index.js @@ -1,17 +1,22 @@ "use strict"; -const comments = require("./src/main/comments"); +const docblock = require("jest-docblock"); + const version = require("./package.json").version; -const printAstToDoc = require("./src/main/ast-to-doc"); + const util = require("./src/common/util"); +const getSupportInfo = require("./src/common/support").getSupportInfo; + +const comments = require("./src/main/comments"); +const printAstToDoc = require("./src/main/ast-to-doc"); +const normalizeOptions = require("./src/main/options").normalize; +const parser = require("./src/main/parser"); + +const config = require("./src/config/resolve-config"); + 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) { const index = text.indexOf("\n"); @@ -101,7 +106,7 @@ function formatWithCursor(text, opts, addAlignmentSize) { let cursorOffset; if (opts.cursorOffset >= 0) { - const cursorNodeAndParents = findNodeAtOffset(ast, opts.cursorOffset); + const cursorNodeAndParents = findNodeAtOffset(ast, opts.cursorOffset, opts); const cursorNode = cursorNodeAndParents.node; if (cursorNode) { cursorOffset = opts.cursorOffset - util.locStart(cursorNode); @@ -179,16 +184,21 @@ function findSiblingAncestors(startNodeAndParents, endNodeAndParents) { }; } -function findNodeAtOffset(node, offset, predicate, parentNodes) { +function findNodeAtOffset(node, offset, options, predicate, parentNodes) { predicate = predicate || (() => true); parentNodes = parentNodes || []; const start = util.locStart(node); const end = util.locEnd(node); if (start <= offset && offset <= end) { - for (const childNode of comments.getSortedChildNodes(node)) { + for (const childNode of comments.getSortedChildNodes( + node, + undefined /* text */, + options + )) { const childResult = findNodeAtOffset( childNode, offset, + options, predicate, [node].concat(parentNodes) ); @@ -301,11 +311,17 @@ function calculateRange(text, opts, ast) { } } - const startNodeAndParents = findNodeAtOffset(ast, startNonWhitespace, node => - isSourceElement(opts, node) + const startNodeAndParents = findNodeAtOffset( + ast, + startNonWhitespace, + opts, + node => isSourceElement(opts, node) ); - const endNodeAndParents = findNodeAtOffset(ast, endNonWhitespace, node => - isSourceElement(opts, node) + const endNodeAndParents = findNodeAtOffset( + ast, + endNonWhitespace, + opts, + node => isSourceElement(opts, node) ); if (!startNodeAndParents || !endNodeAndParents) { @@ -398,6 +414,7 @@ module.exports = { /* istanbul ignore next */ __debug: { parse: function(text, opts) { + opts = normalizeOptions(opts); return parser.parse(text, opts); }, formatAST: function(ast, opts) { diff --git a/src/cli/util.js b/src/cli/util.js index 421a6834..ec7df22c 100644 --- a/src/cli/util.js +++ b/src/cli/util.js @@ -16,7 +16,7 @@ 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 apiDefaultOptions = require("../main/options").defaults; const errors = require("../common/errors"); const logger = require("./logger"); const thirdParty = require("../common/third-party"); diff --git a/src/common/load-plugins.js b/src/common/load-plugins.js index 42ef58c2..038050cb 100644 --- a/src/common/load-plugins.js +++ b/src/common/load-plugins.js @@ -12,9 +12,15 @@ function loadPlugins(options) { require("../language-markdown"), require("../language-html"), require("../language-vue") - ]; + ].filter(plugin => { + return options.plugins.indexOf(plugin) < 0; + }); const externalPlugins = options.plugins.map(plugin => { + if (typeof plugin !== "string") { + return plugin; + } + const pluginPath = resolve.sync(plugin, { basedir: process.cwd() }); return eval("require")(pluginPath); }); diff --git a/src/language-graphql/printer-graphql.js b/src/language-graphql/printer-graphql.js index c8615744..53b3cf77 100644 --- a/src/language-graphql/printer-graphql.js +++ b/src/language-graphql/printer-graphql.js @@ -539,7 +539,24 @@ function printSequence(sequencePath, options, print) { }); } +function canAttachComment(node) { + return node.kind && node.kind !== "Comment"; +} + +function printComment(commentPath) { + const comment = commentPath.getValue(); + + switch (comment.kind) { + case "Comment": + return "#" + comment.value.trimRight(); + default: + throw new Error("Not a comment: " + JSON.stringify(comment)); + } +} + module.exports = { print: genericPrint, - hasPrettierIgnore: util.hasIgnoreComment + hasPrettierIgnore: util.hasIgnoreComment, + printComment, + canAttachComment }; diff --git a/src/language-js/printer-estree.js b/src/language-js/printer-estree.js index 27734bd8..5e84516d 100644 --- a/src/language-js/printer-estree.js +++ b/src/language-js/printer-estree.js @@ -5167,9 +5167,77 @@ function willPrintOwnComments(path) { ); } +function canAttachComment(node) { + return ( + node.type && + node.type !== "CommentBlock" && + node.type !== "CommentLine" && + node.type !== "Line" && + node.type !== "Block" && + node.type !== "EmptyStatement" && + node.type !== "TemplateElement" && + node.type !== "Import" && + !(node.callee && node.callee.type === "Import") + ); +} + +function printComment(commentPath, options) { + const comment = commentPath.getValue(); + + switch (comment.type) { + case "CommentBlock": + case "Block": { + if (isJsDocComment(comment)) { + return printJsDocComment(comment); + } + + const isInsideFlowComment = + options.originalText.substr(util.locEnd(comment) - 3, 3) === "*-/"; + + return "/*" + comment.value + (isInsideFlowComment ? "*-/" : "*/"); + } + case "CommentLine": + case "Line": + // Print shebangs with the proper comment characters + if (options.originalText.slice(util.locStart(comment)).startsWith("#!")) { + return "#!" + comment.value.trimRight(); + } + return "//" + comment.value.trimRight(); + default: + throw new Error("Not a comment: " + JSON.stringify(comment)); + } +} + +function isJsDocComment(comment) { + const lines = comment.value.split("\n"); + return ( + lines.length > 1 && + lines.slice(0, lines.length - 1).every(line => line.trim()[0] === "*") + ); +} + +function printJsDocComment(comment) { + const lines = comment.value.split("\n"); + + return concat([ + "/*", + join( + hardline, + lines.map( + (line, index) => + (index > 0 ? " " : "") + + (index < lines.length - 1 ? line.trim() : line.trimLeft()) + ) + ), + "*/" + ]); +} + module.exports = { print: genericPrint, embed, hasPrettierIgnore, - willPrintOwnComments + willPrintOwnComments, + canAttachComment, + printComment }; diff --git a/src/main/ast-to-doc.js b/src/main/ast-to-doc.js index d4f333cf..7ebaa540 100644 --- a/src/main/ast-to-doc.js +++ b/src/main/ast-to-doc.js @@ -12,12 +12,11 @@ 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 printer = options.printer; const cache = new Map(); function printGenerically(path, args) { @@ -32,11 +31,11 @@ function printAstToDoc(ast, options, addAlignmentSize) { // UnionTypeAnnotation has to align the child without the comments let res; if (printer.willPrintOwnComments && printer.willPrintOwnComments(path)) { - res = genericPrint(path, options, printer, printGenerically, args); + res = genericPrint(path, options, printGenerically, args); } else { res = comments.printComments( path, - p => genericPrint(p, options, printer, printGenerically, args), + p => genericPrint(p, options, printGenerically, args), options, args && args.needsSemi ); @@ -68,10 +67,11 @@ function printAstToDoc(ast, options, addAlignmentSize) { return doc; } -function genericPrint(path, options, printer, printPath, args) { +function genericPrint(path, options, printPath, args) { assert.ok(path instanceof FastPath); const node = path.getValue(); + const printer = options.printer; // Escape hatch if (printer.hasPrettierIgnore && printer.hasPrettierIgnore(path)) { @@ -81,7 +81,7 @@ function genericPrint(path, options, printer, printPath, args) { if (node) { try { // Potentially switch to a different parser - const sub = multiparser.printSubtree(printer, path, printPath, options); + const sub = multiparser.printSubtree(path, printPath, options); if (sub) { return sub; } diff --git a/src/main/comments.js b/src/main/comments.js index 5c2e1d31..ad2fe68d 100644 --- a/src/main/comments.js +++ b/src/main/comments.js @@ -18,25 +18,14 @@ const getNextNonSpaceNonCommentCharacter = const getNextNonSpaceNonCommentCharacterIndex = util.getNextNonSpaceNonCommentCharacterIndex; -function getSortedChildNodes(node, text, resultArray) { +function getSortedChildNodes(node, text, options, resultArray) { if (!node) { return; } + const printer = options.printer; if (resultArray) { - if ( - node && - ((node.type && - node.type !== "CommentBlock" && - node.type !== "CommentLine" && - node.type !== "Line" && - node.type !== "Block" && - node.type !== "EmptyStatement" && - node.type !== "TemplateElement" && - node.type !== "Import" && - !(node.callee && node.callee.type === "Import")) || - (node.kind && node.kind !== "Comment")) - ) { + if (node && printer.canAttachComment && printer.canAttachComment(node)) { // This reverse insertion sort almost always takes constant // time because we almost always (maybe always?) append the // nodes in order anyway. @@ -74,7 +63,7 @@ function getSortedChildNodes(node, text, resultArray) { } for (let i = 0, nameCount = names.length; i < nameCount; ++i) { - getSortedChildNodes(node[names[i]], text, resultArray); + getSortedChildNodes(node[names[i]], text, options, resultArray); } return resultArray; @@ -83,8 +72,8 @@ function getSortedChildNodes(node, text, resultArray) { // As efficiently as possible, decorate the comment object with // .precedingNode, .enclosingNode, and/or .followingNode properties, at // least one of which is guaranteed to be defined. -function decorateComment(node, comment, text) { - const childNodes = getSortedChildNodes(node, text); +function decorateComment(node, comment, text, options) { + const childNodes = getSortedChildNodes(node, text, options); let precedingNode; let followingNode; // Time to dust off the old binary search robes and wizard hat. @@ -101,7 +90,7 @@ function decorateComment(node, comment, text) { // The comment is completely contained by this child node. comment.enclosingNode = child; - decorateComment(child, comment, text); + decorateComment(child, comment, text, options); return; // Abandon the binary search at this level. } @@ -174,7 +163,7 @@ function attach(comments, ast, text, options) { return; } - decorateComment(ast, comment, text); + decorateComment(ast, comment, text, options); const precedingNode = comment.precedingNode; const enclosingNode = comment.enclosingNode; @@ -923,56 +912,7 @@ function handleVariableDeclaratorComments( function printComment(commentPath, options) { const comment = commentPath.getValue(); comment.printed = true; - - switch (comment.type || comment.kind) { - case "Comment": - return "#" + comment.value.trimRight(); - case "CommentBlock": - case "Block": { - if (isJsDocComment(comment)) { - return printJsDocComment(comment); - } - - const isInsideFlowComment = - options.originalText.substr(util.locEnd(comment) - 3, 3) === "*-/"; - - return "/*" + comment.value + (isInsideFlowComment ? "*-/" : "*/"); - } - case "CommentLine": - case "Line": - // Print shebangs with the proper comment characters - if (options.originalText.slice(util.locStart(comment)).startsWith("#!")) { - return "#!" + comment.value.trimRight(); - } - return "//" + comment.value.trimRight(); - default: - throw new Error("Not a comment: " + JSON.stringify(comment)); - } -} - -function isJsDocComment(comment) { - const lines = comment.value.split("\n"); - return ( - lines.length > 1 && - lines.slice(0, lines.length - 1).every(line => line.trim()[0] === "*") - ); -} - -function printJsDocComment(comment) { - const lines = comment.value.split("\n"); - - return concat([ - "/*", - join( - hardline, - lines.map( - (line, index) => - (index > 0 ? " " : "") + - (index < lines.length - 1 ? line.trim() : line.trimLeft()) - ) - ), - "*/" - ]); + return options.printer.printComment(commentPath, options); } function findExpressionIndexForComment(quasis, comment) { diff --git a/src/common/deprecated.js b/src/main/deprecated.js similarity index 100% rename from src/common/deprecated.js rename to src/main/deprecated.js diff --git a/src/main/get-printer.js b/src/main/get-printer.js index 86c7eb92..cba1b100 100644 --- a/src/main/get-printer.js +++ b/src/main/get-printer.js @@ -1,13 +1,14 @@ "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]); + const astFormat = options.astFormat; + + if (!astFormat) { + throw new Error("getPrinter() requires astFormat to be set"); + } + const printerPlugin = options.plugins.find( + plugin => plugin.printers[astFormat] + ); if (!printerPlugin) { throw new Error( `Couldn't find printer plugin for AST format "${astFormat}"` diff --git a/src/main/multiparser.js b/src/main/multiparser.js index 8c635782..3704e658 100644 --- a/src/main/multiparser.js +++ b/src/main/multiparser.js @@ -1,10 +1,11 @@ "use strict"; +const normalize = require("./options").normalize; const comments = require("./comments"); -function printSubtree(printer, path, print, options) { - if (printer.embed) { - return printer.embed( +function printSubtree(path, print, options) { + if (options.printer.embed) { + return options.printer.embed( path, print, (text, partialNextOptions) => @@ -15,13 +16,12 @@ function printSubtree(printer, path, print, 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 nextOptions = normalize( + Object.assign({}, parentOptions, partialNextOptions, { + parentParser: parentOptions.parser, + originalText: text + }) + ); const ast = require("./parser").parse(text, nextOptions); const astComments = ast.comments; diff --git a/src/common/options.js b/src/main/options.js similarity index 86% rename from src/common/options.js rename to src/main/options.js index b47d8140..73932f27 100644 --- a/src/common/options.js +++ b/src/main/options.js @@ -4,7 +4,10 @@ const path = require("path"); const validate = require("jest-validate").validate; const deprecatedConfig = require("./deprecated"); -const getSupportInfo = require("./support").getSupportInfo; +const getSupportInfo = require("../common/support").getSupportInfo; +const loadPlugins = require("../common/load-plugins"); +const resolveParser = require("./parser").resolveParser; +const getPrinter = require("./get-printer"); const defaults = { cursorOffset: -1, @@ -18,12 +21,16 @@ const defaults = { bracketSpacing: true, jsxBracketSameLine: false, parser: "babylon", + parentParser: "", insertPragma: false, requirePragma: false, semi: true, proseWrap: "preserve", arrowParens: "avoid", - plugins: [] + plugins: [], + astFormat: "estree", + printer: {}, + __inJsTemplate: false }; const exampleConfig = Object.assign({}, defaults, { @@ -39,6 +46,7 @@ function normalize(options) { if ( filepath && + !normalized.parentParser && (!normalized.parser || normalized.parser === defaults.parser) ) { const extension = path.extname(filepath); @@ -114,6 +122,10 @@ function normalize(options) { delete normalized.useFlowParser; } + normalized.plugins = loadPlugins(normalized); + normalized.astFormat = resolveParser(normalized).astFormat; + normalized.printer = getPrinter(normalized); + Object.keys(defaults).forEach(k => { if (normalized[k] == null) { normalized[k] = defaults[k]; diff --git a/src/main/parser.js b/src/main/parser.js index 20b25467..6e04267a 100644 --- a/src/main/parser.js +++ b/src/main/parser.js @@ -2,16 +2,17 @@ const path = require("path"); const ConfigError = require("../common/errors").ConfigError; -const loadPlugins = require("../common/load-plugins"); -function getParsers(plugins) { - return plugins.reduce( +function getParsers(options) { + return options.plugins.reduce( (parsers, plugin) => Object.assign({}, parsers, plugin.parsers), {} ); } -function resolveParser(parsers, opts) { +function resolveParser(opts, parsers) { + parsers = parsers || getParsers(opts); + if (typeof opts.parser === "function") { // Custom parser API always works with JavaScript. return { @@ -39,7 +40,7 @@ function resolveParser(parsers, opts) { } function parse(text, opts) { - const parsers = getParsers(loadPlugins(opts), opts); + const parsers = getParsers(opts); // Copy the "parse" function from parser to a new object whose values are // functions. Use defineProperty()/getOwnPropertyDescriptor() such that we @@ -54,7 +55,7 @@ function parse(text, opts) { {} ); - const parser = resolveParser(parsers, opts); + const parser = resolveParser(opts, parsers); try { return parser.parse(text, parsersForCustomParserApi, opts); @@ -75,4 +76,4 @@ function parse(text, opts) { } } -module.exports = { getParsers, parse, resolveParser }; +module.exports = { parse, resolveParser }; diff --git a/tests_config/run_spec.js b/tests_config/run_spec.js index bfc649e5..9baaaff3 100644 --- a/tests_config/run_spec.js +++ b/tests_config/run_spec.js @@ -3,7 +3,6 @@ const fs = require("fs"); const extname = require("path").extname; const prettier = require("./require_prettier"); -const parser = require("../src/main/parser"); const massageAST = require("../src/common/clean-ast.js").massageAST; const AST_COMPARE = process.env["AST_COMPARE"]; @@ -116,7 +115,7 @@ function stripLocation(ast) { } function parse(string, opts) { - return stripLocation(parser.parse(string, opts)); + return stripLocation(prettier.__debug.parse(string, opts)); } function prettyprint(src, filename, options) { From 3a9b25b8bc5f43401bacd1284eceeaa3295d6604 Mon Sep 17 00:00:00 2001 From: Lucas Azzola Date: Wed, 27 Dec 2017 00:20:10 +1100 Subject: [PATCH 05/12] Add JSX to supported language list (#3579) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 0bf1eab2..de966e3e 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ · CSS · SCSS · Less + · JSX · Vue · GraphQL · JSON From 84dd11e875f8ad2585c168b4bbfbbf5ee684adb5 Mon Sep 17 00:00:00 2001 From: Lucas Azzola Date: Wed, 27 Dec 2017 09:06:59 +1100 Subject: [PATCH 06/12] Bump TypeScript to 2.7-insiders (#3580) * Bump TypeScript to 2.7-insiders * Update yarn.lock --- package.json | 2 +- tests/literal-numeric-separator/jsfmt.spec.js | 2 +- yarn.lock | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 395609e2..57cba3eb 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "resolve": "1.5.0", "semver": "5.4.1", "string-width": "2.1.1", - "typescript": "2.6.2", + "typescript": "2.7.0-insiders.20171214", "typescript-eslint-parser": "11.0.0", "unicode-regex": "1.0.1", "unified": "6.1.6" diff --git a/tests/literal-numeric-separator/jsfmt.spec.js b/tests/literal-numeric-separator/jsfmt.spec.js index 968651cd..4ef9b45f 100644 --- a/tests/literal-numeric-separator/jsfmt.spec.js +++ b/tests/literal-numeric-separator/jsfmt.spec.js @@ -1 +1 @@ -run_spec(__dirname, ["babylon"]); +run_spec(__dirname, ["babylon", "typescript"]); diff --git a/yarn.lock b/yarn.lock index 000e374e..157eea65 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4424,9 +4424,9 @@ typescript-eslint-parser@11.0.0: lodash.unescape "4.0.1" semver "5.4.1" -typescript@2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.6.2.tgz#3c5b6fd7f6de0914269027f03c0946758f7673a4" +typescript@2.7.0-insiders.20171214: + version "2.7.0-insiders.20171214" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.7.0-insiders.20171214.tgz#841344ddae5f498a97c0435fcd12860480050e71" uglify-es@3.0.28: version "3.0.28" From 15a68394ddb89f3371ed17be9ab01ccc34bde72c Mon Sep 17 00:00:00 2001 From: artiebits Date: Wed, 27 Dec 2017 23:32:37 +0100 Subject: [PATCH 07/12] Move playground styles to the single CSS file (#3588) * Move playground styles to the single css file * Add separateCss property to siteConfig.js --- website/pages/playground/index.html | 286 +--------------------------- website/siteConfig.js | 1 + website/static/playground.css | 283 +++++++++++++++++++++++++++ 3 files changed, 285 insertions(+), 285 deletions(-) create mode 100644 website/static/playground.css diff --git a/website/pages/playground/index.html b/website/pages/playground/index.html index 87c854ee..35faca05 100644 --- a/website/pages/playground/index.html +++ b/website/pages/playground/index.html @@ -41,291 +41,7 @@ - + diff --git a/website/siteConfig.js b/website/siteConfig.js index 57b9194d..209dd3f3 100644 --- a/website/siteConfig.js +++ b/website/siteConfig.js @@ -74,6 +74,7 @@ const siteConfig = { ); } ], + separateCss: "/playground.css", gaTrackingId: "UA-111350464-1" }; diff --git a/website/static/playground.css b/website/static/playground.css new file mode 100644 index 00000000..ed239bf5 --- /dev/null +++ b/website/static/playground.css @@ -0,0 +1,283 @@ +html { + background-color: #fafafa; + color: #6a6a6a; + font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", + Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", + "Helvetica Neue", Arial, sans-serif; + font-size: 12px; + line-height: 1.25; +} + +body { + display: flex; + flex-direction: column; + height: 100vh; + margin: 0; +} + +header { + display: flex; + flex-wrap: nowrap; + justify-content: space-between; + align-items: center; + height: 30px; + padding: 11px 27px; + background-color: #1a2b34; + color: #e0e0e0; + position: relative; + z-index: 20; +} + +@media (max-width: 400px) { + header { + padding: 10px; + } +} + +header a, +header a:visited, +header a:focus, +header a:active, +header a:hover { + color: #fff; + text-decoration: none; +} + +.logo-wrapper { + display: flex; + align-items: center; +} + +.logo { + height: 34px; + margin-right: 10px; +} + +header h1 { + font-size: 20px; + display: block; + font-family: inherit; + font-weight: 400; + line-height: 18px; + position: relative; + z-index: 9999; + margin: 0; +} + +#version { + font-size: 0.5em; + line-height: 0; + opacity: 0.5; +} + +.links { + display: flex; + font-size: 16px; +} +.links > * + * { + margin-left: 15px; +} + +.editors-container { + display: flex; + flex: 1; + min-height: 0; +} + +.editors { + display: flex; + flex-flow: row wrap; + flex: 1; +} + +.editor { + box-sizing: border-box; + display: flex; + flex: 1 1 100%; + position: relative; + border-bottom: 1px solid #ddd; +} + +/* display as 2x2 grid */ +@media (min-width: 800px) { + .options-container { + border-right: 0; + } + + .editor { + flex-basis: 50%; + border-left: 1px solid #ddd; + margin-left: -1px; + } +} + +/* display as four columns */ +@media (min-width: 1200px) { + .editor { + flex-basis: 25%; + } +} + +.editor.loading { + opacity: 0; +} + +.CodeMirror { + height: auto; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + line-height: 1.6; +} + +.bottom-bar { + position: relative; +} + +.bottom-bar-buttons { + z-index: 10; + padding: 8px; + display: flex; + float: left; +} + +.bottom-bar-buttons-right { + float: right; +} + +.bottom-bar-buttons > * + * { + margin-left: 9px; +} + +@media (max-width: 799px) { + .bottom-bar-buttons { + top: auto; + bottom: 100%; + padding: 2px; + } + + .bottom-bar-buttons > * + * { + margin-left: 2px; + } +} + +.options-container { + display: none; + box-sizing: border-box; + width: 225px; + height: 100%; + border-bottom: 1px solid #ddd; + border-right: 1px solid #ddd; + flex: 0 1 auto; +} + +.options-container.open { + display: block; +} + +.options { + display: flex; + flex-direction: column; + max-height: 100%; + overflow: auto; +} + +.sub-options { + flex: 1; + display: flex; + padding: 15px 0 10px; + border-bottom: 1px solid #ddd; +} + +.sub-options:last-child { + border: 0; +} + +.sub-options > summary { + font-size: 14px; + font-weight: bold; + padding-bottom: 5px; + cursor: pointer; +} + +.sub-options > summary:focus { + outline: 0; +} + +.sub-options > * { + margin-left: 10px; +} + +label { + font-family: Consolas, Courier New, Courier, monospace; + margin: 10px 0; + display: block; +} + +input[type="number"] { + max-width: 40px; +} + +/* Copied from the GitHub button styling. */ +.btn { + box-sizing: content-box; + display: inline-block; + height: 18px; + padding: 0 5px; + border: 1px solid #d1d2d3; + border-radius: 0.25em; + background-image: linear-gradient(to bottom, #fafbfc, #e4ebf0); + font-size: 11px; + line-height: 18px; + font-weight: 600; + font-family: inherit; + color: #24292e; + text-decoration: none; + cursor: pointer; + outline: none; + position: relative; +} + +.btn:focus { + border-color: #c8e1ff; +} + +.btn:hover { + background-color: #e6ebf1; + background-image: linear-gradient(to bottom, #f0f3f6, #dce3ec); + border-color: #afb1b2; +} + +.btn:active { + background-color: #e9ecef; + background-image: none; + border-color: #afb1b2; + box-shadow: inset 0 0.15em 0.3em rgba(27, 31, 35, 0.15); +} + +.tooltip { + position: absolute; + z-index: 1; + bottom: 100%; + left: 50%; + transform: translateX(-50%); + margin-top: 4px; + padding: 0.4em 0.8em; + background-color: #000; + color: #fff; + border-radius: 0.4em; + pointer-events: none; +} + +.tooltip::before { + content: ""; + position: absolute; + top: 100%; + left: 50%; + transform: translateX(-50%); + border: 6px solid transparent; + border-bottom: none; + border-top-color: #000; +} \ No newline at end of file From b63c669ed9821a0e0d6918243ef4f4a091b222a9 Mon Sep 17 00:00:00 2001 From: Jimmy Jia Date: Thu, 28 Dec 2017 01:08:58 -0800 Subject: [PATCH 08/12] Support plugins field in config (#3584) * Actually support plugins field in config * Resolve plugin parsers * Fix default from CLI for "plugins" --- src/cli/constant.js | 9 +++++++++ src/cli/util.js | 16 +++++++++++----- src/main/options.js | 5 +++-- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/cli/constant.js b/src/cli/constant.js index 902bff79..523f1292 100644 --- a/src/cli/constant.js +++ b/src/cli/constant.js @@ -443,10 +443,19 @@ const detailedOptionMap = detailedOptions.reduce( {} ); +const apiDetailedOptionMap = detailedOptions.reduce( + (current, option) => + option.forwardToApi && option.forwardToApi !== option.name + ? Object.assign(current, { [option.forwardToApi]: option }) + : current, + {} +); + module.exports = { categoryOrder, minimistOptions, detailedOptions, detailedOptionMap, + apiDetailedOptionMap, usageSummary }; diff --git a/src/cli/util.js b/src/cli/util.js index ec7df22c..eb1db585 100644 --- a/src/cli/util.js +++ b/src/cli/util.js @@ -37,9 +37,12 @@ function getOptions(argv) { ); } -function dashifyObject(object) { +function cliifyOptions(object) { return Object.keys(object || {}).reduce((output, key) => { - output[dashify(key)] = object[key]; + const apiOption = constant.apiDetailedOptionMap[key]; + const cliKey = apiOption ? apiOption.name : key; + + output[dashify(cliKey)] = object[key]; return output; }, {}); } @@ -202,8 +205,8 @@ function parseArgsToOptions(argv, overrideDefaults) { boolean: constant.minimistOptions.boolean, default: Object.assign( {}, - dashifyObject(apiDefaultOptions), - dashifyObject(overrideDefaults) + cliifyOptions(apiDefaultOptions), + cliifyOptions(overrideDefaults) ) }) ), @@ -619,7 +622,10 @@ function normalizeConfig(type, rawConfig, options) { return; } - const option = constant.detailedOptionMap[key]; + let option = constant.detailedOptionMap[key]; + if (type === "api" && option === undefined) { + option = constant.apiDetailedOptionMap[key]; + } // unknown option if (option === undefined) { diff --git a/src/main/options.js b/src/main/options.js index 73932f27..c52ceea5 100644 --- a/src/main/options.js +++ b/src/main/options.js @@ -44,6 +44,8 @@ function normalize(options) { const normalized = Object.assign({}, options || {}); const filepath = normalized.filepath; + normalized.plugins = loadPlugins(normalized); + if ( filepath && !normalized.parentParser && @@ -52,7 +54,7 @@ function normalize(options) { const extension = path.extname(filepath); const filename = path.basename(filepath).toLowerCase(); - const language = getSupportInfo().languages.find( + const language = getSupportInfo(null, normalized).languages.find( language => typeof language.since === "string" && (language.extensions.indexOf(extension) > -1 || @@ -122,7 +124,6 @@ function normalize(options) { delete normalized.useFlowParser; } - normalized.plugins = loadPlugins(normalized); normalized.astFormat = resolveParser(normalized).astFormat; normalized.printer = getPrinter(normalized); From b0647cb2c9936ef40f6a999143c8d0cb126f7f21 Mon Sep 17 00:00:00 2001 From: Lucas Azzola Date: Thu, 28 Dec 2017 22:37:47 +1100 Subject: [PATCH 09/12] Fix PR Preview Playground (#3592) * Fix PR Preview Playground * Use module.exports for Prettier export * Keep index for backwards compatibility --- website/static/worker.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/website/static/worker.js b/website/static/worker.js index 2e273a9e..06013285 100644 --- a/website/static/worker.js +++ b/website/static/worker.js @@ -40,8 +40,14 @@ self.require = function require(path) { return self[path]; }; +var prettier; importScripts("lib/index.js"); -var prettier = index; // eslint-disable-line +if (typeof prettier === "undefined") { + prettier = module.exports; // eslint-disable-line +} +if (typeof prettier === "undefined") { + prettier = index; // eslint-disable-line +} var parsersLoaded = {}; From bbfc450cd2a072512b756d45eef4f6648b267058 Mon Sep 17 00:00:00 2001 From: Jimmy Jia Date: Thu, 28 Dec 2017 09:20:25 -0800 Subject: [PATCH 10/12] Support Relay Classic (#3595) --- src/language-js/embed.js | 6 ++++-- .../__snapshots__/jsfmt.spec.js.snap | 20 +++++++++++++++++++ tests/multiparser_js_graphql/react-relay.js | 9 +++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/language-js/embed.js b/src/language-js/embed.js index b439aa08..6affe0cf 100644 --- a/src/language-js/embed.js +++ b/src/language-js/embed.js @@ -39,8 +39,10 @@ function embed(path, print, textToDoc /*, options */) { parent && ((parent.type === "TaggedTemplateExpression" && ((parent.tag.type === "MemberExpression" && - parent.tag.object.name === "graphql" && - parent.tag.property.name === "experimental") || + ((parent.tag.object.name === "graphql" && + parent.tag.property.name === "experimental") || + (parent.tag.object.name === "Relay" && + parent.tag.property.name === "QL"))) || (parent.tag.type === "Identifier" && (parent.tag.name === "gql" || parent.tag.name === "graphql")))) || (parent.type === "CallExpression" && diff --git a/tests/multiparser_js_graphql/__snapshots__/jsfmt.spec.js.snap b/tests/multiparser_js_graphql/__snapshots__/jsfmt.spec.js.snap index 580b80d4..9092cc38 100644 --- a/tests/multiparser_js_graphql/__snapshots__/jsfmt.spec.js.snap +++ b/tests/multiparser_js_graphql/__snapshots__/jsfmt.spec.js.snap @@ -394,6 +394,7 @@ gql\` exports[`react-relay.js 1`] = ` const { graphql } = require("react-relay"); +const Relay = require("react-relay/classic"); graphql\` mutation MarkReadNotificationMutation( @@ -410,8 +411,17 @@ graphql.experimental\` ) { markReadNotification(data: $input ) { notification {seenState} } } \`; + +Relay.QL\` + mutation MarkReadNotificationMutation( + $input + : MarkReadNotificationData! + ) +{ markReadNotification(data: $input ) { notification {seenState} } } +\`; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ const { graphql } = require("react-relay"); +const Relay = require("react-relay/classic"); graphql\` mutation MarkReadNotificationMutation($input: MarkReadNotificationData!) { @@ -433,4 +443,14 @@ graphql.experimental\` } \`; +Relay.QL\` + mutation MarkReadNotificationMutation($input: MarkReadNotificationData!) { + markReadNotification(data: $input) { + notification { + seenState + } + } + } +\`; + `; diff --git a/tests/multiparser_js_graphql/react-relay.js b/tests/multiparser_js_graphql/react-relay.js index 6cc85ccf..2fb69942 100644 --- a/tests/multiparser_js_graphql/react-relay.js +++ b/tests/multiparser_js_graphql/react-relay.js @@ -1,4 +1,5 @@ const { graphql } = require("react-relay"); +const Relay = require("react-relay/classic"); graphql` mutation MarkReadNotificationMutation( @@ -15,3 +16,11 @@ graphql.experimental` ) { markReadNotification(data: $input ) { notification {seenState} } } `; + +Relay.QL` + mutation MarkReadNotificationMutation( + $input + : MarkReadNotificationData! + ) +{ markReadNotification(data: $input ) { notification {seenState} } } +`; From bd78b3bfbe3983a5af48c35eb4da0a45422edc70 Mon Sep 17 00:00:00 2001 From: Lucas Azzola Date: Fri, 29 Dec 2017 08:25:11 +1100 Subject: [PATCH 11/12] Remove ALL_PARSERS, print ~ printWidth times (#3596) --- .../__snapshots__/jsfmt.spec.js.snap | 2 +- tests_config/run_spec.js | 36 +++++++------------ 2 files changed, 13 insertions(+), 25 deletions(-) diff --git a/tests/object_colon_bug/__snapshots__/jsfmt.spec.js.snap b/tests/object_colon_bug/__snapshots__/jsfmt.spec.js.snap index c9bb429f..ea150189 100644 --- a/tests/object_colon_bug/__snapshots__/jsfmt.spec.js.snap +++ b/tests/object_colon_bug/__snapshots__/jsfmt.spec.js.snap @@ -5,7 +5,7 @@ const foo = { bar: props.bar ? props.bar : noop, baz: props.baz } -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ const foo = { bar: props.bar ? props.bar diff --git a/tests_config/run_spec.js b/tests_config/run_spec.js index 9baaaff3..fece39d4 100644 --- a/tests_config/run_spec.js +++ b/tests_config/run_spec.js @@ -6,10 +6,6 @@ const prettier = require("./require_prettier"); 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; -const ALL_PARSERS = process.env["ALL_PARSERS"] - ? JSON.parse(process.env["ALL_PARSERS"]) - : ["flow", "graphql", "babylon", "typescript"]; function run_spec(dirname, parsers, options) { /* instabul ignore if */ @@ -45,22 +41,20 @@ function run_spec(dirname, parsers, options) { }); const output = prettyprint(source, path, mergedOptions); test(`${filename} - ${mergedOptions.parser}-verify`, () => { - expect(raw(source + "~".repeat(80) + "\n" + output)).toMatchSnapshot( - filename - ); + expect( + raw(source + "~".repeat(mergedOptions.printWidth) + "\n" + output) + ).toMatchSnapshot(filename); }); - getParsersToVerify(mergedOptions.parser, parsers.slice(1)).forEach( - parserName => { - test(`${filename} - ${parserName}-verify`, () => { - const verifyOptions = Object.assign(mergedOptions, { - parser: parserName - }); - const verifyOutput = prettyprint(source, path, verifyOptions); - expect(output).toEqual(verifyOutput); + parsers.slice(1).forEach(parserName => { + test(`${filename} - ${parserName}-verify`, () => { + const verifyOptions = Object.assign(mergedOptions, { + parser: parserName }); - } - ); + const verifyOutput = prettyprint(source, path, verifyOptions); + expect(output).toEqual(verifyOutput); + }); + }); if (AST_COMPARE) { const ast = parse(source, mergedOptions); @@ -88,6 +82,7 @@ function run_spec(dirname, parsers, options) { } }); } + global.run_spec = run_spec; function stripLocation(ast) { @@ -154,10 +149,3 @@ function mergeDefaultOptions(parserConfig) { parserConfig ); } - -function getParsersToVerify(parser, additionalParsers) { - if (VERIFY_ALL_PARSERS) { - return ALL_PARSERS.splice(ALL_PARSERS.indexOf(parser), 1); - } - return additionalParsers; -} From 6a75f667316d34719e8ddbfee81613b5148664c5 Mon Sep 17 00:00:00 2001 From: Lipis Date: Fri, 29 Dec 2017 16:59:49 +0200 Subject: [PATCH 12/12] Add Google Analytics on Playground (#3576) --- website/pages/playground/index.html | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/website/pages/playground/index.html b/website/pages/playground/index.html index 35faca05..b1e885a9 100644 --- a/website/pages/playground/index.html +++ b/website/pages/playground/index.html @@ -42,6 +42,15 @@ + + + +