Split pp.js into doc-{printer,builders,utils}.js (#334)
- doc-printer.js is now the direct implementation of the Wadler paper - doc-builders.js are a lot of utils to generate the IR the above file needs - doc-utils.js are small utils to traverse list of docs.master
parent
ab046c6850
commit
ad96fce6c2
7
index.js
7
index.js
|
@ -1,10 +1,10 @@
|
|||
"use strict";
|
||||
const babylon = require("babylon");
|
||||
const printAstToDoc = require("./src/printer").printAstToDoc;
|
||||
const flowParser = require("flow-parser");
|
||||
const comments = require("./src/comments");
|
||||
const version = require("./package.json").version;
|
||||
const pp = require("./src/pp");
|
||||
const printAstToDoc = require("./src/printer").printAstToDoc;
|
||||
const printDocToString = require("./src/doc-printer").printDocToString;
|
||||
const normalizeOptions = require("./src/options").normalize;
|
||||
|
||||
var babylonOptions = {
|
||||
|
@ -59,7 +59,8 @@ function format(text, opts) {
|
|||
opts.originalText = text;
|
||||
|
||||
const doc = printAstToDoc(ast, opts)
|
||||
return pp.print(opts.printWidth, doc);
|
||||
const str = printDocToString(doc, opts.printWidth)
|
||||
return str;
|
||||
}
|
||||
|
||||
function formatWithShebang(text, opts) {
|
||||
|
|
|
@ -3,10 +3,10 @@ var types = require("ast-types");
|
|||
var n = types.namedTypes;
|
||||
var isArray = types.builtInTypes.array;
|
||||
var isObject = types.builtInTypes.object;
|
||||
var pp = require("./pp");
|
||||
var fromString = pp.fromString;
|
||||
var concat = pp.concat;
|
||||
var hardline = pp.hardline;
|
||||
var docBuilders = require("./doc-builders");
|
||||
var fromString = docBuilders.fromString;
|
||||
var concat = docBuilders.concat;
|
||||
var hardline = docBuilders.hardline;
|
||||
var util = require("./util");
|
||||
var comparePos = util.comparePos;
|
||||
var childNodesCacheKey = require("private").makeUniqueKey();
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
const assert = require("assert");
|
||||
const utils = require("./doc-utils");
|
||||
const hasHardLine = utils.hasHardLine;
|
||||
|
||||
function assertDoc(val) {
|
||||
assert(
|
||||
typeof val === "string" || val != null && typeof val.type === "string",
|
||||
"Value is a valid document"
|
||||
);
|
||||
}
|
||||
|
||||
function fromString(text) {
|
||||
return "" + text;
|
||||
}
|
||||
|
||||
function concat(parts) {
|
||||
parts.forEach(assertDoc);
|
||||
|
||||
return { type: "concat", parts };
|
||||
}
|
||||
|
||||
function indent(n, contents) {
|
||||
assertDoc(contents);
|
||||
|
||||
return { type: "indent", contents, n };
|
||||
}
|
||||
|
||||
function group(contents, opts) {
|
||||
opts = opts || {};
|
||||
|
||||
assertDoc(contents);
|
||||
|
||||
return {
|
||||
type: "group",
|
||||
contents: contents,
|
||||
break: !!opts.shouldBreak,
|
||||
expandedStates: opts.expandedStates
|
||||
};
|
||||
}
|
||||
|
||||
function multilineGroup(contents, opts) {
|
||||
return group(
|
||||
contents,
|
||||
Object.assign(opts || {}, { shouldBreak: hasHardLine(contents) })
|
||||
);
|
||||
}
|
||||
|
||||
function conditionalGroup(states, opts) {
|
||||
return group(
|
||||
states[0],
|
||||
Object.assign(opts || {}, { expandedStates: states })
|
||||
);
|
||||
}
|
||||
|
||||
function ifBreak(breakContents, flatContents) {
|
||||
if (breakContents) {
|
||||
assertDoc(breakContents);
|
||||
}
|
||||
if (flatContents) {
|
||||
assertDoc(flatContents);
|
||||
}
|
||||
|
||||
return { type: "if-break", breakContents, flatContents };
|
||||
}
|
||||
|
||||
const line = { type: "line" };
|
||||
const softline = { type: "line", soft: true };
|
||||
const hardline = { type: "line", hard: true };
|
||||
const literalline = { type: "line", hard: true, literal: true };
|
||||
|
||||
function join(sep, arr) {
|
||||
var res = [];
|
||||
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
if (i !== 0) {
|
||||
res.push(sep);
|
||||
}
|
||||
|
||||
res.push(arr[i]);
|
||||
}
|
||||
|
||||
return concat(res);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
fromString,
|
||||
concat,
|
||||
join,
|
||||
line,
|
||||
softline,
|
||||
hardline,
|
||||
literalline,
|
||||
group,
|
||||
multilineGroup,
|
||||
conditionalGroup,
|
||||
ifBreak,
|
||||
indent,
|
||||
};
|
|
@ -1,149 +1,4 @@
|
|||
"use strict";
|
||||
const assert = require("assert");
|
||||
|
||||
function assertDoc(val) {
|
||||
assert(
|
||||
typeof val === "string" || val != null && typeof val.type === "string",
|
||||
"Value is a valid document"
|
||||
);
|
||||
}
|
||||
|
||||
function fromString(text) {
|
||||
return "" + text;
|
||||
}
|
||||
|
||||
function concat(parts) {
|
||||
parts.forEach(assertDoc);
|
||||
|
||||
return { type: "concat", parts };
|
||||
}
|
||||
|
||||
function indent(n, contents) {
|
||||
assertDoc(contents);
|
||||
|
||||
return { type: "indent", contents, n };
|
||||
}
|
||||
|
||||
function group(contents, opts) {
|
||||
opts = opts || {};
|
||||
|
||||
assertDoc(contents);
|
||||
|
||||
return {
|
||||
type: "group",
|
||||
contents: contents,
|
||||
break: !!opts.shouldBreak,
|
||||
expandedStates: opts.expandedStates
|
||||
};
|
||||
}
|
||||
|
||||
function multilineGroup(contents, opts) {
|
||||
return group(
|
||||
contents,
|
||||
Object.assign(opts || {}, { shouldBreak: hasHardLine(contents) })
|
||||
);
|
||||
}
|
||||
|
||||
function conditionalGroup(states, opts) {
|
||||
return group(
|
||||
states[0],
|
||||
Object.assign(opts || {}, { expandedStates: states })
|
||||
);
|
||||
}
|
||||
|
||||
function ifBreak(breakContents, flatContents) {
|
||||
if (breakContents) {
|
||||
assertDoc(breakContents);
|
||||
}
|
||||
if (flatContents) {
|
||||
assertDoc(flatContents);
|
||||
}
|
||||
|
||||
return { type: "if-break", breakContents, flatContents };
|
||||
}
|
||||
|
||||
function iterDoc(topDoc, func) {
|
||||
const docs = [ topDoc ];
|
||||
while (docs.length !== 0) {
|
||||
const doc = docs.pop();
|
||||
let res = undefined;
|
||||
|
||||
if (typeof doc === "string") {
|
||||
const res = func("string", doc);
|
||||
|
||||
if (res) {
|
||||
return res;
|
||||
}
|
||||
} else {
|
||||
const res = func(doc.type, doc);
|
||||
|
||||
if (res) {
|
||||
return res;
|
||||
}
|
||||
|
||||
if (doc.type === "concat") {
|
||||
for (var i = doc.parts.length - 1; i >= 0; i--) {
|
||||
docs.push(doc.parts[i]);
|
||||
}
|
||||
} else if (doc.type === "if-break") {
|
||||
if (doc.breakContents) {
|
||||
docs.push(doc.breakContents);
|
||||
}
|
||||
if (doc.flatContents) {
|
||||
docs.push(doc.flatContents);
|
||||
}
|
||||
} else if (doc.type !== "line") {
|
||||
docs.push(doc.contents);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const line = { type: "line" };
|
||||
const softline = { type: "line", soft: true };
|
||||
const hardline = { type: "line", hard: true };
|
||||
const literalline = { type: "line", hard: true, literal: true };
|
||||
|
||||
function isEmpty(n) {
|
||||
return typeof n === "string" && n.length === 0;
|
||||
}
|
||||
|
||||
function join(sep, arr) {
|
||||
var res = [];
|
||||
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
if (i !== 0) {
|
||||
res.push(sep);
|
||||
}
|
||||
|
||||
res.push(arr[i]);
|
||||
}
|
||||
|
||||
return concat(res);
|
||||
}
|
||||
|
||||
function getFirstString(doc) {
|
||||
return iterDoc(doc, (type, doc) => {
|
||||
if (type === "string" && doc.trim().length !== 0) {
|
||||
return doc;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function hasHardLine(doc) {
|
||||
// TODO: If we hit a group, check if it's already marked as a
|
||||
// multiline group because they should be marked bottom-up.
|
||||
return !!iterDoc(doc, (type, doc) => {
|
||||
switch (type) {
|
||||
case "line":
|
||||
if (doc.hard) {
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const MODE_BREAK = 1;
|
||||
const MODE_FLAT = 2;
|
||||
|
@ -222,7 +77,7 @@ function fits(next, restCommands, width) {
|
|||
return false;
|
||||
}
|
||||
|
||||
function print(w, doc) {
|
||||
function printDocToString(doc, w) {
|
||||
let pos = 0;
|
||||
// cmds is basically a stack. We've turned a recursive call into a
|
||||
// while loop which is much faster. The while loop below adds new
|
||||
|
@ -381,20 +236,5 @@ function print(w, doc) {
|
|||
}
|
||||
|
||||
module.exports = {
|
||||
fromString,
|
||||
concat,
|
||||
isEmpty,
|
||||
join,
|
||||
line,
|
||||
softline,
|
||||
hardline,
|
||||
literalline,
|
||||
group,
|
||||
multilineGroup,
|
||||
conditionalGroup,
|
||||
ifBreak,
|
||||
hasHardLine,
|
||||
indent,
|
||||
print,
|
||||
getFirstString
|
||||
printDocToString,
|
||||
};
|
|
@ -0,0 +1,70 @@
|
|||
|
||||
function iterDoc(topDoc, func) {
|
||||
const docs = [ topDoc ];
|
||||
while (docs.length !== 0) {
|
||||
const doc = docs.pop();
|
||||
let res = undefined;
|
||||
|
||||
if (typeof doc === "string") {
|
||||
const res = func("string", doc);
|
||||
|
||||
if (res) {
|
||||
return res;
|
||||
}
|
||||
} else {
|
||||
const res = func(doc.type, doc);
|
||||
|
||||
if (res) {
|
||||
return res;
|
||||
}
|
||||
|
||||
if (doc.type === "concat") {
|
||||
for (var i = doc.parts.length - 1; i >= 0; i--) {
|
||||
docs.push(doc.parts[i]);
|
||||
}
|
||||
} else if (doc.type === "if-break") {
|
||||
if (doc.breakContents) {
|
||||
docs.push(doc.breakContents);
|
||||
}
|
||||
if (doc.flatContents) {
|
||||
docs.push(doc.flatContents);
|
||||
}
|
||||
} else if (doc.type !== "line") {
|
||||
docs.push(doc.contents);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function isEmpty(n) {
|
||||
return typeof n === "string" && n.length === 0;
|
||||
}
|
||||
|
||||
function getFirstString(doc) {
|
||||
return iterDoc(doc, (type, doc) => {
|
||||
if (type === "string" && doc.trim().length !== 0) {
|
||||
return doc;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function hasHardLine(doc) {
|
||||
// TODO: If we hit a group, check if it's already marked as a
|
||||
// multiline group because they should be marked bottom-up.
|
||||
return !!iterDoc(doc, (type, doc) => {
|
||||
switch (type) {
|
||||
case "line":
|
||||
if (doc.hard) {
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
isEmpty,
|
||||
getFirstString,
|
||||
hasHardLine,
|
||||
};
|
|
@ -1,31 +1,35 @@
|
|||
"use strict";
|
||||
var assert = require("assert");
|
||||
var comments = require("./comments");
|
||||
var pp = require("./pp");
|
||||
var fromString = pp.fromString;
|
||||
var concat = pp.concat;
|
||||
var isEmpty = pp.isEmpty;
|
||||
var join = pp.join;
|
||||
var line = pp.line;
|
||||
var hardline = pp.hardline;
|
||||
var softline = pp.softline;
|
||||
var literalline = pp.literalline;
|
||||
var group = pp.group;
|
||||
var multilineGroup = pp.multilineGroup;
|
||||
var indent = pp.indent;
|
||||
var getFirstString = pp.getFirstString;
|
||||
var hasHardLine = pp.hasHardLine;
|
||||
var conditionalGroup = pp.conditionalGroup;
|
||||
var ifBreak = pp.ifBreak;
|
||||
var types = require("ast-types");
|
||||
var namedTypes = types.namedTypes;
|
||||
var isString = types.builtInTypes.string;
|
||||
var isObject = types.builtInTypes.object;
|
||||
var FastPath = require("./fast-path");
|
||||
var util = require("./util");
|
||||
var isIdentifierName = require("esutils").keyword.isIdentifierNameES6;
|
||||
var jsesc = require("jsesc");
|
||||
|
||||
var docBuilders = require("./doc-builders");
|
||||
var fromString = docBuilders.fromString;
|
||||
var concat = docBuilders.concat;
|
||||
var join = docBuilders.join;
|
||||
var line = docBuilders.line;
|
||||
var hardline = docBuilders.hardline;
|
||||
var softline = docBuilders.softline;
|
||||
var literalline = docBuilders.literalline;
|
||||
var group = docBuilders.group;
|
||||
var multilineGroup = docBuilders.multilineGroup;
|
||||
var indent = docBuilders.indent;
|
||||
var conditionalGroup = docBuilders.conditionalGroup;
|
||||
var ifBreak = docBuilders.ifBreak;
|
||||
|
||||
var docUtils = require("./doc-utils");
|
||||
var hasHardLine = docUtils.hasHardLine;
|
||||
var getFirstString = docUtils.getFirstString;
|
||||
var isEmpty = docUtils.isEmpty;
|
||||
|
||||
var types = require("ast-types");
|
||||
var namedTypes = types.namedTypes;
|
||||
var isString = types.builtInTypes.string;
|
||||
var isObject = types.builtInTypes.object;
|
||||
|
||||
function maybeAddParens(path, lines) {
|
||||
return path.needsParens() ? concat([ "(", lines, ")" ]) : lines;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue