In #1250, @jeresig reported that adding // prettier-ignore on a file that has a ton of conditional group still took 1.7s. The issue is that we're printing before checking for the comment. Swaping the two had the unfortunate side effect of not marking the comments as being printed, so I had to skip that safety check if there's a prettier-ignore. With this change, adding prettier-ignore makes the file be printed instantly!
144 lines
3.8 KiB
JavaScript
144 lines
3.8 KiB
JavaScript
"use strict";
|
|
|
|
const codeFrame = require("babel-code-frame");
|
|
const comments = require("./src/comments");
|
|
const version = require("./package.json").version;
|
|
const printAstToDoc = require("./src/printer").printAstToDoc;
|
|
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;
|
|
|
|
function guessLineEnding(text) {
|
|
const index = text.indexOf("\n");
|
|
if (index >= 0 && text.charAt(index - 1) === "\r") {
|
|
return "\r\n";
|
|
}
|
|
return "\n";
|
|
}
|
|
|
|
function parse(text, opts) {
|
|
let parseFunction;
|
|
|
|
if (opts.parser === "flow") {
|
|
parseFunction = parser.parseWithFlow;
|
|
} else if (opts.parser === "typescript") {
|
|
parseFunction = parser.parseWithTypeScript;
|
|
} else {
|
|
parseFunction = parser.parseWithBabylon;
|
|
}
|
|
|
|
try {
|
|
return parseFunction(text);
|
|
} catch (error) {
|
|
const loc = error.loc;
|
|
|
|
if (loc) {
|
|
error.codeFrame = codeFrame(text, loc.line, loc.column + 1, {
|
|
highlightCode: true
|
|
});
|
|
error.message += "\n" + error.codeFrame;
|
|
}
|
|
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
function attachComments(text, ast, opts) {
|
|
const astComments = ast.comments;
|
|
if (astComments) {
|
|
delete ast.comments;
|
|
comments.attach(astComments, ast, text, opts);
|
|
}
|
|
ast.tokens = [];
|
|
opts.originalText = text.trimRight();
|
|
return astComments;
|
|
}
|
|
|
|
function ensureAllCommentsPrinted(astComments) {
|
|
for (let i = 0; i < astComments.length; ++i) {
|
|
if (astComments[i].value.trim() === "prettier-ignore") {
|
|
// If there's a prettier-ignore, we're not printing that sub-tree so we
|
|
// don't know if the comments was printed or not.
|
|
return;
|
|
}
|
|
}
|
|
|
|
astComments.forEach(comment => {
|
|
if (!comment.printed) {
|
|
throw new Error(
|
|
'Comment "' +
|
|
comment.value.trim() +
|
|
'" was not printed. Please report this error!'
|
|
);
|
|
}
|
|
delete comment.printed;
|
|
});
|
|
}
|
|
|
|
function format(text, opts) {
|
|
const ast = parse(text, opts);
|
|
const astComments = attachComments(text, ast, opts);
|
|
const doc = printAstToDoc(ast, opts);
|
|
opts.newLine = guessLineEnding(text);
|
|
const str = printDocToString(doc, opts);
|
|
ensureAllCommentsPrinted(astComments);
|
|
return str;
|
|
}
|
|
|
|
function formatWithShebang(text, opts) {
|
|
if (!text.startsWith("#!")) {
|
|
return format(text, opts);
|
|
}
|
|
|
|
const index = text.indexOf("\n");
|
|
const shebang = text.slice(0, index + 1);
|
|
const programText = text.slice(index + 1);
|
|
const nextChar = text.charAt(index + 1);
|
|
const newLine = nextChar === "\n" ? "\n" : nextChar === "\r" ? "\r\n" : "";
|
|
|
|
return shebang + newLine + format(programText, opts);
|
|
}
|
|
|
|
module.exports = {
|
|
format: function(text, opts) {
|
|
return formatWithShebang(text, normalizeOptions(opts));
|
|
},
|
|
check: function(text, opts) {
|
|
try {
|
|
const formatted = this.format(text, opts);
|
|
return formatted === text;
|
|
} catch (e) {
|
|
return false;
|
|
}
|
|
},
|
|
version: version,
|
|
__debug: {
|
|
formatAST: function(ast, opts) {
|
|
opts = normalizeOptions(opts);
|
|
const doc = printAstToDoc(ast, opts);
|
|
const str = printDocToString(doc, opts);
|
|
return str;
|
|
},
|
|
// Doesn't handle shebang for now
|
|
formatDoc: function(doc, opts) {
|
|
opts = normalizeOptions(opts);
|
|
const debug = printDocToDebug(doc);
|
|
const str = format(debug, opts);
|
|
return str;
|
|
},
|
|
printToDoc: function(text, opts) {
|
|
opts = normalizeOptions(opts);
|
|
const ast = parse(text, opts);
|
|
attachComments(text, ast, opts);
|
|
const doc = printAstToDoc(ast, opts);
|
|
return doc;
|
|
},
|
|
printDocToString: function(doc, opts) {
|
|
opts = normalizeOptions(opts);
|
|
const str = printDocToString(doc, opts);
|
|
return str;
|
|
}
|
|
}
|
|
};
|