$
This commit is contained in:
2
node_modules/recast/lib/comments.d.ts
generated
vendored
Normal file
2
node_modules/recast/lib/comments.d.ts
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
export declare function attach(comments: any[], ast: any, lines: any): void;
|
||||
export declare function printComments(path: any, print: any): any;
|
306
node_modules/recast/lib/comments.js
generated
vendored
Normal file
306
node_modules/recast/lib/comments.js
generated
vendored
Normal file
@@ -0,0 +1,306 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.printComments = exports.attach = void 0;
|
||||
var tslib_1 = require("tslib");
|
||||
var assert_1 = tslib_1.__importDefault(require("assert"));
|
||||
var types = tslib_1.__importStar(require("ast-types"));
|
||||
var n = types.namedTypes;
|
||||
var isArray = types.builtInTypes.array;
|
||||
var isObject = types.builtInTypes.object;
|
||||
var lines_1 = require("./lines");
|
||||
var util_1 = require("./util");
|
||||
var childNodesCache = new WeakMap();
|
||||
// TODO Move a non-caching implementation of this function into ast-types,
|
||||
// and implement a caching wrapper function here.
|
||||
function getSortedChildNodes(node, lines, resultArray) {
|
||||
if (!node) {
|
||||
return resultArray;
|
||||
}
|
||||
// The .loc checks below are sensitive to some of the problems that
|
||||
// are fixed by this utility function. Specifically, if it decides to
|
||||
// set node.loc to null, indicating that the node's .loc information
|
||||
// is unreliable, then we don't want to add node to the resultArray.
|
||||
util_1.fixFaultyLocations(node, lines);
|
||||
if (resultArray) {
|
||||
if (n.Node.check(node) && n.SourceLocation.check(node.loc)) {
|
||||
// This reverse insertion sort almost always takes constant
|
||||
// time because we almost always (maybe always?) append the
|
||||
// nodes in order anyway.
|
||||
var i = resultArray.length - 1;
|
||||
for (; i >= 0; --i) {
|
||||
var child = resultArray[i];
|
||||
if (child &&
|
||||
child.loc &&
|
||||
util_1.comparePos(child.loc.end, node.loc.start) <= 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
resultArray.splice(i + 1, 0, node);
|
||||
return resultArray;
|
||||
}
|
||||
}
|
||||
else {
|
||||
var childNodes = childNodesCache.get(node);
|
||||
if (childNodes) {
|
||||
return childNodes;
|
||||
}
|
||||
}
|
||||
var names;
|
||||
if (isArray.check(node)) {
|
||||
names = Object.keys(node);
|
||||
}
|
||||
else if (isObject.check(node)) {
|
||||
names = types.getFieldNames(node);
|
||||
}
|
||||
else {
|
||||
return resultArray;
|
||||
}
|
||||
if (!resultArray) {
|
||||
childNodesCache.set(node, (resultArray = []));
|
||||
}
|
||||
for (var i = 0, nameCount = names.length; i < nameCount; ++i) {
|
||||
getSortedChildNodes(node[names[i]], lines, resultArray);
|
||||
}
|
||||
return 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, lines) {
|
||||
var childNodes = getSortedChildNodes(node, lines);
|
||||
// Time to dust off the old binary search robes and wizard hat.
|
||||
var left = 0;
|
||||
var right = childNodes && childNodes.length;
|
||||
var precedingNode;
|
||||
var followingNode;
|
||||
while (typeof right === "number" && left < right) {
|
||||
var middle = (left + right) >> 1;
|
||||
var child = childNodes[middle];
|
||||
if (util_1.comparePos(child.loc.start, comment.loc.start) <= 0 &&
|
||||
util_1.comparePos(comment.loc.end, child.loc.end) <= 0) {
|
||||
// The comment is completely contained by this child node.
|
||||
decorateComment((comment.enclosingNode = child), comment, lines);
|
||||
return; // Abandon the binary search at this level.
|
||||
}
|
||||
if (util_1.comparePos(child.loc.end, comment.loc.start) <= 0) {
|
||||
// This child node falls completely before the comment.
|
||||
// Because we will never consider this node or any nodes
|
||||
// before it again, this node must be the closest preceding
|
||||
// node we have encountered so far.
|
||||
precedingNode = child;
|
||||
left = middle + 1;
|
||||
continue;
|
||||
}
|
||||
if (util_1.comparePos(comment.loc.end, child.loc.start) <= 0) {
|
||||
// This child node falls completely after the comment.
|
||||
// Because we will never consider this node or any nodes after
|
||||
// it again, this node must be the closest following node we
|
||||
// have encountered so far.
|
||||
followingNode = child;
|
||||
right = middle;
|
||||
continue;
|
||||
}
|
||||
throw new Error("Comment location overlaps with node location");
|
||||
}
|
||||
if (precedingNode) {
|
||||
comment.precedingNode = precedingNode;
|
||||
}
|
||||
if (followingNode) {
|
||||
comment.followingNode = followingNode;
|
||||
}
|
||||
}
|
||||
function attach(comments, ast, lines) {
|
||||
if (!isArray.check(comments)) {
|
||||
return;
|
||||
}
|
||||
var tiesToBreak = [];
|
||||
comments.forEach(function (comment) {
|
||||
comment.loc.lines = lines;
|
||||
decorateComment(ast, comment, lines);
|
||||
var pn = comment.precedingNode;
|
||||
var en = comment.enclosingNode;
|
||||
var fn = comment.followingNode;
|
||||
if (pn && fn) {
|
||||
var tieCount = tiesToBreak.length;
|
||||
if (tieCount > 0) {
|
||||
var lastTie = tiesToBreak[tieCount - 1];
|
||||
assert_1.default.strictEqual(lastTie.precedingNode === comment.precedingNode, lastTie.followingNode === comment.followingNode);
|
||||
if (lastTie.followingNode !== comment.followingNode) {
|
||||
breakTies(tiesToBreak, lines);
|
||||
}
|
||||
}
|
||||
tiesToBreak.push(comment);
|
||||
}
|
||||
else if (pn) {
|
||||
// No contest: we have a trailing comment.
|
||||
breakTies(tiesToBreak, lines);
|
||||
addTrailingComment(pn, comment);
|
||||
}
|
||||
else if (fn) {
|
||||
// No contest: we have a leading comment.
|
||||
breakTies(tiesToBreak, lines);
|
||||
addLeadingComment(fn, comment);
|
||||
}
|
||||
else if (en) {
|
||||
// The enclosing node has no child nodes at all, so what we
|
||||
// have here is a dangling comment, e.g. [/* crickets */].
|
||||
breakTies(tiesToBreak, lines);
|
||||
addDanglingComment(en, comment);
|
||||
}
|
||||
else {
|
||||
throw new Error("AST contains no nodes at all?");
|
||||
}
|
||||
});
|
||||
breakTies(tiesToBreak, lines);
|
||||
comments.forEach(function (comment) {
|
||||
// These node references were useful for breaking ties, but we
|
||||
// don't need them anymore, and they create cycles in the AST that
|
||||
// may lead to infinite recursion if we don't delete them here.
|
||||
delete comment.precedingNode;
|
||||
delete comment.enclosingNode;
|
||||
delete comment.followingNode;
|
||||
});
|
||||
}
|
||||
exports.attach = attach;
|
||||
function breakTies(tiesToBreak, lines) {
|
||||
var tieCount = tiesToBreak.length;
|
||||
if (tieCount === 0) {
|
||||
return;
|
||||
}
|
||||
var pn = tiesToBreak[0].precedingNode;
|
||||
var fn = tiesToBreak[0].followingNode;
|
||||
var gapEndPos = fn.loc.start;
|
||||
// Iterate backwards through tiesToBreak, examining the gaps
|
||||
// between the tied comments. In order to qualify as leading, a
|
||||
// comment must be separated from fn by an unbroken series of
|
||||
// whitespace-only gaps (or other comments).
|
||||
var indexOfFirstLeadingComment = tieCount;
|
||||
var comment;
|
||||
for (; indexOfFirstLeadingComment > 0; --indexOfFirstLeadingComment) {
|
||||
comment = tiesToBreak[indexOfFirstLeadingComment - 1];
|
||||
assert_1.default.strictEqual(comment.precedingNode, pn);
|
||||
assert_1.default.strictEqual(comment.followingNode, fn);
|
||||
var gap = lines.sliceString(comment.loc.end, gapEndPos);
|
||||
if (/\S/.test(gap)) {
|
||||
// The gap string contained something other than whitespace.
|
||||
break;
|
||||
}
|
||||
gapEndPos = comment.loc.start;
|
||||
}
|
||||
while (indexOfFirstLeadingComment <= tieCount &&
|
||||
(comment = tiesToBreak[indexOfFirstLeadingComment]) &&
|
||||
// If the comment is a //-style comment and indented more
|
||||
// deeply than the node itself, reconsider it as trailing.
|
||||
(comment.type === "Line" || comment.type === "CommentLine") &&
|
||||
comment.loc.start.column > fn.loc.start.column) {
|
||||
++indexOfFirstLeadingComment;
|
||||
}
|
||||
tiesToBreak.forEach(function (comment, i) {
|
||||
if (i < indexOfFirstLeadingComment) {
|
||||
addTrailingComment(pn, comment);
|
||||
}
|
||||
else {
|
||||
addLeadingComment(fn, comment);
|
||||
}
|
||||
});
|
||||
tiesToBreak.length = 0;
|
||||
}
|
||||
function addCommentHelper(node, comment) {
|
||||
var comments = node.comments || (node.comments = []);
|
||||
comments.push(comment);
|
||||
}
|
||||
function addLeadingComment(node, comment) {
|
||||
comment.leading = true;
|
||||
comment.trailing = false;
|
||||
addCommentHelper(node, comment);
|
||||
}
|
||||
function addDanglingComment(node, comment) {
|
||||
comment.leading = false;
|
||||
comment.trailing = false;
|
||||
addCommentHelper(node, comment);
|
||||
}
|
||||
function addTrailingComment(node, comment) {
|
||||
comment.leading = false;
|
||||
comment.trailing = true;
|
||||
addCommentHelper(node, comment);
|
||||
}
|
||||
function printLeadingComment(commentPath, print) {
|
||||
var comment = commentPath.getValue();
|
||||
n.Comment.assert(comment);
|
||||
var loc = comment.loc;
|
||||
var lines = loc && loc.lines;
|
||||
var parts = [print(commentPath)];
|
||||
if (comment.trailing) {
|
||||
// When we print trailing comments as leading comments, we don't
|
||||
// want to bring any trailing spaces along.
|
||||
parts.push("\n");
|
||||
}
|
||||
else if (lines instanceof lines_1.Lines) {
|
||||
var trailingSpace = lines.slice(loc.end, lines.skipSpaces(loc.end) || lines.lastPos());
|
||||
if (trailingSpace.length === 1) {
|
||||
// If the trailing space contains no newlines, then we want to
|
||||
// preserve it exactly as we found it.
|
||||
parts.push(trailingSpace);
|
||||
}
|
||||
else {
|
||||
// If the trailing space contains newlines, then replace it
|
||||
// with just that many newlines, with all other spaces removed.
|
||||
parts.push(new Array(trailingSpace.length).join("\n"));
|
||||
}
|
||||
}
|
||||
else {
|
||||
parts.push("\n");
|
||||
}
|
||||
return lines_1.concat(parts);
|
||||
}
|
||||
function printTrailingComment(commentPath, print) {
|
||||
var comment = commentPath.getValue(commentPath);
|
||||
n.Comment.assert(comment);
|
||||
var loc = comment.loc;
|
||||
var lines = loc && loc.lines;
|
||||
var parts = [];
|
||||
if (lines instanceof lines_1.Lines) {
|
||||
var fromPos = lines.skipSpaces(loc.start, true) || lines.firstPos();
|
||||
var leadingSpace = lines.slice(fromPos, loc.start);
|
||||
if (leadingSpace.length === 1) {
|
||||
// If the leading space contains no newlines, then we want to
|
||||
// preserve it exactly as we found it.
|
||||
parts.push(leadingSpace);
|
||||
}
|
||||
else {
|
||||
// If the leading space contains newlines, then replace it
|
||||
// with just that many newlines, sans all other spaces.
|
||||
parts.push(new Array(leadingSpace.length).join("\n"));
|
||||
}
|
||||
}
|
||||
parts.push(print(commentPath));
|
||||
return lines_1.concat(parts);
|
||||
}
|
||||
function printComments(path, print) {
|
||||
var value = path.getValue();
|
||||
var innerLines = print(path);
|
||||
var comments = n.Node.check(value) && types.getFieldValue(value, "comments");
|
||||
if (!comments || comments.length === 0) {
|
||||
return innerLines;
|
||||
}
|
||||
var leadingParts = [];
|
||||
var trailingParts = [innerLines];
|
||||
path.each(function (commentPath) {
|
||||
var comment = commentPath.getValue();
|
||||
var leading = types.getFieldValue(comment, "leading");
|
||||
var trailing = types.getFieldValue(comment, "trailing");
|
||||
if (leading ||
|
||||
(trailing &&
|
||||
!(n.Statement.check(value) ||
|
||||
comment.type === "Block" ||
|
||||
comment.type === "CommentBlock"))) {
|
||||
leadingParts.push(printLeadingComment(commentPath, print));
|
||||
}
|
||||
else if (trailing) {
|
||||
trailingParts.push(printTrailingComment(commentPath, print));
|
||||
}
|
||||
}, "comments");
|
||||
leadingParts.push.apply(leadingParts, trailingParts);
|
||||
return lines_1.concat(leadingParts);
|
||||
}
|
||||
exports.printComments = printComments;
|
25
node_modules/recast/lib/fast-path.d.ts
generated
vendored
Normal file
25
node_modules/recast/lib/fast-path.d.ts
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
interface FastPathType {
|
||||
stack: any[];
|
||||
copy(): any;
|
||||
getName(): any;
|
||||
getValue(): any;
|
||||
valueIsDuplicate(): any;
|
||||
getNode(count?: number): any;
|
||||
getParentNode(count?: number): any;
|
||||
getRootValue(): any;
|
||||
call(callback: any, ...names: any[]): any;
|
||||
each(callback: any, ...names: any[]): any;
|
||||
map(callback: any, ...names: any[]): any;
|
||||
hasParens(): any;
|
||||
getPrevToken(node: any): any;
|
||||
getNextToken(node: any): any;
|
||||
needsParens(assumeExpressionContext?: boolean): any;
|
||||
canBeFirstInStatement(): any;
|
||||
firstInStatement(): any;
|
||||
}
|
||||
interface FastPathConstructor {
|
||||
new (value: any): FastPathType;
|
||||
from(obj: any): any;
|
||||
}
|
||||
declare const FastPath: FastPathConstructor;
|
||||
export default FastPath;
|
527
node_modules/recast/lib/fast-path.js
generated
vendored
Normal file
527
node_modules/recast/lib/fast-path.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
62
node_modules/recast/lib/lines.d.ts
generated
vendored
Normal file
62
node_modules/recast/lib/lines.d.ts
generated
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
import { Options } from "./options";
|
||||
import { namedTypes } from "ast-types";
|
||||
declare type Pos = namedTypes.Position;
|
||||
declare type LineInfo = {
|
||||
readonly line: string;
|
||||
readonly indent: number;
|
||||
readonly locked: boolean;
|
||||
readonly sliceStart: number;
|
||||
readonly sliceEnd: number;
|
||||
};
|
||||
export declare class Lines {
|
||||
private infos;
|
||||
readonly length: number;
|
||||
readonly name: string | null;
|
||||
private mappings;
|
||||
private cachedSourceMap;
|
||||
private cachedTabWidth;
|
||||
constructor(infos: LineInfo[], sourceFileName?: string | null);
|
||||
toString(options?: Options): string;
|
||||
getSourceMap(sourceMapName: string, sourceRoot?: string): any;
|
||||
bootstrapCharAt(pos: Pos): string;
|
||||
charAt(pos: Pos): string;
|
||||
stripMargin(width: number, skipFirstLine: boolean): Lines;
|
||||
indent(by: number): Lines;
|
||||
indentTail(by: number): Lines;
|
||||
lockIndentTail(): Lines;
|
||||
getIndentAt(line: number): number;
|
||||
guessTabWidth(): number;
|
||||
startsWithComment(): boolean;
|
||||
isOnlyWhitespace(): boolean;
|
||||
isPrecededOnlyByWhitespace(pos: Pos): boolean;
|
||||
getLineLength(line: number): number;
|
||||
nextPos(pos: Pos, skipSpaces?: boolean): boolean;
|
||||
prevPos(pos: Pos, skipSpaces?: boolean): boolean;
|
||||
firstPos(): {
|
||||
line: number;
|
||||
column: number;
|
||||
};
|
||||
lastPos(): {
|
||||
line: number;
|
||||
column: number;
|
||||
};
|
||||
skipSpaces(pos: Pos, backward?: boolean, modifyInPlace?: boolean): namedTypes.Position | null;
|
||||
trimLeft(): Lines;
|
||||
trimRight(): Lines;
|
||||
trim(): Lines;
|
||||
eachPos(callback: (pos: Pos) => any, startPos?: Pos, skipSpaces?: boolean): void;
|
||||
bootstrapSlice(start: Pos, end: Pos): Lines;
|
||||
slice(start?: Pos, end?: Pos): Lines;
|
||||
bootstrapSliceString(start: Pos, end: Pos, options?: Options): string;
|
||||
sliceString(start?: Pos, end?: Pos, options?: Options): string;
|
||||
isEmpty(): boolean;
|
||||
join(elements: (string | Lines)[]): Lines;
|
||||
concat(...args: (string | Lines)[]): Lines;
|
||||
}
|
||||
export declare function countSpaces(spaces: any, tabWidth?: number): number;
|
||||
/**
|
||||
* @param {Object} options - Options object that configures printing.
|
||||
*/
|
||||
export declare function fromString(string: string | Lines, options?: Options): Lines;
|
||||
export declare function concat(elements: any): Lines;
|
||||
export {};
|
654
node_modules/recast/lib/lines.js
generated
vendored
Normal file
654
node_modules/recast/lib/lines.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
15
node_modules/recast/lib/mapping.d.ts
generated
vendored
Normal file
15
node_modules/recast/lib/mapping.d.ts
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
import { namedTypes } from "ast-types";
|
||||
import { Lines } from "./lines";
|
||||
declare type Pos = namedTypes.Position;
|
||||
declare type Loc = namedTypes.SourceLocation;
|
||||
export default class Mapping {
|
||||
sourceLines: Lines;
|
||||
sourceLoc: Loc;
|
||||
targetLoc: Loc;
|
||||
constructor(sourceLines: Lines, sourceLoc: Loc, targetLoc?: Loc);
|
||||
slice(lines: Lines, start: Pos, end?: Pos): Mapping | null;
|
||||
add(line: number, column: number): Mapping;
|
||||
subtract(line: number, column: number): Mapping;
|
||||
indent(by: number, skipFirstLine?: boolean, noNegativeColumns?: boolean): Mapping;
|
||||
}
|
||||
export {};
|
197
node_modules/recast/lib/mapping.js
generated
vendored
Normal file
197
node_modules/recast/lib/mapping.js
generated
vendored
Normal file
@@ -0,0 +1,197 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var tslib_1 = require("tslib");
|
||||
var assert_1 = tslib_1.__importDefault(require("assert"));
|
||||
var util_1 = require("./util");
|
||||
var Mapping = /** @class */ (function () {
|
||||
function Mapping(sourceLines, sourceLoc, targetLoc) {
|
||||
if (targetLoc === void 0) { targetLoc = sourceLoc; }
|
||||
this.sourceLines = sourceLines;
|
||||
this.sourceLoc = sourceLoc;
|
||||
this.targetLoc = targetLoc;
|
||||
}
|
||||
Mapping.prototype.slice = function (lines, start, end) {
|
||||
if (end === void 0) { end = lines.lastPos(); }
|
||||
var sourceLines = this.sourceLines;
|
||||
var sourceLoc = this.sourceLoc;
|
||||
var targetLoc = this.targetLoc;
|
||||
function skip(name) {
|
||||
var sourceFromPos = sourceLoc[name];
|
||||
var targetFromPos = targetLoc[name];
|
||||
var targetToPos = start;
|
||||
if (name === "end") {
|
||||
targetToPos = end;
|
||||
}
|
||||
else {
|
||||
assert_1.default.strictEqual(name, "start");
|
||||
}
|
||||
return skipChars(sourceLines, sourceFromPos, lines, targetFromPos, targetToPos);
|
||||
}
|
||||
if (util_1.comparePos(start, targetLoc.start) <= 0) {
|
||||
if (util_1.comparePos(targetLoc.end, end) <= 0) {
|
||||
targetLoc = {
|
||||
start: subtractPos(targetLoc.start, start.line, start.column),
|
||||
end: subtractPos(targetLoc.end, start.line, start.column),
|
||||
};
|
||||
// The sourceLoc can stay the same because the contents of the
|
||||
// targetLoc have not changed.
|
||||
}
|
||||
else if (util_1.comparePos(end, targetLoc.start) <= 0) {
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
sourceLoc = {
|
||||
start: sourceLoc.start,
|
||||
end: skip("end"),
|
||||
};
|
||||
targetLoc = {
|
||||
start: subtractPos(targetLoc.start, start.line, start.column),
|
||||
end: subtractPos(end, start.line, start.column),
|
||||
};
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (util_1.comparePos(targetLoc.end, start) <= 0) {
|
||||
return null;
|
||||
}
|
||||
if (util_1.comparePos(targetLoc.end, end) <= 0) {
|
||||
sourceLoc = {
|
||||
start: skip("start"),
|
||||
end: sourceLoc.end,
|
||||
};
|
||||
targetLoc = {
|
||||
// Same as subtractPos(start, start.line, start.column):
|
||||
start: { line: 1, column: 0 },
|
||||
end: subtractPos(targetLoc.end, start.line, start.column),
|
||||
};
|
||||
}
|
||||
else {
|
||||
sourceLoc = {
|
||||
start: skip("start"),
|
||||
end: skip("end"),
|
||||
};
|
||||
targetLoc = {
|
||||
// Same as subtractPos(start, start.line, start.column):
|
||||
start: { line: 1, column: 0 },
|
||||
end: subtractPos(end, start.line, start.column),
|
||||
};
|
||||
}
|
||||
}
|
||||
return new Mapping(this.sourceLines, sourceLoc, targetLoc);
|
||||
};
|
||||
Mapping.prototype.add = function (line, column) {
|
||||
return new Mapping(this.sourceLines, this.sourceLoc, {
|
||||
start: addPos(this.targetLoc.start, line, column),
|
||||
end: addPos(this.targetLoc.end, line, column),
|
||||
});
|
||||
};
|
||||
Mapping.prototype.subtract = function (line, column) {
|
||||
return new Mapping(this.sourceLines, this.sourceLoc, {
|
||||
start: subtractPos(this.targetLoc.start, line, column),
|
||||
end: subtractPos(this.targetLoc.end, line, column),
|
||||
});
|
||||
};
|
||||
Mapping.prototype.indent = function (by, skipFirstLine, noNegativeColumns) {
|
||||
if (skipFirstLine === void 0) { skipFirstLine = false; }
|
||||
if (noNegativeColumns === void 0) { noNegativeColumns = false; }
|
||||
if (by === 0) {
|
||||
return this;
|
||||
}
|
||||
var targetLoc = this.targetLoc;
|
||||
var startLine = targetLoc.start.line;
|
||||
var endLine = targetLoc.end.line;
|
||||
if (skipFirstLine && startLine === 1 && endLine === 1) {
|
||||
return this;
|
||||
}
|
||||
targetLoc = {
|
||||
start: targetLoc.start,
|
||||
end: targetLoc.end,
|
||||
};
|
||||
if (!skipFirstLine || startLine > 1) {
|
||||
var startColumn = targetLoc.start.column + by;
|
||||
targetLoc.start = {
|
||||
line: startLine,
|
||||
column: noNegativeColumns ? Math.max(0, startColumn) : startColumn,
|
||||
};
|
||||
}
|
||||
if (!skipFirstLine || endLine > 1) {
|
||||
var endColumn = targetLoc.end.column + by;
|
||||
targetLoc.end = {
|
||||
line: endLine,
|
||||
column: noNegativeColumns ? Math.max(0, endColumn) : endColumn,
|
||||
};
|
||||
}
|
||||
return new Mapping(this.sourceLines, this.sourceLoc, targetLoc);
|
||||
};
|
||||
return Mapping;
|
||||
}());
|
||||
exports.default = Mapping;
|
||||
function addPos(toPos, line, column) {
|
||||
return {
|
||||
line: toPos.line + line - 1,
|
||||
column: toPos.line === 1 ? toPos.column + column : toPos.column,
|
||||
};
|
||||
}
|
||||
function subtractPos(fromPos, line, column) {
|
||||
return {
|
||||
line: fromPos.line - line + 1,
|
||||
column: fromPos.line === line ? fromPos.column - column : fromPos.column,
|
||||
};
|
||||
}
|
||||
function skipChars(sourceLines, sourceFromPos, targetLines, targetFromPos, targetToPos) {
|
||||
var targetComparison = util_1.comparePos(targetFromPos, targetToPos);
|
||||
if (targetComparison === 0) {
|
||||
// Trivial case: no characters to skip.
|
||||
return sourceFromPos;
|
||||
}
|
||||
var sourceCursor, targetCursor;
|
||||
if (targetComparison < 0) {
|
||||
// Skipping forward.
|
||||
sourceCursor =
|
||||
sourceLines.skipSpaces(sourceFromPos) || sourceLines.lastPos();
|
||||
targetCursor =
|
||||
targetLines.skipSpaces(targetFromPos) || targetLines.lastPos();
|
||||
var lineDiff = targetToPos.line - targetCursor.line;
|
||||
sourceCursor.line += lineDiff;
|
||||
targetCursor.line += lineDiff;
|
||||
if (lineDiff > 0) {
|
||||
// If jumping to later lines, reset columns to the beginnings
|
||||
// of those lines.
|
||||
sourceCursor.column = 0;
|
||||
targetCursor.column = 0;
|
||||
}
|
||||
else {
|
||||
assert_1.default.strictEqual(lineDiff, 0);
|
||||
}
|
||||
while (util_1.comparePos(targetCursor, targetToPos) < 0 &&
|
||||
targetLines.nextPos(targetCursor, true)) {
|
||||
assert_1.default.ok(sourceLines.nextPos(sourceCursor, true));
|
||||
assert_1.default.strictEqual(sourceLines.charAt(sourceCursor), targetLines.charAt(targetCursor));
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Skipping backward.
|
||||
sourceCursor =
|
||||
sourceLines.skipSpaces(sourceFromPos, true) || sourceLines.firstPos();
|
||||
targetCursor =
|
||||
targetLines.skipSpaces(targetFromPos, true) || targetLines.firstPos();
|
||||
var lineDiff = targetToPos.line - targetCursor.line;
|
||||
sourceCursor.line += lineDiff;
|
||||
targetCursor.line += lineDiff;
|
||||
if (lineDiff < 0) {
|
||||
// If jumping to earlier lines, reset columns to the ends of
|
||||
// those lines.
|
||||
sourceCursor.column = sourceLines.getLineLength(sourceCursor.line);
|
||||
targetCursor.column = targetLines.getLineLength(targetCursor.line);
|
||||
}
|
||||
else {
|
||||
assert_1.default.strictEqual(lineDiff, 0);
|
||||
}
|
||||
while (util_1.comparePos(targetToPos, targetCursor) < 0 &&
|
||||
targetLines.prevPos(targetCursor, true)) {
|
||||
assert_1.default.ok(sourceLines.prevPos(sourceCursor, true));
|
||||
assert_1.default.strictEqual(sourceLines.charAt(sourceCursor), targetLines.charAt(targetCursor));
|
||||
}
|
||||
}
|
||||
return sourceCursor;
|
||||
}
|
148
node_modules/recast/lib/options.d.ts
generated
vendored
Normal file
148
node_modules/recast/lib/options.d.ts
generated
vendored
Normal file
@@ -0,0 +1,148 @@
|
||||
import { Omit } from "ast-types/types";
|
||||
/**
|
||||
* All Recast API functions take second parameter with configuration options,
|
||||
* documented in options.js
|
||||
*/
|
||||
export interface Options extends DeprecatedOptions {
|
||||
/**
|
||||
* If you want to use a different branch of esprima, or any other module
|
||||
* that supports a .parse function, pass that module object to
|
||||
* recast.parse as options.parser (legacy synonym: options.esprima).
|
||||
* @default require("recast/parsers/esprima")
|
||||
*/
|
||||
parser?: any;
|
||||
/**
|
||||
* Number of spaces the pretty-printer should use per tab for
|
||||
* indentation. If you do not pass this option explicitly, it will be
|
||||
* (quite reliably!) inferred from the original code.
|
||||
* @default 4
|
||||
*/
|
||||
tabWidth?: number;
|
||||
/**
|
||||
* If you really want the pretty-printer to use tabs instead of spaces,
|
||||
* make this option true.
|
||||
* @default false
|
||||
*/
|
||||
useTabs?: boolean;
|
||||
/**
|
||||
* The reprinting code leaves leading whitespace untouched unless it has
|
||||
* to reindent a line, or you pass false for this option.
|
||||
* @default true
|
||||
*/
|
||||
reuseWhitespace?: boolean;
|
||||
/**
|
||||
* Override this option to use a different line terminator, e.g. \r\n.
|
||||
* @default require("os").EOL || "\n"
|
||||
*/
|
||||
lineTerminator?: string;
|
||||
/**
|
||||
* Some of the pretty-printer code (such as that for printing function
|
||||
* parameter lists) makes a valiant attempt to prevent really long
|
||||
* lines. You can adjust the limit by changing this option; however,
|
||||
* there is no guarantee that line length will fit inside this limit.
|
||||
* @default 74
|
||||
*/
|
||||
wrapColumn?: number;
|
||||
/**
|
||||
* Pass a string as options.sourceFileName to recast.parse to tell the
|
||||
* reprinter to keep track of reused code so that it can construct a
|
||||
* source map automatically.
|
||||
* @default null
|
||||
*/
|
||||
sourceFileName?: string | null;
|
||||
/**
|
||||
* Pass a string as options.sourceMapName to recast.print, and (provided
|
||||
* you passed options.sourceFileName earlier) the PrintResult of
|
||||
* recast.print will have a .map property for the generated source map.
|
||||
* @default null
|
||||
*/
|
||||
sourceMapName?: string | null;
|
||||
/**
|
||||
* If provided, this option will be passed along to the source map
|
||||
* generator as a root directory for relative source file paths.
|
||||
* @default null
|
||||
*/
|
||||
sourceRoot?: string | null;
|
||||
/**
|
||||
* If you provide a source map that was generated from a previous call
|
||||
* to recast.print as options.inputSourceMap, the old source map will be
|
||||
* composed with the new source map.
|
||||
* @default null
|
||||
*/
|
||||
inputSourceMap?: string | null;
|
||||
/**
|
||||
* If you want esprima to generate .range information (recast only uses
|
||||
* .loc internally), pass true for this option.
|
||||
* @default false
|
||||
*/
|
||||
range?: boolean;
|
||||
/**
|
||||
* If you want esprima not to throw exceptions when it encounters
|
||||
* non-fatal errors, keep this option true.
|
||||
* @default true
|
||||
*/
|
||||
tolerant?: boolean;
|
||||
/**
|
||||
* If you want to override the quotes used in string literals, specify
|
||||
* either "single", "double", or "auto" here ("auto" will select the one
|
||||
* which results in the shorter literal) Otherwise, use double quotes.
|
||||
* @default null
|
||||
*/
|
||||
quote?: "single" | "double" | "auto" | null;
|
||||
/**
|
||||
* Controls the printing of trailing commas in object literals, array
|
||||
* expressions and function parameters.
|
||||
*
|
||||
* This option could either be:
|
||||
* * Boolean - enable/disable in all contexts (objects, arrays and function params).
|
||||
* * Object - enable/disable per context.
|
||||
*
|
||||
* Example:
|
||||
* trailingComma: {
|
||||
* objects: true,
|
||||
* arrays: true,
|
||||
* parameters: false,
|
||||
* }
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
trailingComma?: boolean;
|
||||
/**
|
||||
* Controls the printing of spaces inside array brackets.
|
||||
* See: http://eslint.org/docs/rules/array-bracket-spacing
|
||||
* @default false
|
||||
*/
|
||||
arrayBracketSpacing?: boolean;
|
||||
/**
|
||||
* Controls the printing of spaces inside object literals,
|
||||
* destructuring assignments, and import/export specifiers.
|
||||
* See: http://eslint.org/docs/rules/object-curly-spacing
|
||||
* @default true
|
||||
*/
|
||||
objectCurlySpacing?: boolean;
|
||||
/**
|
||||
* If you want parenthesis to wrap single-argument arrow function
|
||||
* parameter lists, pass true for this option.
|
||||
* @default false
|
||||
*/
|
||||
arrowParensAlways?: boolean;
|
||||
/**
|
||||
* There are 2 supported syntaxes (`,` and `;`) in Flow Object Types;
|
||||
* The use of commas is in line with the more popular style and matches
|
||||
* how objects are defined in JS, making it a bit more natural to write.
|
||||
* @default true
|
||||
*/
|
||||
flowObjectCommas?: boolean;
|
||||
/**
|
||||
* Whether to return an array of .tokens on the root AST node.
|
||||
* @default true
|
||||
*/
|
||||
tokens?: boolean;
|
||||
}
|
||||
interface DeprecatedOptions {
|
||||
/** @deprecated */
|
||||
esprima?: any;
|
||||
}
|
||||
export declare type NormalizedOptions = Required<Omit<Options, keyof DeprecatedOptions>>;
|
||||
export declare function normalize(opts?: Options): NormalizedOptions;
|
||||
export {};
|
54
node_modules/recast/lib/options.js
generated
vendored
Normal file
54
node_modules/recast/lib/options.js
generated
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.normalize = void 0;
|
||||
var defaults = {
|
||||
parser: require("../parsers/esprima"),
|
||||
tabWidth: 4,
|
||||
useTabs: false,
|
||||
reuseWhitespace: true,
|
||||
lineTerminator: require("os").EOL || "\n",
|
||||
wrapColumn: 74,
|
||||
sourceFileName: null,
|
||||
sourceMapName: null,
|
||||
sourceRoot: null,
|
||||
inputSourceMap: null,
|
||||
range: false,
|
||||
tolerant: true,
|
||||
quote: null,
|
||||
trailingComma: false,
|
||||
arrayBracketSpacing: false,
|
||||
objectCurlySpacing: true,
|
||||
arrowParensAlways: false,
|
||||
flowObjectCommas: true,
|
||||
tokens: true,
|
||||
};
|
||||
var hasOwn = defaults.hasOwnProperty;
|
||||
// Copy options and fill in default values.
|
||||
function normalize(opts) {
|
||||
var options = opts || defaults;
|
||||
function get(key) {
|
||||
return hasOwn.call(options, key) ? options[key] : defaults[key];
|
||||
}
|
||||
return {
|
||||
tabWidth: +get("tabWidth"),
|
||||
useTabs: !!get("useTabs"),
|
||||
reuseWhitespace: !!get("reuseWhitespace"),
|
||||
lineTerminator: get("lineTerminator"),
|
||||
wrapColumn: Math.max(get("wrapColumn"), 0),
|
||||
sourceFileName: get("sourceFileName"),
|
||||
sourceMapName: get("sourceMapName"),
|
||||
sourceRoot: get("sourceRoot"),
|
||||
inputSourceMap: get("inputSourceMap"),
|
||||
parser: get("esprima") || get("parser"),
|
||||
range: get("range"),
|
||||
tolerant: get("tolerant"),
|
||||
quote: get("quote"),
|
||||
trailingComma: get("trailingComma"),
|
||||
arrayBracketSpacing: get("arrayBracketSpacing"),
|
||||
objectCurlySpacing: get("objectCurlySpacing"),
|
||||
arrowParensAlways: get("arrowParensAlways"),
|
||||
flowObjectCommas: get("flowObjectCommas"),
|
||||
tokens: !!get("tokens"),
|
||||
};
|
||||
}
|
||||
exports.normalize = normalize;
|
2
node_modules/recast/lib/parser.d.ts
generated
vendored
Normal file
2
node_modules/recast/lib/parser.d.ts
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
import { Options } from "./options";
|
||||
export declare function parse(source: string, options?: Partial<Options>): any;
|
250
node_modules/recast/lib/parser.js
generated
vendored
Normal file
250
node_modules/recast/lib/parser.js
generated
vendored
Normal file
@@ -0,0 +1,250 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.parse = void 0;
|
||||
var tslib_1 = require("tslib");
|
||||
var assert_1 = tslib_1.__importDefault(require("assert"));
|
||||
var types = tslib_1.__importStar(require("ast-types"));
|
||||
var b = types.builders;
|
||||
var isObject = types.builtInTypes.object;
|
||||
var isArray = types.builtInTypes.array;
|
||||
var options_1 = require("./options");
|
||||
var lines_1 = require("./lines");
|
||||
var comments_1 = require("./comments");
|
||||
var util = tslib_1.__importStar(require("./util"));
|
||||
function parse(source, options) {
|
||||
options = options_1.normalize(options);
|
||||
var lines = lines_1.fromString(source, options);
|
||||
var sourceWithoutTabs = lines.toString({
|
||||
tabWidth: options.tabWidth,
|
||||
reuseWhitespace: false,
|
||||
useTabs: false,
|
||||
});
|
||||
var comments = [];
|
||||
var ast = options.parser.parse(sourceWithoutTabs, {
|
||||
jsx: true,
|
||||
loc: true,
|
||||
locations: true,
|
||||
range: options.range,
|
||||
comment: true,
|
||||
onComment: comments,
|
||||
tolerant: util.getOption(options, "tolerant", true),
|
||||
ecmaVersion: 6,
|
||||
sourceType: util.getOption(options, "sourceType", "module"),
|
||||
});
|
||||
// Use ast.tokens if possible, and otherwise fall back to the Esprima
|
||||
// tokenizer. All the preconfigured ../parsers/* expose ast.tokens
|
||||
// automatically, but custom parsers might need additional configuration
|
||||
// to avoid this fallback.
|
||||
var tokens = Array.isArray(ast.tokens)
|
||||
? ast.tokens
|
||||
: require("esprima").tokenize(sourceWithoutTabs, {
|
||||
loc: true,
|
||||
});
|
||||
// We will reattach the tokens array to the file object below.
|
||||
delete ast.tokens;
|
||||
// Make sure every token has a token.value string.
|
||||
tokens.forEach(function (token) {
|
||||
if (typeof token.value !== "string") {
|
||||
token.value = lines.sliceString(token.loc.start, token.loc.end);
|
||||
}
|
||||
});
|
||||
if (Array.isArray(ast.comments)) {
|
||||
comments = ast.comments;
|
||||
delete ast.comments;
|
||||
}
|
||||
if (ast.loc) {
|
||||
// If the source was empty, some parsers give loc.{start,end}.line
|
||||
// values of 0, instead of the minimum of 1.
|
||||
util.fixFaultyLocations(ast, lines);
|
||||
}
|
||||
else {
|
||||
ast.loc = {
|
||||
start: lines.firstPos(),
|
||||
end: lines.lastPos(),
|
||||
};
|
||||
}
|
||||
ast.loc.lines = lines;
|
||||
ast.loc.indent = 0;
|
||||
var file;
|
||||
var program;
|
||||
if (ast.type === "Program") {
|
||||
program = ast;
|
||||
// In order to ensure we reprint leading and trailing program
|
||||
// comments, wrap the original Program node with a File node. Only
|
||||
// ESTree parsers (Acorn and Esprima) return a Program as the root AST
|
||||
// node. Most other (Babylon-like) parsers return a File.
|
||||
file = b.file(ast, options.sourceFileName || null);
|
||||
file.loc = {
|
||||
start: lines.firstPos(),
|
||||
end: lines.lastPos(),
|
||||
lines: lines,
|
||||
indent: 0,
|
||||
};
|
||||
}
|
||||
else if (ast.type === "File") {
|
||||
file = ast;
|
||||
program = file.program;
|
||||
}
|
||||
// Expose file.tokens unless the caller passed false for options.tokens.
|
||||
if (options.tokens) {
|
||||
file.tokens = tokens;
|
||||
}
|
||||
// Expand the Program's .loc to include all comments (not just those
|
||||
// attached to the Program node, as its children may have comments as
|
||||
// well), since sometimes program.loc.{start,end} will coincide with the
|
||||
// .loc.{start,end} of the first and last *statements*, mistakenly
|
||||
// excluding comments that fall outside that region.
|
||||
var trueProgramLoc = util.getTrueLoc({
|
||||
type: program.type,
|
||||
loc: program.loc,
|
||||
body: [],
|
||||
comments: comments,
|
||||
}, lines);
|
||||
program.loc.start = trueProgramLoc.start;
|
||||
program.loc.end = trueProgramLoc.end;
|
||||
// Passing file.program here instead of just file means that initial
|
||||
// comments will be attached to program.body[0] instead of program.
|
||||
comments_1.attach(comments, program.body.length ? file.program : file, lines);
|
||||
// Return a copy of the original AST so that any changes made may be
|
||||
// compared to the original.
|
||||
return new TreeCopier(lines, tokens).copy(file);
|
||||
}
|
||||
exports.parse = parse;
|
||||
var TreeCopier = function TreeCopier(lines, tokens) {
|
||||
assert_1.default.ok(this instanceof TreeCopier);
|
||||
this.lines = lines;
|
||||
this.tokens = tokens;
|
||||
this.startTokenIndex = 0;
|
||||
this.endTokenIndex = tokens.length;
|
||||
this.indent = 0;
|
||||
this.seen = new Map();
|
||||
};
|
||||
var TCp = TreeCopier.prototype;
|
||||
TCp.copy = function (node) {
|
||||
if (this.seen.has(node)) {
|
||||
return this.seen.get(node);
|
||||
}
|
||||
if (isArray.check(node)) {
|
||||
var copy_1 = new Array(node.length);
|
||||
this.seen.set(node, copy_1);
|
||||
node.forEach(function (item, i) {
|
||||
copy_1[i] = this.copy(item);
|
||||
}, this);
|
||||
return copy_1;
|
||||
}
|
||||
if (!isObject.check(node)) {
|
||||
return node;
|
||||
}
|
||||
util.fixFaultyLocations(node, this.lines);
|
||||
var copy = Object.create(Object.getPrototypeOf(node), {
|
||||
original: {
|
||||
// Provide a link from the copy to the original.
|
||||
value: node,
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
writable: true,
|
||||
},
|
||||
});
|
||||
this.seen.set(node, copy);
|
||||
var loc = node.loc;
|
||||
var oldIndent = this.indent;
|
||||
var newIndent = oldIndent;
|
||||
var oldStartTokenIndex = this.startTokenIndex;
|
||||
var oldEndTokenIndex = this.endTokenIndex;
|
||||
if (loc) {
|
||||
// When node is a comment, we set node.loc.indent to
|
||||
// node.loc.start.column so that, when/if we print the comment by
|
||||
// itself, we can strip that much whitespace from the left margin of
|
||||
// the comment. This only really matters for multiline Block comments,
|
||||
// but it doesn't hurt for Line comments.
|
||||
if (node.type === "Block" ||
|
||||
node.type === "Line" ||
|
||||
node.type === "CommentBlock" ||
|
||||
node.type === "CommentLine" ||
|
||||
this.lines.isPrecededOnlyByWhitespace(loc.start)) {
|
||||
newIndent = this.indent = loc.start.column;
|
||||
}
|
||||
// Every node.loc has a reference to the original source lines as well
|
||||
// as a complete list of source tokens.
|
||||
loc.lines = this.lines;
|
||||
loc.tokens = this.tokens;
|
||||
loc.indent = newIndent;
|
||||
// Set loc.start.token and loc.end.token such that
|
||||
// loc.tokens.slice(loc.start.token, loc.end.token) returns a list of
|
||||
// all the tokens that make up this node.
|
||||
this.findTokenRange(loc);
|
||||
}
|
||||
var keys = Object.keys(node);
|
||||
var keyCount = keys.length;
|
||||
for (var i = 0; i < keyCount; ++i) {
|
||||
var key = keys[i];
|
||||
if (key === "loc") {
|
||||
copy[key] = node[key];
|
||||
}
|
||||
else if (key === "tokens" && node.type === "File") {
|
||||
// Preserve file.tokens (uncopied) in case client code cares about
|
||||
// it, even though Recast ignores it when reprinting.
|
||||
copy[key] = node[key];
|
||||
}
|
||||
else {
|
||||
copy[key] = this.copy(node[key]);
|
||||
}
|
||||
}
|
||||
this.indent = oldIndent;
|
||||
this.startTokenIndex = oldStartTokenIndex;
|
||||
this.endTokenIndex = oldEndTokenIndex;
|
||||
return copy;
|
||||
};
|
||||
// If we didn't have any idea where in loc.tokens to look for tokens
|
||||
// contained by this loc, a binary search would be appropriate, but
|
||||
// because we maintain this.startTokenIndex and this.endTokenIndex as we
|
||||
// traverse the AST, we only need to make small (linear) adjustments to
|
||||
// those indexes with each recursive iteration.
|
||||
TCp.findTokenRange = function (loc) {
|
||||
// In the unlikely event that loc.tokens[this.startTokenIndex] starts
|
||||
// *after* loc.start, we need to rewind this.startTokenIndex first.
|
||||
while (this.startTokenIndex > 0) {
|
||||
var token = loc.tokens[this.startTokenIndex];
|
||||
if (util.comparePos(loc.start, token.loc.start) < 0) {
|
||||
--this.startTokenIndex;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
// In the unlikely event that loc.tokens[this.endTokenIndex - 1] ends
|
||||
// *before* loc.end, we need to fast-forward this.endTokenIndex first.
|
||||
while (this.endTokenIndex < loc.tokens.length) {
|
||||
var token = loc.tokens[this.endTokenIndex];
|
||||
if (util.comparePos(token.loc.end, loc.end) < 0) {
|
||||
++this.endTokenIndex;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
// Increment this.startTokenIndex until we've found the first token
|
||||
// contained by this node.
|
||||
while (this.startTokenIndex < this.endTokenIndex) {
|
||||
var token = loc.tokens[this.startTokenIndex];
|
||||
if (util.comparePos(token.loc.start, loc.start) < 0) {
|
||||
++this.startTokenIndex;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
// Index into loc.tokens of the first token within this node.
|
||||
loc.start.token = this.startTokenIndex;
|
||||
// Decrement this.endTokenIndex until we've found the first token after
|
||||
// this node (not contained by the node).
|
||||
while (this.endTokenIndex > this.startTokenIndex) {
|
||||
var token = loc.tokens[this.endTokenIndex - 1];
|
||||
if (util.comparePos(loc.end, token.loc.end) < 0) {
|
||||
--this.endTokenIndex;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
// Index into loc.tokens of the first token *after* this node.
|
||||
// If loc.start.token === loc.end.token, the node contains no tokens,
|
||||
// and the index is that of the next token following this node.
|
||||
loc.end.token = this.endTokenIndex;
|
||||
};
|
12
node_modules/recast/lib/patcher.d.ts
generated
vendored
Normal file
12
node_modules/recast/lib/patcher.d.ts
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
interface PatcherType {
|
||||
replace(loc: any, lines: any): any;
|
||||
get(loc?: any): any;
|
||||
tryToReprintComments(newNode: any, oldNode: any, print: any): any;
|
||||
deleteComments(node: any): any;
|
||||
}
|
||||
interface PatcherConstructor {
|
||||
new (lines: any): PatcherType;
|
||||
}
|
||||
declare const Patcher: PatcherConstructor;
|
||||
export { Patcher };
|
||||
export declare function getReprinter(path: any): ((print: any) => any) | undefined;
|
386
node_modules/recast/lib/patcher.js
generated
vendored
Normal file
386
node_modules/recast/lib/patcher.js
generated
vendored
Normal file
@@ -0,0 +1,386 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getReprinter = exports.Patcher = void 0;
|
||||
var tslib_1 = require("tslib");
|
||||
var assert_1 = tslib_1.__importDefault(require("assert"));
|
||||
var linesModule = tslib_1.__importStar(require("./lines"));
|
||||
var types = tslib_1.__importStar(require("ast-types"));
|
||||
var Printable = types.namedTypes.Printable;
|
||||
var Expression = types.namedTypes.Expression;
|
||||
var ReturnStatement = types.namedTypes.ReturnStatement;
|
||||
var SourceLocation = types.namedTypes.SourceLocation;
|
||||
var util_1 = require("./util");
|
||||
var fast_path_1 = tslib_1.__importDefault(require("./fast-path"));
|
||||
var isObject = types.builtInTypes.object;
|
||||
var isArray = types.builtInTypes.array;
|
||||
var isString = types.builtInTypes.string;
|
||||
var riskyAdjoiningCharExp = /[0-9a-z_$]/i;
|
||||
var Patcher = function Patcher(lines) {
|
||||
assert_1.default.ok(this instanceof Patcher);
|
||||
assert_1.default.ok(lines instanceof linesModule.Lines);
|
||||
var self = this, replacements = [];
|
||||
self.replace = function (loc, lines) {
|
||||
if (isString.check(lines))
|
||||
lines = linesModule.fromString(lines);
|
||||
replacements.push({
|
||||
lines: lines,
|
||||
start: loc.start,
|
||||
end: loc.end,
|
||||
});
|
||||
};
|
||||
self.get = function (loc) {
|
||||
// If no location is provided, return the complete Lines object.
|
||||
loc = loc || {
|
||||
start: { line: 1, column: 0 },
|
||||
end: { line: lines.length, column: lines.getLineLength(lines.length) },
|
||||
};
|
||||
var sliceFrom = loc.start, toConcat = [];
|
||||
function pushSlice(from, to) {
|
||||
assert_1.default.ok(util_1.comparePos(from, to) <= 0);
|
||||
toConcat.push(lines.slice(from, to));
|
||||
}
|
||||
replacements
|
||||
.sort(function (a, b) { return util_1.comparePos(a.start, b.start); })
|
||||
.forEach(function (rep) {
|
||||
if (util_1.comparePos(sliceFrom, rep.start) > 0) {
|
||||
// Ignore nested replacement ranges.
|
||||
}
|
||||
else {
|
||||
pushSlice(sliceFrom, rep.start);
|
||||
toConcat.push(rep.lines);
|
||||
sliceFrom = rep.end;
|
||||
}
|
||||
});
|
||||
pushSlice(sliceFrom, loc.end);
|
||||
return linesModule.concat(toConcat);
|
||||
};
|
||||
};
|
||||
exports.Patcher = Patcher;
|
||||
var Pp = Patcher.prototype;
|
||||
Pp.tryToReprintComments = function (newNode, oldNode, print) {
|
||||
var patcher = this;
|
||||
if (!newNode.comments && !oldNode.comments) {
|
||||
// We were (vacuously) able to reprint all the comments!
|
||||
return true;
|
||||
}
|
||||
var newPath = fast_path_1.default.from(newNode);
|
||||
var oldPath = fast_path_1.default.from(oldNode);
|
||||
newPath.stack.push("comments", getSurroundingComments(newNode));
|
||||
oldPath.stack.push("comments", getSurroundingComments(oldNode));
|
||||
var reprints = [];
|
||||
var ableToReprintComments = findArrayReprints(newPath, oldPath, reprints);
|
||||
// No need to pop anything from newPath.stack or oldPath.stack, since
|
||||
// newPath and oldPath are fresh local variables.
|
||||
if (ableToReprintComments && reprints.length > 0) {
|
||||
reprints.forEach(function (reprint) {
|
||||
var oldComment = reprint.oldPath.getValue();
|
||||
assert_1.default.ok(oldComment.leading || oldComment.trailing);
|
||||
patcher.replace(oldComment.loc,
|
||||
// Comments can't have .comments, so it doesn't matter whether we
|
||||
// print with comments or without.
|
||||
print(reprint.newPath).indentTail(oldComment.loc.indent));
|
||||
});
|
||||
}
|
||||
return ableToReprintComments;
|
||||
};
|
||||
// Get all comments that are either leading or trailing, ignoring any
|
||||
// comments that occur inside node.loc. Returns an empty array for nodes
|
||||
// with no leading or trailing comments.
|
||||
function getSurroundingComments(node) {
|
||||
var result = [];
|
||||
if (node.comments && node.comments.length > 0) {
|
||||
node.comments.forEach(function (comment) {
|
||||
if (comment.leading || comment.trailing) {
|
||||
result.push(comment);
|
||||
}
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
Pp.deleteComments = function (node) {
|
||||
if (!node.comments) {
|
||||
return;
|
||||
}
|
||||
var patcher = this;
|
||||
node.comments.forEach(function (comment) {
|
||||
if (comment.leading) {
|
||||
// Delete leading comments along with any trailing whitespace they
|
||||
// might have.
|
||||
patcher.replace({
|
||||
start: comment.loc.start,
|
||||
end: node.loc.lines.skipSpaces(comment.loc.end, false, false),
|
||||
}, "");
|
||||
}
|
||||
else if (comment.trailing) {
|
||||
// Delete trailing comments along with any leading whitespace they
|
||||
// might have.
|
||||
patcher.replace({
|
||||
start: node.loc.lines.skipSpaces(comment.loc.start, true, false),
|
||||
end: comment.loc.end,
|
||||
}, "");
|
||||
}
|
||||
});
|
||||
};
|
||||
function getReprinter(path) {
|
||||
assert_1.default.ok(path instanceof fast_path_1.default);
|
||||
// Make sure that this path refers specifically to a Node, rather than
|
||||
// some non-Node subproperty of a Node.
|
||||
var node = path.getValue();
|
||||
if (!Printable.check(node))
|
||||
return;
|
||||
var orig = node.original;
|
||||
var origLoc = orig && orig.loc;
|
||||
var lines = origLoc && origLoc.lines;
|
||||
var reprints = [];
|
||||
if (!lines || !findReprints(path, reprints))
|
||||
return;
|
||||
return function (print) {
|
||||
var patcher = new Patcher(lines);
|
||||
reprints.forEach(function (reprint) {
|
||||
var newNode = reprint.newPath.getValue();
|
||||
var oldNode = reprint.oldPath.getValue();
|
||||
SourceLocation.assert(oldNode.loc, true);
|
||||
var needToPrintNewPathWithComments = !patcher.tryToReprintComments(newNode, oldNode, print);
|
||||
if (needToPrintNewPathWithComments) {
|
||||
// Since we were not able to preserve all leading/trailing
|
||||
// comments, we delete oldNode's comments, print newPath with
|
||||
// comments, and then patch the resulting lines where oldNode used
|
||||
// to be.
|
||||
patcher.deleteComments(oldNode);
|
||||
}
|
||||
var newLines = print(reprint.newPath, {
|
||||
includeComments: needToPrintNewPathWithComments,
|
||||
// If the oldNode we're replacing already had parentheses, we may
|
||||
// not need to print the new node with any extra parentheses,
|
||||
// because the existing parentheses will suffice. However, if the
|
||||
// newNode has a different type than the oldNode, let the printer
|
||||
// decide if reprint.newPath needs parentheses, as usual.
|
||||
avoidRootParens: oldNode.type === newNode.type && reprint.oldPath.hasParens(),
|
||||
}).indentTail(oldNode.loc.indent);
|
||||
var nls = needsLeadingSpace(lines, oldNode.loc, newLines);
|
||||
var nts = needsTrailingSpace(lines, oldNode.loc, newLines);
|
||||
// If we try to replace the argument of a ReturnStatement like
|
||||
// return"asdf" with e.g. a literal null expression, we run the risk
|
||||
// of ending up with returnnull, so we need to add an extra leading
|
||||
// space in situations where that might happen. Likewise for
|
||||
// "asdf"in obj. See #170.
|
||||
if (nls || nts) {
|
||||
var newParts = [];
|
||||
nls && newParts.push(" ");
|
||||
newParts.push(newLines);
|
||||
nts && newParts.push(" ");
|
||||
newLines = linesModule.concat(newParts);
|
||||
}
|
||||
patcher.replace(oldNode.loc, newLines);
|
||||
});
|
||||
// Recall that origLoc is the .loc of an ancestor node that is
|
||||
// guaranteed to contain all the reprinted nodes and comments.
|
||||
var patchedLines = patcher.get(origLoc).indentTail(-orig.loc.indent);
|
||||
if (path.needsParens()) {
|
||||
return linesModule.concat(["(", patchedLines, ")"]);
|
||||
}
|
||||
return patchedLines;
|
||||
};
|
||||
}
|
||||
exports.getReprinter = getReprinter;
|
||||
// If the last character before oldLoc and the first character of newLines
|
||||
// are both identifier characters, they must be separated by a space,
|
||||
// otherwise they will most likely get fused together into a single token.
|
||||
function needsLeadingSpace(oldLines, oldLoc, newLines) {
|
||||
var posBeforeOldLoc = util_1.copyPos(oldLoc.start);
|
||||
// The character just before the location occupied by oldNode.
|
||||
var charBeforeOldLoc = oldLines.prevPos(posBeforeOldLoc) && oldLines.charAt(posBeforeOldLoc);
|
||||
// First character of the reprinted node.
|
||||
var newFirstChar = newLines.charAt(newLines.firstPos());
|
||||
return (charBeforeOldLoc &&
|
||||
riskyAdjoiningCharExp.test(charBeforeOldLoc) &&
|
||||
newFirstChar &&
|
||||
riskyAdjoiningCharExp.test(newFirstChar));
|
||||
}
|
||||
// If the last character of newLines and the first character after oldLoc
|
||||
// are both identifier characters, they must be separated by a space,
|
||||
// otherwise they will most likely get fused together into a single token.
|
||||
function needsTrailingSpace(oldLines, oldLoc, newLines) {
|
||||
// The character just after the location occupied by oldNode.
|
||||
var charAfterOldLoc = oldLines.charAt(oldLoc.end);
|
||||
var newLastPos = newLines.lastPos();
|
||||
// Last character of the reprinted node.
|
||||
var newLastChar = newLines.prevPos(newLastPos) && newLines.charAt(newLastPos);
|
||||
return (newLastChar &&
|
||||
riskyAdjoiningCharExp.test(newLastChar) &&
|
||||
charAfterOldLoc &&
|
||||
riskyAdjoiningCharExp.test(charAfterOldLoc));
|
||||
}
|
||||
function findReprints(newPath, reprints) {
|
||||
var newNode = newPath.getValue();
|
||||
Printable.assert(newNode);
|
||||
var oldNode = newNode.original;
|
||||
Printable.assert(oldNode);
|
||||
assert_1.default.deepEqual(reprints, []);
|
||||
if (newNode.type !== oldNode.type) {
|
||||
return false;
|
||||
}
|
||||
var oldPath = new fast_path_1.default(oldNode);
|
||||
var canReprint = findChildReprints(newPath, oldPath, reprints);
|
||||
if (!canReprint) {
|
||||
// Make absolutely sure the calling code does not attempt to reprint
|
||||
// any nodes.
|
||||
reprints.length = 0;
|
||||
}
|
||||
return canReprint;
|
||||
}
|
||||
function findAnyReprints(newPath, oldPath, reprints) {
|
||||
var newNode = newPath.getValue();
|
||||
var oldNode = oldPath.getValue();
|
||||
if (newNode === oldNode)
|
||||
return true;
|
||||
if (isArray.check(newNode))
|
||||
return findArrayReprints(newPath, oldPath, reprints);
|
||||
if (isObject.check(newNode))
|
||||
return findObjectReprints(newPath, oldPath, reprints);
|
||||
return false;
|
||||
}
|
||||
function findArrayReprints(newPath, oldPath, reprints) {
|
||||
var newNode = newPath.getValue();
|
||||
var oldNode = oldPath.getValue();
|
||||
if (newNode === oldNode ||
|
||||
newPath.valueIsDuplicate() ||
|
||||
oldPath.valueIsDuplicate()) {
|
||||
return true;
|
||||
}
|
||||
isArray.assert(newNode);
|
||||
var len = newNode.length;
|
||||
if (!(isArray.check(oldNode) && oldNode.length === len))
|
||||
return false;
|
||||
for (var i = 0; i < len; ++i) {
|
||||
newPath.stack.push(i, newNode[i]);
|
||||
oldPath.stack.push(i, oldNode[i]);
|
||||
var canReprint = findAnyReprints(newPath, oldPath, reprints);
|
||||
newPath.stack.length -= 2;
|
||||
oldPath.stack.length -= 2;
|
||||
if (!canReprint) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
function findObjectReprints(newPath, oldPath, reprints) {
|
||||
var newNode = newPath.getValue();
|
||||
isObject.assert(newNode);
|
||||
if (newNode.original === null) {
|
||||
// If newNode.original node was set to null, reprint the node.
|
||||
return false;
|
||||
}
|
||||
var oldNode = oldPath.getValue();
|
||||
if (!isObject.check(oldNode))
|
||||
return false;
|
||||
if (newNode === oldNode ||
|
||||
newPath.valueIsDuplicate() ||
|
||||
oldPath.valueIsDuplicate()) {
|
||||
return true;
|
||||
}
|
||||
if (Printable.check(newNode)) {
|
||||
if (!Printable.check(oldNode)) {
|
||||
return false;
|
||||
}
|
||||
var newParentNode = newPath.getParentNode();
|
||||
var oldParentNode = oldPath.getParentNode();
|
||||
if (oldParentNode !== null &&
|
||||
oldParentNode.type === "FunctionTypeAnnotation" &&
|
||||
newParentNode !== null &&
|
||||
newParentNode.type === "FunctionTypeAnnotation") {
|
||||
var oldNeedsParens = oldParentNode.params.length !== 1 || !!oldParentNode.params[0].name;
|
||||
var newNeedParens = newParentNode.params.length !== 1 || !!newParentNode.params[0].name;
|
||||
if (!oldNeedsParens && newNeedParens) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Here we need to decide whether the reprinted code for newNode is
|
||||
// appropriate for patching into the location of oldNode.
|
||||
if (newNode.type === oldNode.type) {
|
||||
var childReprints = [];
|
||||
if (findChildReprints(newPath, oldPath, childReprints)) {
|
||||
reprints.push.apply(reprints, childReprints);
|
||||
}
|
||||
else if (oldNode.loc) {
|
||||
// If we have no .loc information for oldNode, then we won't be
|
||||
// able to reprint it.
|
||||
reprints.push({
|
||||
oldPath: oldPath.copy(),
|
||||
newPath: newPath.copy(),
|
||||
});
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (Expression.check(newNode) &&
|
||||
Expression.check(oldNode) &&
|
||||
// If we have no .loc information for oldNode, then we won't be
|
||||
// able to reprint it.
|
||||
oldNode.loc) {
|
||||
// If both nodes are subtypes of Expression, then we should be able
|
||||
// to fill the location occupied by the old node with code printed
|
||||
// for the new node with no ill consequences.
|
||||
reprints.push({
|
||||
oldPath: oldPath.copy(),
|
||||
newPath: newPath.copy(),
|
||||
});
|
||||
return true;
|
||||
}
|
||||
// The nodes have different types, and at least one of the types is
|
||||
// not a subtype of the Expression type, so we cannot safely assume
|
||||
// the nodes are syntactically interchangeable.
|
||||
return false;
|
||||
}
|
||||
return findChildReprints(newPath, oldPath, reprints);
|
||||
}
|
||||
function findChildReprints(newPath, oldPath, reprints) {
|
||||
var newNode = newPath.getValue();
|
||||
var oldNode = oldPath.getValue();
|
||||
isObject.assert(newNode);
|
||||
isObject.assert(oldNode);
|
||||
if (newNode.original === null) {
|
||||
// If newNode.original node was set to null, reprint the node.
|
||||
return false;
|
||||
}
|
||||
// If this node needs parentheses and will not be wrapped with
|
||||
// parentheses when reprinted, then return false to skip reprinting and
|
||||
// let it be printed generically.
|
||||
if (newPath.needsParens() && !oldPath.hasParens()) {
|
||||
return false;
|
||||
}
|
||||
var keys = util_1.getUnionOfKeys(oldNode, newNode);
|
||||
if (oldNode.type === "File" || newNode.type === "File") {
|
||||
// Don't bother traversing file.tokens, an often very large array
|
||||
// returned by Babylon, and useless for our purposes.
|
||||
delete keys.tokens;
|
||||
}
|
||||
// Don't bother traversing .loc objects looking for reprintable nodes.
|
||||
delete keys.loc;
|
||||
var originalReprintCount = reprints.length;
|
||||
for (var k in keys) {
|
||||
if (k.charAt(0) === "_") {
|
||||
// Ignore "private" AST properties added by e.g. Babel plugins and
|
||||
// parsers like Babylon.
|
||||
continue;
|
||||
}
|
||||
newPath.stack.push(k, types.getFieldValue(newNode, k));
|
||||
oldPath.stack.push(k, types.getFieldValue(oldNode, k));
|
||||
var canReprint = findAnyReprints(newPath, oldPath, reprints);
|
||||
newPath.stack.length -= 2;
|
||||
oldPath.stack.length -= 2;
|
||||
if (!canReprint) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Return statements might end up running into ASI issues due to
|
||||
// comments inserted deep within the tree, so reprint them if anything
|
||||
// changed within them.
|
||||
if (ReturnStatement.check(newPath.getNode()) &&
|
||||
reprints.length > originalReprintCount) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
14
node_modules/recast/lib/printer.d.ts
generated
vendored
Normal file
14
node_modules/recast/lib/printer.d.ts
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
export interface PrintResultType {
|
||||
code: string;
|
||||
map?: any;
|
||||
toString(): string;
|
||||
}
|
||||
interface PrinterType {
|
||||
print(ast: any): PrintResultType;
|
||||
printGenerically(ast: any): PrintResultType;
|
||||
}
|
||||
interface PrinterConstructor {
|
||||
new (config?: any): PrinterType;
|
||||
}
|
||||
declare const Printer: PrinterConstructor;
|
||||
export { Printer };
|
2262
node_modules/recast/lib/printer.js
generated
vendored
Normal file
2262
node_modules/recast/lib/printer.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
16
node_modules/recast/lib/util.d.ts
generated
vendored
Normal file
16
node_modules/recast/lib/util.d.ts
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
export declare function getOption(options: any, key: any, defaultValue: any): any;
|
||||
export declare function getUnionOfKeys(...args: any[]): any;
|
||||
export declare function comparePos(pos1: any, pos2: any): number;
|
||||
export declare function copyPos(pos: any): {
|
||||
line: any;
|
||||
column: any;
|
||||
};
|
||||
export declare function composeSourceMaps(formerMap: any, latterMap: any): any;
|
||||
export declare function getTrueLoc(node: any, lines: any): {
|
||||
start: any;
|
||||
end: any;
|
||||
} | null;
|
||||
export declare function fixFaultyLocations(node: any, lines: any): void;
|
||||
export declare function isExportDeclaration(node: any): boolean;
|
||||
export declare function getParentExportDeclaration(path: any): any;
|
||||
export declare function isTrailingCommaEnabled(options: any, context: any): boolean;
|
323
node_modules/recast/lib/util.js
generated
vendored
Normal file
323
node_modules/recast/lib/util.js
generated
vendored
Normal file
@@ -0,0 +1,323 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.isTrailingCommaEnabled = exports.getParentExportDeclaration = exports.isExportDeclaration = exports.fixFaultyLocations = exports.getTrueLoc = exports.composeSourceMaps = exports.copyPos = exports.comparePos = exports.getUnionOfKeys = exports.getOption = void 0;
|
||||
var tslib_1 = require("tslib");
|
||||
var assert_1 = tslib_1.__importDefault(require("assert"));
|
||||
var types = tslib_1.__importStar(require("ast-types"));
|
||||
var n = types.namedTypes;
|
||||
var source_map_1 = tslib_1.__importDefault(require("source-map"));
|
||||
var SourceMapConsumer = source_map_1.default.SourceMapConsumer;
|
||||
var SourceMapGenerator = source_map_1.default.SourceMapGenerator;
|
||||
var hasOwn = Object.prototype.hasOwnProperty;
|
||||
function getOption(options, key, defaultValue) {
|
||||
if (options && hasOwn.call(options, key)) {
|
||||
return options[key];
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
exports.getOption = getOption;
|
||||
function getUnionOfKeys() {
|
||||
var args = [];
|
||||
for (var _i = 0; _i < arguments.length; _i++) {
|
||||
args[_i] = arguments[_i];
|
||||
}
|
||||
var result = {};
|
||||
var argc = args.length;
|
||||
for (var i = 0; i < argc; ++i) {
|
||||
var keys = Object.keys(args[i]);
|
||||
var keyCount = keys.length;
|
||||
for (var j = 0; j < keyCount; ++j) {
|
||||
result[keys[j]] = true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
exports.getUnionOfKeys = getUnionOfKeys;
|
||||
function comparePos(pos1, pos2) {
|
||||
return pos1.line - pos2.line || pos1.column - pos2.column;
|
||||
}
|
||||
exports.comparePos = comparePos;
|
||||
function copyPos(pos) {
|
||||
return {
|
||||
line: pos.line,
|
||||
column: pos.column,
|
||||
};
|
||||
}
|
||||
exports.copyPos = copyPos;
|
||||
function composeSourceMaps(formerMap, latterMap) {
|
||||
if (formerMap) {
|
||||
if (!latterMap) {
|
||||
return formerMap;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return latterMap || null;
|
||||
}
|
||||
var smcFormer = new SourceMapConsumer(formerMap);
|
||||
var smcLatter = new SourceMapConsumer(latterMap);
|
||||
var smg = new SourceMapGenerator({
|
||||
file: latterMap.file,
|
||||
sourceRoot: latterMap.sourceRoot,
|
||||
});
|
||||
var sourcesToContents = {};
|
||||
smcLatter.eachMapping(function (mapping) {
|
||||
var origPos = smcFormer.originalPositionFor({
|
||||
line: mapping.originalLine,
|
||||
column: mapping.originalColumn,
|
||||
});
|
||||
var sourceName = origPos.source;
|
||||
if (sourceName === null) {
|
||||
return;
|
||||
}
|
||||
smg.addMapping({
|
||||
source: sourceName,
|
||||
original: copyPos(origPos),
|
||||
generated: {
|
||||
line: mapping.generatedLine,
|
||||
column: mapping.generatedColumn,
|
||||
},
|
||||
name: mapping.name,
|
||||
});
|
||||
var sourceContent = smcFormer.sourceContentFor(sourceName);
|
||||
if (sourceContent && !hasOwn.call(sourcesToContents, sourceName)) {
|
||||
sourcesToContents[sourceName] = sourceContent;
|
||||
smg.setSourceContent(sourceName, sourceContent);
|
||||
}
|
||||
});
|
||||
return smg.toJSON();
|
||||
}
|
||||
exports.composeSourceMaps = composeSourceMaps;
|
||||
function getTrueLoc(node, lines) {
|
||||
// It's possible that node is newly-created (not parsed by Esprima),
|
||||
// in which case it probably won't have a .loc property (or an
|
||||
// .original property for that matter). That's fine; we'll just
|
||||
// pretty-print it as usual.
|
||||
if (!node.loc) {
|
||||
return null;
|
||||
}
|
||||
var result = {
|
||||
start: node.loc.start,
|
||||
end: node.loc.end,
|
||||
};
|
||||
function include(node) {
|
||||
expandLoc(result, node.loc);
|
||||
}
|
||||
// If the node is an export declaration and its .declaration has any
|
||||
// decorators, their locations might contribute to the true start/end
|
||||
// positions of the export declaration node.
|
||||
if (node.declaration &&
|
||||
node.declaration.decorators &&
|
||||
isExportDeclaration(node)) {
|
||||
node.declaration.decorators.forEach(include);
|
||||
}
|
||||
if (comparePos(result.start, result.end) < 0) {
|
||||
// Trim leading whitespace.
|
||||
result.start = copyPos(result.start);
|
||||
lines.skipSpaces(result.start, false, true);
|
||||
if (comparePos(result.start, result.end) < 0) {
|
||||
// Trim trailing whitespace, if the end location is not already the
|
||||
// same as the start location.
|
||||
result.end = copyPos(result.end);
|
||||
lines.skipSpaces(result.end, true, true);
|
||||
}
|
||||
}
|
||||
// If the node has any comments, their locations might contribute to
|
||||
// the true start/end positions of the node.
|
||||
if (node.comments) {
|
||||
node.comments.forEach(include);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
exports.getTrueLoc = getTrueLoc;
|
||||
function expandLoc(parentLoc, childLoc) {
|
||||
if (parentLoc && childLoc) {
|
||||
if (comparePos(childLoc.start, parentLoc.start) < 0) {
|
||||
parentLoc.start = childLoc.start;
|
||||
}
|
||||
if (comparePos(parentLoc.end, childLoc.end) < 0) {
|
||||
parentLoc.end = childLoc.end;
|
||||
}
|
||||
}
|
||||
}
|
||||
function fixFaultyLocations(node, lines) {
|
||||
var loc = node.loc;
|
||||
if (loc) {
|
||||
if (loc.start.line < 1) {
|
||||
loc.start.line = 1;
|
||||
}
|
||||
if (loc.end.line < 1) {
|
||||
loc.end.line = 1;
|
||||
}
|
||||
}
|
||||
if (node.type === "File") {
|
||||
// Babylon returns File nodes whose .loc.{start,end} do not include
|
||||
// leading or trailing whitespace.
|
||||
loc.start = lines.firstPos();
|
||||
loc.end = lines.lastPos();
|
||||
}
|
||||
fixForLoopHead(node, lines);
|
||||
fixTemplateLiteral(node, lines);
|
||||
if (loc && node.decorators) {
|
||||
// Expand the .loc of the node responsible for printing the decorators
|
||||
// (here, the decorated node) so that it includes node.decorators.
|
||||
node.decorators.forEach(function (decorator) {
|
||||
expandLoc(loc, decorator.loc);
|
||||
});
|
||||
}
|
||||
else if (node.declaration && isExportDeclaration(node)) {
|
||||
// Nullify .loc information for the child declaration so that we never
|
||||
// try to reprint it without also reprinting the export declaration.
|
||||
node.declaration.loc = null;
|
||||
// Expand the .loc of the node responsible for printing the decorators
|
||||
// (here, the export declaration) so that it includes node.decorators.
|
||||
var decorators = node.declaration.decorators;
|
||||
if (decorators) {
|
||||
decorators.forEach(function (decorator) {
|
||||
expandLoc(loc, decorator.loc);
|
||||
});
|
||||
}
|
||||
}
|
||||
else if ((n.MethodDefinition && n.MethodDefinition.check(node)) ||
|
||||
(n.Property.check(node) && (node.method || node.shorthand))) {
|
||||
// If the node is a MethodDefinition or a .method or .shorthand
|
||||
// Property, then the location information stored in
|
||||
// node.value.loc is very likely untrustworthy (just the {body}
|
||||
// part of a method, or nothing in the case of shorthand
|
||||
// properties), so we null out that information to prevent
|
||||
// accidental reuse of bogus source code during reprinting.
|
||||
node.value.loc = null;
|
||||
if (n.FunctionExpression.check(node.value)) {
|
||||
// FunctionExpression method values should be anonymous,
|
||||
// because their .id fields are ignored anyway.
|
||||
node.value.id = null;
|
||||
}
|
||||
}
|
||||
else if (node.type === "ObjectTypeProperty") {
|
||||
var loc_1 = node.loc;
|
||||
var end = loc_1 && loc_1.end;
|
||||
if (end) {
|
||||
end = copyPos(end);
|
||||
if (lines.prevPos(end) && lines.charAt(end) === ",") {
|
||||
// Some parsers accidentally include trailing commas in the
|
||||
// .loc.end information for ObjectTypeProperty nodes.
|
||||
if ((end = lines.skipSpaces(end, true, true))) {
|
||||
loc_1.end = end;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.fixFaultyLocations = fixFaultyLocations;
|
||||
function fixForLoopHead(node, lines) {
|
||||
if (node.type !== "ForStatement") {
|
||||
return;
|
||||
}
|
||||
function fix(child) {
|
||||
var loc = child && child.loc;
|
||||
var start = loc && loc.start;
|
||||
var end = loc && copyPos(loc.end);
|
||||
while (start && end && comparePos(start, end) < 0) {
|
||||
lines.prevPos(end);
|
||||
if (lines.charAt(end) === ";") {
|
||||
// Update child.loc.end to *exclude* the ';' character.
|
||||
loc.end.line = end.line;
|
||||
loc.end.column = end.column;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
fix(node.init);
|
||||
fix(node.test);
|
||||
fix(node.update);
|
||||
}
|
||||
function fixTemplateLiteral(node, lines) {
|
||||
if (node.type !== "TemplateLiteral") {
|
||||
return;
|
||||
}
|
||||
if (node.quasis.length === 0) {
|
||||
// If there are no quasi elements, then there is nothing to fix.
|
||||
return;
|
||||
}
|
||||
// node.loc is not present when using export default with a template literal
|
||||
if (node.loc) {
|
||||
// First we need to exclude the opening ` from the .loc of the first
|
||||
// quasi element, in case the parser accidentally decided to include it.
|
||||
var afterLeftBackTickPos = copyPos(node.loc.start);
|
||||
assert_1.default.strictEqual(lines.charAt(afterLeftBackTickPos), "`");
|
||||
assert_1.default.ok(lines.nextPos(afterLeftBackTickPos));
|
||||
var firstQuasi = node.quasis[0];
|
||||
if (comparePos(firstQuasi.loc.start, afterLeftBackTickPos) < 0) {
|
||||
firstQuasi.loc.start = afterLeftBackTickPos;
|
||||
}
|
||||
// Next we need to exclude the closing ` from the .loc of the last quasi
|
||||
// element, in case the parser accidentally decided to include it.
|
||||
var rightBackTickPos = copyPos(node.loc.end);
|
||||
assert_1.default.ok(lines.prevPos(rightBackTickPos));
|
||||
assert_1.default.strictEqual(lines.charAt(rightBackTickPos), "`");
|
||||
var lastQuasi = node.quasis[node.quasis.length - 1];
|
||||
if (comparePos(rightBackTickPos, lastQuasi.loc.end) < 0) {
|
||||
lastQuasi.loc.end = rightBackTickPos;
|
||||
}
|
||||
}
|
||||
// Now we need to exclude ${ and } characters from the .loc's of all
|
||||
// quasi elements, since some parsers accidentally include them.
|
||||
node.expressions.forEach(function (expr, i) {
|
||||
// Rewind from expr.loc.start over any whitespace and the ${ that
|
||||
// precedes the expression. The position of the $ should be the same
|
||||
// as the .loc.end of the preceding quasi element, but some parsers
|
||||
// accidentally include the ${ in the .loc of the quasi element.
|
||||
var dollarCurlyPos = lines.skipSpaces(expr.loc.start, true, false);
|
||||
if (lines.prevPos(dollarCurlyPos) &&
|
||||
lines.charAt(dollarCurlyPos) === "{" &&
|
||||
lines.prevPos(dollarCurlyPos) &&
|
||||
lines.charAt(dollarCurlyPos) === "$") {
|
||||
var quasiBefore = node.quasis[i];
|
||||
if (comparePos(dollarCurlyPos, quasiBefore.loc.end) < 0) {
|
||||
quasiBefore.loc.end = dollarCurlyPos;
|
||||
}
|
||||
}
|
||||
// Likewise, some parsers accidentally include the } that follows
|
||||
// the expression in the .loc of the following quasi element.
|
||||
var rightCurlyPos = lines.skipSpaces(expr.loc.end, false, false);
|
||||
if (lines.charAt(rightCurlyPos) === "}") {
|
||||
assert_1.default.ok(lines.nextPos(rightCurlyPos));
|
||||
// Now rightCurlyPos is technically the position just after the }.
|
||||
var quasiAfter = node.quasis[i + 1];
|
||||
if (comparePos(quasiAfter.loc.start, rightCurlyPos) < 0) {
|
||||
quasiAfter.loc.start = rightCurlyPos;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
function isExportDeclaration(node) {
|
||||
if (node)
|
||||
switch (node.type) {
|
||||
case "ExportDeclaration":
|
||||
case "ExportDefaultDeclaration":
|
||||
case "ExportDefaultSpecifier":
|
||||
case "DeclareExportDeclaration":
|
||||
case "ExportNamedDeclaration":
|
||||
case "ExportAllDeclaration":
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
exports.isExportDeclaration = isExportDeclaration;
|
||||
function getParentExportDeclaration(path) {
|
||||
var parentNode = path.getParentNode();
|
||||
if (path.getName() === "declaration" && isExportDeclaration(parentNode)) {
|
||||
return parentNode;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
exports.getParentExportDeclaration = getParentExportDeclaration;
|
||||
function isTrailingCommaEnabled(options, context) {
|
||||
var trailingComma = options.trailingComma;
|
||||
if (typeof trailingComma === "object") {
|
||||
return !!trailingComma[context];
|
||||
}
|
||||
return !!trailingComma;
|
||||
}
|
||||
exports.isTrailingCommaEnabled = isTrailingCommaEnabled;
|
Reference in New Issue
Block a user