Fix TypeScript compilation errors

This commit is contained in:
Brie 2019-01-08 17:43:17 -08:00
parent 67ac248985
commit 72aa176d38
36 changed files with 891 additions and 651 deletions

View file

@ -1,19 +1,16 @@
var assert = require("assert");
var types = require("./types");
import assert from "assert";
import types from "./types";
var n = types.namedTypes;
var isArray = types.builtInTypes.array;
var isObject = types.builtInTypes.object;
var linesModule = require("./lines");
var fromString = linesModule.fromString;
var Lines = linesModule.Lines;
var concat = linesModule.concat;
var util = require("./util");
var comparePos = util.comparePos;
var childNodesCacheKey = require("private").makeUniqueKey();
import { Lines, concat } from "./lines";
import { comparePos, fixFaultyLocations } from "./util";
import { makeUniqueKey } from "private";
var childNodesCacheKey = makeUniqueKey();
// TODO Move a non-caching implementation of this function into ast-types,
// and implement a caching wrapper function here.
function getSortedChildNodes(node, lines, resultArray) {
function getSortedChildNodes(node: any, lines: any, resultArray?: any) {
if (!node) {
return;
}
@ -22,7 +19,7 @@ function getSortedChildNodes(node, lines, resultArray) {
// 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.fixFaultyLocations(node, lines);
fixFaultyLocations(node, lines);
if (resultArray) {
if (n.Node.check(node) &&
@ -69,7 +66,7 @@ function getSortedChildNodes(node, lines, 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) {
function decorateComment(node: any, comment: any, lines: any) {
var childNodes = getSortedChildNodes(node, lines);
// Time to dust off the old binary search robes and wizard hat.
@ -117,12 +114,12 @@ function decorateComment(node, comment, lines) {
}
}
exports.attach = function(comments, ast, lines) {
export function attach(comments: any[], ast: any, lines: any) {
if (!isArray.check(comments)) {
return;
}
var tiesToBreak = [];
var tiesToBreak: any[] = [];
comments.forEach(function(comment) {
comment.loc.lines = lines;
@ -182,7 +179,7 @@ exports.attach = function(comments, ast, lines) {
});
};
function breakTies(tiesToBreak, lines) {
function breakTies(tiesToBreak: any[], lines: any) {
var tieCount = tiesToBreak.length;
if (tieCount === 0) {
return;
@ -232,30 +229,30 @@ function breakTies(tiesToBreak, lines) {
tiesToBreak.length = 0;
}
function addCommentHelper(node, comment) {
function addCommentHelper(node: any, comment: any) {
var comments = node.comments || (node.comments = []);
comments.push(comment);
}
function addLeadingComment(node, comment) {
function addLeadingComment(node: any, comment: any) {
comment.leading = true;
comment.trailing = false;
addCommentHelper(node, comment);
}
function addDanglingComment(node, comment) {
function addDanglingComment(node: any, comment: any) {
comment.leading = false;
comment.trailing = false;
addCommentHelper(node, comment);
}
function addTrailingComment(node, comment) {
function addTrailingComment(node: any, comment: any) {
comment.leading = false;
comment.trailing = true;
addCommentHelper(node, comment);
}
function printLeadingComment(commentPath, print) {
function printLeadingComment(commentPath: any, print: any) {
var comment = commentPath.getValue();
n.Comment.assert(comment);
@ -291,7 +288,7 @@ function printLeadingComment(commentPath, print) {
return concat(parts);
}
function printTrailingComment(commentPath, print) {
function printTrailingComment(commentPath: any, print: any) {
var comment = commentPath.getValue(commentPath);
n.Comment.assert(comment);
@ -319,7 +316,7 @@ function printTrailingComment(commentPath, print) {
return concat(parts);
}
exports.printComments = function(path, print) {
export function printComments(path: any, print: any) {
var value = path.getValue();
var innerLines = print(path);
var comments = n.Node.check(value) &&
@ -329,10 +326,10 @@ exports.printComments = function(path, print) {
return innerLines;
}
var leadingParts = [];
var leadingParts: any[] = [];
var trailingParts = [innerLines];
path.each(function(commentPath) {
path.each(function(commentPath: any) {
var comment = commentPath.getValue();
var leading = types.getFieldValue(comment, "leading");
var trailing = types.getFieldValue(comment, "trailing");

View file

@ -1,18 +1,41 @@
var assert = require("assert");
var types = require("./types");
import assert from "assert";
import types from "./types";
var n = types.namedTypes;
var Node = n.Node;
var isArray = types.builtInTypes.array;
var isNumber = types.builtInTypes.number;
var util = require("./util.js");
import * as util from "./util";
function FastPath(value) {
assert.ok(this instanceof FastPath);
this.stack = [value];
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: any): any;
canBeFirstInStatement(): any;
firstInStatement(): any;
}
var FPp = FastPath.prototype;
module.exports = FastPath;
interface FastPathConstructor {
new(value: any): FastPathType;
from(obj: any): any;
}
const FastPath = function FastPath(this: FastPathType, value: any) {
assert.ok(this instanceof FastPath);
this.stack = [value];
} as any as FastPathConstructor;
var FPp: FastPathType = FastPath.prototype;
// Static convenience function for coercing a value to a FastPath.
FastPath.from = function(obj) {
@ -68,7 +91,7 @@ FPp.valueIsDuplicate = function () {
return s.lastIndexOf(s[valueIndex], valueIndex - 1) >= 0;
};
function getNodeHelper(path, count) {
function getNodeHelper(path: any, count: number) {
var s = path.stack;
for (var i = s.length - 1; i >= 0; i -= 2) {
@ -81,11 +104,11 @@ function getNodeHelper(path, count) {
return null;
}
FPp.getNode = function getNode(count) {
FPp.getNode = function getNode(count = 0) {
return getNodeHelper(this, ~~count);
};
FPp.getParentNode = function getParentNode(count) {
FPp.getParentNode = function getParentNode(count = 0) {
return getNodeHelper(this, ~~count + 1);
};
@ -474,12 +497,13 @@ FPp.needsParens = function(assumeExpressionContext) {
return false;
};
function isBinary(node) {
function isBinary(node: any) {
return n.BinaryExpression.check(node)
|| n.LogicalExpression.check(node);
}
function isUnaryLike(node) {
// @ts-ignore 'isUnaryLike' is declared but its value is never read. [6133]
function isUnaryLike(node: any) {
return n.UnaryExpression.check(node)
// I considered making SpreadElement and SpreadProperty subtypes of
// UnaryExpression, but they're not really Expression nodes.
@ -487,7 +511,7 @@ function isUnaryLike(node) {
|| (n.SpreadProperty && n.SpreadProperty.check(node));
}
var PRECEDENCE = {};
var PRECEDENCE: any = {};
[["||"],
["&&"],
["|"],
@ -504,7 +528,7 @@ var PRECEDENCE = {};
});
});
function containsCallExpression(node) {
function containsCallExpression(node: any): any {
if (n.CallExpression.check(node)) {
return true;
}
@ -514,7 +538,7 @@ function containsCallExpression(node) {
}
if (n.Node.check(node)) {
return types.someField(node, function(name, child) {
return types.someField(node, function(_name: any, child: any) {
return containsCallExpression(child);
});
}
@ -625,3 +649,5 @@ FPp.firstInStatement = function() {
return true;
};
export default FastPath;

View file

@ -1,11 +1,12 @@
var assert = require("assert");
var sourceMap = require("source-map");
var normalizeOptions = require("./options").normalize;
var secretKey = require("private").makeUniqueKey();
var types = require("./types");
import assert from "assert";
import sourceMap from "source-map";
import { normalize as normalizeOptions } from "./options";
import { makeUniqueKey } from "private";
var secretKey = makeUniqueKey();
import types from "./types";
var isString = types.builtInTypes.string;
var comparePos = require("./util").comparePos;
var Mapping = require("./mapping");
import { comparePos } from "./util";
import Mapping from "./mapping";
// Goals:
// 1. Minimize new string creation.
@ -15,16 +16,58 @@ var Mapping = require("./mapping");
// 5. No newline characters.
var useSymbol = typeof Symbol === "function";
// @ts-ignore Subsequent variable declarations must have the same type.
var secretKey = "recastLinesSecret";
if (useSymbol) {
secretKey = Symbol.for(secretKey);
}
function getSecret(lines) {
function getSecret(lines: any) {
return lines[secretKey];
}
function Lines(infos, sourceFileName) {
export type Pos = { line: number, column: number };
export interface LinesType {
length: any;
name: any;
toString(options?: any): any;
getSourceMap(sourceMapName: any, sourceRoot: any): any;
bootstrapCharAt(pos: any): any;
charAt(pos: any): any;
stripMargin(width: any, skipFirstLine: any): any;
indent(by: number): any;
indentTail(by: any): any;
lockIndentTail (): any;
getIndentAt(line: any): any;
guessTabWidth(): any;
startsWithComment (): any;
isOnlyWhitespace(): any;
isPrecededOnlyByWhitespace(pos: any): any;
getLineLength(line: any): any;
nextPos(pos: any, skipSpaces?: any): any;
prevPos(pos: any, skipSpaces?: any): any;
firstPos(): Pos;
lastPos(): Pos;
skipSpaces(pos: any, backward?: any, modifyInPlace?: any): any;
trimLeft(): any;
trimRight(): any;
trim(): any;
eachPos(callback: (pos: Pos) => any, startPos?: any, skipSpaces?: any): any;
bootstrapSlice(start: any, end: any): any;
slice(start?: Pos, end?: Pos): LinesType;
bootstrapSliceString(start: any, end: any, options: any): any;
sliceString(start: any, end: any, options?: any): any;
isEmpty(): any;
join(elements: any): any;
concat(...args: any[]): any;
}
interface LinesConstructor {
new(infos: any, sourceFileName?: any): LinesType;
}
const Lines = function Lines(this: LinesType, infos: any, sourceFileName?: any) {
assert.ok(this instanceof Lines);
assert.ok(infos.length > 0);
@ -50,9 +93,13 @@ function Lines(infos, sourceFileName) {
end: this.lastPos()
}));
}
}
} as any as LinesConstructor;
function setSymbolOrKey(obj, key, value) {
// Exposed for instanceof checks. The fromString function should be used
// to create new Lines objects.
export { Lines };
function setSymbolOrKey(obj: any, key: any, value: any) {
if (useSymbol) {
return obj[key] = value;
}
@ -67,12 +114,9 @@ function setSymbolOrKey(obj, key, value) {
return value;
}
// Exposed for instanceof checks. The fromString function should be used
// to create new Lines objects.
exports.Lines = Lines;
var Lp = Lines.prototype;
var Lp: LinesType = Lines.prototype;
function copyLineInfo(info) {
function copyLineInfo(info: any) {
return {
line: info.line,
indent: info.indent,
@ -82,11 +126,11 @@ function copyLineInfo(info) {
};
}
var fromStringCache = {};
var fromStringCache: any = {};
var hasOwn = fromStringCache.hasOwnProperty;
var maxCacheKeyLen = 10;
function countSpaces(spaces, tabWidth) {
export function countSpaces(spaces: any, tabWidth?: number) {
var count = 0;
var len = spaces.length;
@ -94,11 +138,11 @@ function countSpaces(spaces, tabWidth) {
switch (spaces.charCodeAt(i)) {
case 9: // '\t'
assert.strictEqual(typeof tabWidth, "number");
assert.ok(tabWidth > 0);
assert.ok(tabWidth! > 0);
var next = Math.ceil(count / tabWidth) * tabWidth;
var next = Math.ceil(count / tabWidth!) * tabWidth!;
if (next === count) {
count += tabWidth;
count += tabWidth!;
} else {
count = next;
}
@ -121,7 +165,6 @@ function countSpaces(spaces, tabWidth) {
return count;
}
exports.countSpaces = countSpaces;
var leadingSpaceExp = /^\s*/;
@ -132,7 +175,7 @@ var lineTerminatorSeqExp =
/**
* @param {Object} options - Options object that configures printing.
*/
function fromString(string, options) {
export function fromString(string: string | LinesType, options?: any): LinesType {
if (string instanceof Lines)
return string;
@ -149,7 +192,8 @@ function fromString(string, options) {
return fromStringCache[string];
var lines = new Lines(string.split(lineTerminatorSeqExp).map(function(line) {
var spaces = leadingSpaceExp.exec(line)[0];
// TODO: handle null exec result
var spaces = leadingSpaceExp.exec(line)![0];
return {
line: line,
indent: countSpaces(spaces, tabWidth),
@ -165,9 +209,8 @@ function fromString(string, options) {
return lines;
}
exports.fromString = fromString;
function isOnlyWhitespace(string) {
function isOnlyWhitespace(string: string) {
return !/\S/.test(string);
}
@ -185,7 +228,7 @@ Lp.getSourceMap = function(sourceMapName, sourceRoot) {
var targetLines = this;
function updateJSON(json) {
function updateJSON(json?: any) {
json = json || {};
isString.assert(sourceMapName);
@ -209,9 +252,9 @@ Lp.getSourceMap = function(sourceMapName, sourceRoot) {
}
var smg = new sourceMap.SourceMapGenerator(updateJSON());
var sourcesToContents = {};
var sourcesToContents: any = {};
secret.mappings.forEach(function(mapping) {
secret.mappings.forEach(function(mapping: any) {
var sourceCursor = mapping.sourceLines.skipSpaces(
mapping.sourceLoc.start
) || mapping.sourceLines.lastPos();
@ -251,7 +294,7 @@ Lp.getSourceMap = function(sourceMapName, sourceRoot) {
secret.cachedSourceMap = smg;
return smg.toJSON();
return (smg as any).toJSON();
};
Lp.bootstrapCharAt = function(pos) {
@ -319,7 +362,7 @@ Lp.stripMargin = function(width, skipFirstLine) {
var secret = getSecret(this);
var lines = new Lines(secret.infos.map(function(info, i) {
var lines = new Lines(secret.infos.map(function(info: any, i: any) {
if (info.line && (i > 0 || !skipFirstLine)) {
info = copyLineInfo(info);
info.indent = Math.max(0, info.indent - width);
@ -330,7 +373,7 @@ Lp.stripMargin = function(width, skipFirstLine) {
if (secret.mappings.length > 0) {
var newMappings = getSecret(lines).mappings;
assert.strictEqual(newMappings.length, 0);
secret.mappings.forEach(function(mapping) {
secret.mappings.forEach(function(mapping: any) {
newMappings.push(mapping.indent(width, skipFirstLine, true));
});
}
@ -344,7 +387,7 @@ Lp.indent = function(by) {
var secret = getSecret(this);
var lines = new Lines(secret.infos.map(function(info) {
var lines = new Lines(secret.infos.map(function(info: any) {
if (info.line && ! info.locked) {
info = copyLineInfo(info);
info.indent += by;
@ -355,7 +398,7 @@ Lp.indent = function(by) {
if (secret.mappings.length > 0) {
var newMappings = getSecret(lines).mappings;
assert.strictEqual(newMappings.length, 0);
secret.mappings.forEach(function(mapping) {
secret.mappings.forEach(function(mapping: any) {
newMappings.push(mapping.indent(by));
});
}
@ -372,7 +415,7 @@ Lp.indentTail = function(by) {
var secret = getSecret(this);
var lines = new Lines(secret.infos.map(function(info, i) {
var lines = new Lines(secret.infos.map(function(info: any, i: any) {
if (i > 0 && info.line && ! info.locked) {
info = copyLineInfo(info);
info.indent += by;
@ -384,7 +427,7 @@ Lp.indentTail = function(by) {
if (secret.mappings.length > 0) {
var newMappings = getSecret(lines).mappings;
assert.strictEqual(newMappings.length, 0);
secret.mappings.forEach(function(mapping) {
secret.mappings.forEach(function(mapping: any) {
newMappings.push(mapping.indent(by, true));
});
}
@ -399,7 +442,7 @@ Lp.lockIndentTail = function () {
var infos = getSecret(this).infos;
return new Lines(infos.map(function (info, i) {
return new Lines(infos.map(function (info: any, i: any) {
info = copyLineInfo(info);
info.locked = i > 0;
return info;
@ -419,7 +462,7 @@ Lp.guessTabWidth = function() {
return secret.cachedTabWidth;
}
var counts = []; // Sparse array.
var counts: any[] = []; // Sparse array.
var lastIndent = 0;
for (var line = 1, last = this.length; line <= last; ++line) {
@ -656,6 +699,10 @@ Lp.slice = function(start, end) {
end = this.lastPos();
}
if (!start) {
throw new Error("cannot slice with end but not start");
}
var secret = getSecret(this);
var sliced = secret.infos.slice(start.line - 1, end.line);
@ -672,7 +719,7 @@ Lp.slice = function(start, end) {
if (secret.mappings.length > 0) {
var newMappings = getSecret(lines).mappings;
assert.strictEqual(newMappings.length, 0);
secret.mappings.forEach(function(mapping) {
secret.mappings.forEach(function(this: any, mapping: any) {
var sliced = mapping.slice(this, start, end);
if (sliced) {
newMappings.push(sliced);
@ -683,7 +730,7 @@ Lp.slice = function(start, end) {
return lines;
};
function sliceInfo(info, startCol, endCol) {
function sliceInfo(info: any, startCol: number, endCol?: number) {
var sliceStart = info.sliceStart;
var sliceEnd = info.sliceEnd;
var indent = Math.max(info.indent, 0);
@ -815,11 +862,11 @@ Lp.isEmpty = function() {
Lp.join = function(elements) {
var separator = this;
var separatorSecret = getSecret(separator);
var infos = [];
var mappings = [];
var prevInfo;
var infos: any[] = [];
var mappings: any[] = [];
var prevInfo: any;
function appendSecret(secret) {
function appendSecret(secret: any) {
if (secret === null)
return;
@ -841,7 +888,7 @@ Lp.join = function(elements) {
prevInfo.sliceEnd = prevInfo.line.length;
if (secret.mappings.length > 0) {
secret.mappings.forEach(function(mapping) {
secret.mappings.forEach(function(mapping: any) {
mappings.push(mapping.add(prevLine, prevColumn));
});
}
@ -850,7 +897,7 @@ Lp.join = function(elements) {
mappings.push.apply(mappings, secret.mappings);
}
secret.infos.forEach(function(info, i) {
secret.infos.forEach(function(info: any, i: any) {
if (!prevInfo || i > 0) {
prevInfo = copyLineInfo(info);
infos.push(prevInfo);
@ -858,13 +905,13 @@ Lp.join = function(elements) {
});
}
function appendWithSeparator(secret, i) {
function appendWithSeparator(secret: any, i: any) {
if (i > 0)
appendSecret(separatorSecret);
appendSecret(secret);
}
elements.map(function(elem) {
elements.map(function(elem: any) {
var lines = fromString(elem);
if (lines.isEmpty())
return null;
@ -883,13 +930,12 @@ Lp.join = function(elements) {
return lines;
};
exports.concat = function(elements) {
export function concat(elements: any) {
return emptyLines.join(elements);
};
Lp.concat = function(other) {
var args = arguments,
list = [this];
Lp.concat = function(...args) {
var list = [this];
list.push.apply(list, args);
assert.strictEqual(list.length, args.length + 1);
return emptyLines.join(list);

View file

@ -1,13 +1,26 @@
var assert = require("assert");
var types = require("./types");
var isString = types.builtInTypes.string;
import assert from "assert";
import types from "./types";
var isNumber = types.builtInTypes.number;
var SourceLocation = types.namedTypes.SourceLocation;
var Position = types.namedTypes.Position;
var linesModule = require("./lines");
var comparePos = require("./util").comparePos;
import * as linesModule from "./lines";
import { comparePos } from "./util";
function Mapping(sourceLines, sourceLoc, targetLoc) {
interface MappingType {
sourceLines: any;
sourceLoc: any;
targetLoc: any;
slice(lines: any, start: any, end: any): MappingType | null;
add(line: number, column: number): MappingType;
subtract(line: number, column: number): MappingType;
indent(by: any, skipFirstLine: any, noNegativeColumns: any): MappingType;
}
interface MappingConstructor {
new(sourceLines: any, sourceLoc: any, targetLoc?: any): MappingType;
}
const Mapping = function Mapping(this: MappingType, sourceLines: any, sourceLoc: any, targetLoc?: any) {
assert.ok(this instanceof Mapping);
assert.ok(sourceLines instanceof linesModule.Lines);
SourceLocation.assert(sourceLoc);
@ -32,10 +45,10 @@ function Mapping(sourceLines, sourceLoc, targetLoc) {
sourceLoc: { value: sourceLoc },
targetLoc: { value: targetLoc }
});
}
} as any as MappingConstructor;
var Mp = Mapping.prototype;
module.exports = Mapping;
var Mp: MappingType = Mapping.prototype;
export default Mapping;
Mp.slice = function(lines, start, end) {
assert.ok(lines instanceof linesModule.Lines);
@ -51,7 +64,7 @@ Mp.slice = function(lines, start, end) {
var sourceLoc = this.sourceLoc;
var targetLoc = this.targetLoc;
function skip(name) {
function skip(name: string) {
var sourceFromPos = sourceLoc[name];
var targetFromPos = targetLoc[name];
var targetToPos = start;
@ -134,7 +147,7 @@ Mp.add = function(line, column) {
});
};
function addPos(toPos, line, column) {
function addPos(toPos: any, line: number, column: number) {
return {
line: toPos.line + line - 1,
column: (toPos.line === 1)
@ -150,7 +163,7 @@ Mp.subtract = function(line, column) {
});
};
function subtractPos(fromPos, line, column) {
function subtractPos(fromPos: any, line: number, column: number) {
return {
line: fromPos.line - line + 1,
column: (fromPos.line === line)
@ -201,8 +214,8 @@ Mp.indent = function(by, skipFirstLine, noNegativeColumns) {
};
function skipChars(
sourceLines, sourceFromPos,
targetLines, targetFromPos, targetToPos
sourceLines: any, sourceFromPos: any,
targetLines: any, targetFromPos: any, targetToPos: any
) {
assert.ok(sourceLines instanceof linesModule.Lines);
assert.ok(targetLines instanceof linesModule.Lines);

View file

@ -1,106 +1,198 @@
var defaults = {
// 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).
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;
}
var defaults: Options = {
parser: require("../parsers/esprima"),
// 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.
tabWidth: 4,
// If you really want the pretty-printer to use tabs instead of spaces,
// make this option true.
useTabs: false,
// The reprinting code leaves leading whitespace untouched unless it has
// to reindent a line, or you pass false for this option.
reuseWhitespace: true,
// Override this option to use a different line terminator, e.g. \r\n.
lineTerminator: require("os").EOL || "\n",
// 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.
wrapColumn: 74, // Aspirational for now.
// 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.
sourceFileName: 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.
sourceMapName: null,
// If provided, this option will be passed along to the source map
// generator as a root directory for relative source file paths.
sourceRoot: 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.
inputSourceMap: null,
// If you want esprima to generate .range information (recast only uses
// .loc internally), pass true for this option.
range: false,
// If you want esprima not to throw exceptions when it encounters
// non-fatal errors, keep this option true.
tolerant: true,
// 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.
quote: 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,
// }
trailingComma: false,
// Controls the printing of spaces inside array brackets.
// See: http://eslint.org/docs/rules/array-bracket-spacing
arrayBracketSpacing: false,
// Controls the printing of spaces inside object literals,
// destructuring assignments, and import/export specifiers.
// See: http://eslint.org/docs/rules/object-curly-spacing
objectCurlySpacing: true,
// If you want parenthesis to wrap single-argument arrow function
// parameter lists, pass true for this option.
arrowParensAlways: false,
// 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.
flowObjectCommas: true,
// Whether to return an array of .tokens on the root AST node.
tokens: true
}, hasOwn = defaults.hasOwnProperty;
// Copy options and fill in default values.
exports.normalize = function(options) {
options = options || defaults;
export type NormalizedOptions = Required<Omit<Options, keyof DeprecatedOptions>>;
function get(key) {
// Copy options and fill in default values.
export function normalize(opts?: Options): NormalizedOptions {
var options = opts || defaults;
function get(key: keyof Options) {
return hasOwn.call(options, key)
? options[key]
: defaults[key];

View file

@ -1,19 +1,15 @@
"use strict";
var assert = require("assert");
var types = require("./types");
var n = types.namedTypes;
import assert from "assert";
import types from "./types";
var b = types.builders;
var isObject = types.builtInTypes.object;
var isArray = types.builtInTypes.array;
var isFunction = types.builtInTypes.function;
var Patcher = require("./patcher").Patcher;
var normalizeOptions = require("./options").normalize;
var fromString = require("./lines").fromString;
var attachComments = require("./comments").attach;
var util = require("./util");
import { normalize as normalizeOptions } from "./options";
import { fromString } from "./lines";
import { attach as attachComments } from "./comments";
import * as util from "./util";
import { Options } from "./options";
exports.parse = function parse(source, options) {
export function parse(source: string, options?: Partial<Options>) {
options = normalizeOptions(options);
const lines = fromString(source, options);
@ -24,7 +20,7 @@ exports.parse = function parse(source, options) {
useTabs: false
});
let comments = [];
let comments: any[] = [];
const ast = options.parser.parse(sourceWithoutTabs, {
jsx: true,
loc: true,
@ -41,7 +37,7 @@ exports.parse = function parse(source, options) {
// tokenizer. All the preconfigured ../parsers/* expose ast.tokens
// automatically, but custom parsers might need additional configuration
// to avoid this fallback.
const tokens = Array.isArray(ast.tokens)
const tokens: any[] = Array.isArray(ast.tokens)
? ast.tokens
: require("esprima").tokenize(sourceWithoutTabs, {
loc: true
@ -90,7 +86,7 @@ exports.parse = function parse(source, options) {
end: lines.lastPos(),
lines: lines,
indent: 0
};
} as any;
} else if (ast.type === "File") {
file = ast;
program = file.program;
@ -106,7 +102,7 @@ exports.parse = function parse(source, options) {
// 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({
var trueProgramLoc: any = util.getTrueLoc({
type: program.type,
loc: program.loc,
body: [],
@ -128,7 +124,22 @@ exports.parse = function parse(source, options) {
return new TreeCopier(lines, tokens).copy(file);
};
function TreeCopier(lines, tokens) {
interface TreeCopierType {
lines: any;
tokens: any[];
startTokenIndex: number;
endTokenIndex: number;
indent: number;
seen: Map<any, any>;
copy(node: any): any;
findTokenRange(loc: any): any;
}
interface TreeCopierConstructor {
new(lines: any, tokens: any): TreeCopierType;
}
const TreeCopier = function TreeCopier(this: TreeCopierType, lines: any, tokens: any) {
assert.ok(this instanceof TreeCopier);
this.lines = lines;
this.tokens = tokens;
@ -136,9 +147,9 @@ function TreeCopier(lines, tokens) {
this.endTokenIndex = tokens.length;
this.indent = 0;
this.seen = new Map;
}
} as any as TreeCopierConstructor;
var TCp = TreeCopier.prototype;
var TCp: TreeCopierType = TreeCopier.prototype;
TCp.copy = function(node) {
if (this.seen.has(node)) {
@ -146,9 +157,9 @@ TCp.copy = function(node) {
}
if (isArray.check(node)) {
var copy = new Array(node.length);
var copy: any = new Array(node.length);
this.seen.set(node, copy);
node.forEach(function (item, i) {
node.forEach(function (this: any, item: any, i: any) {
copy[i] = this.copy(item);
}, this);
return copy;
@ -160,7 +171,7 @@ TCp.copy = function(node) {
util.fixFaultyLocations(node, this.lines);
var copy = Object.create(Object.getPrototypeOf(node), {
var copy: any = Object.create(Object.getPrototypeOf(node), {
original: { // Provide a link from the copy to the original.
value: node,
configurable: false,

View file

@ -1,26 +1,34 @@
var assert = require("assert");
var linesModule = require("./lines");
var types = require("./types");
var getFieldValue = types.getFieldValue;
var Node = types.namedTypes.Node;
import assert from "assert";
import * as linesModule from "./lines";
import types from "./types";
var Printable = types.namedTypes.Printable;
var Expression = types.namedTypes.Expression;
var ReturnStatement = types.namedTypes.ReturnStatement;
var SourceLocation = types.namedTypes.SourceLocation;
var util = require("./util");
var comparePos = util.comparePos;
var FastPath = require("./fast-path");
import { comparePos, copyPos, getUnionOfKeys } from "./util";
import FastPath from "./fast-path";
var isObject = types.builtInTypes.object;
var isArray = types.builtInTypes.array;
var isString = types.builtInTypes.string;
var riskyAdjoiningCharExp = /[0-9a-z_$]/i;
function Patcher(lines) {
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;
}
const Patcher = function Patcher(this: PatcherType, lines: any) {
assert.ok(this instanceof Patcher);
assert.ok(lines instanceof linesModule.Lines);
var self = this,
replacements = [];
replacements: any[] = [];
self.replace = function(loc, lines) {
if (isString.check(lines))
@ -42,9 +50,9 @@ function Patcher(lines) {
};
var sliceFrom = loc.start,
toConcat = [];
toConcat: any[] = [];
function pushSlice(from, to) {
function pushSlice(from: any, to: any) {
assert.ok(comparePos(from, to) <= 0);
toConcat.push(lines.slice(from, to));
}
@ -65,10 +73,10 @@ function Patcher(lines) {
return linesModule.concat(toConcat);
};
}
exports.Patcher = Patcher;
} as any as PatcherConstructor;
export { Patcher };
var Pp = Patcher.prototype;
var Pp: PatcherType = Patcher.prototype;
Pp.tryToReprintComments = function(newNode, oldNode, print) {
var patcher = this;
@ -85,7 +93,7 @@ Pp.tryToReprintComments = function(newNode, oldNode, print) {
newPath.stack.push("comments", getSurroundingComments(newNode));
oldPath.stack.push("comments", getSurroundingComments(oldNode));
var reprints = [];
var reprints: any[] = [];
var ableToReprintComments =
findArrayReprints(newPath, oldPath, reprints);
@ -111,11 +119,11 @@ Pp.tryToReprintComments = function(newNode, oldNode, print) {
// 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 = [];
function getSurroundingComments(node: any) {
var result: any[] = [];
if (node.comments &&
node.comments.length > 0) {
node.comments.forEach(function(comment) {
node.comments.forEach(function(comment: any) {
if (comment.leading || comment.trailing) {
result.push(comment);
}
@ -131,7 +139,7 @@ Pp.deleteComments = function(node) {
var patcher = this;
node.comments.forEach(function(comment) {
node.comments.forEach(function(comment: any) {
if (comment.leading) {
// Delete leading comments along with any trailing whitespace they
// might have.
@ -153,7 +161,7 @@ Pp.deleteComments = function(node) {
});
};
exports.getReprinter = function(path) {
export function getReprinter(path: any) {
assert.ok(path instanceof FastPath);
// Make sure that this path refers specifically to a Node, rather than
@ -162,15 +170,15 @@ exports.getReprinter = function(path) {
if (!Printable.check(node))
return;
var orig = node.original;
var orig = (node as any).original;
var origLoc = orig && orig.loc;
var lines = origLoc && origLoc.lines;
var reprints = [];
var reprints: any[] = [];
if (!lines || !findReprints(path, reprints))
return;
return function(print) {
return function(print: any) {
var patcher = new Patcher(lines);
reprints.forEach(function(reprint) {
@ -235,8 +243,8 @@ exports.getReprinter = function(path) {
// 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.copyPos(oldLoc.start);
function needsLeadingSpace(oldLines: any, oldLoc: any, newLines: any) {
var posBeforeOldLoc = copyPos(oldLoc.start);
// The character just before the location occupied by oldNode.
var charBeforeOldLoc =
@ -255,7 +263,7 @@ function needsLeadingSpace(oldLines, oldLoc, newLines) {
// 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) {
function needsTrailingSpace(oldLines: any, oldLoc: any, newLines: any) {
// The character just after the location occupied by oldNode.
var charAfterOldLoc = oldLines.charAt(oldLoc.end);
@ -271,7 +279,7 @@ function needsTrailingSpace(oldLines, oldLoc, newLines) {
riskyAdjoiningCharExp.test(charAfterOldLoc);
}
function findReprints(newPath, reprints) {
function findReprints(newPath: any, reprints: any) {
var newNode = newPath.getValue();
Printable.assert(newNode);
@ -296,7 +304,7 @@ function findReprints(newPath, reprints) {
return canReprint;
}
function findAnyReprints(newPath, oldPath, reprints) {
function findAnyReprints(newPath: any, oldPath: any, reprints: any) {
var newNode = newPath.getValue();
var oldNode = oldPath.getValue();
@ -312,7 +320,7 @@ function findAnyReprints(newPath, oldPath, reprints) {
return false;
}
function findArrayReprints(newPath, oldPath, reprints) {
function findArrayReprints(newPath: any, oldPath: any, reprints: any) {
var newNode = newPath.getValue();
var oldNode = oldPath.getValue();
@ -343,7 +351,7 @@ function findArrayReprints(newPath, oldPath, reprints) {
return true;
}
function findObjectReprints(newPath, oldPath, reprints) {
function findObjectReprints(newPath: any, oldPath: any, reprints: any) {
var newNode = newPath.getValue();
isObject.assert(newNode);
@ -370,8 +378,8 @@ function findObjectReprints(newPath, oldPath, reprints) {
// 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 ((newNode as any).type === (oldNode as any).type) {
var childReprints: any[] = [];
if (findChildReprints(newPath, oldPath, childReprints)) {
reprints.push.apply(reprints, childReprints);
@ -415,7 +423,7 @@ function findObjectReprints(newPath, oldPath, reprints) {
return findChildReprints(newPath, oldPath, reprints);
}
function findChildReprints(newPath, oldPath, reprints) {
function findChildReprints(newPath: any, oldPath: any, reprints: any) {
var newNode = newPath.getValue();
var oldNode = oldPath.getValue();
@ -435,7 +443,7 @@ function findChildReprints(newPath, oldPath, reprints) {
return false;
}
var keys = util.getUnionOfKeys(oldNode, newNode);
var keys = getUnionOfKeys(oldNode, newNode);
if (oldNode.type === "File" ||
newNode.type === "File") {

View file

@ -1,21 +1,28 @@
"use strict";
var assert = require("assert");
var sourceMap = require("source-map");
var printComments = require("./comments").printComments;
var linesModule = require("./lines");
import assert from "assert";
import { printComments } from "./comments";
import * as linesModule from "./lines";
var fromString = linesModule.fromString;
var concat = linesModule.concat;
var normalizeOptions = require("./options").normalize;
var getReprinter = require("./patcher").getReprinter;
var types = require("./types");
import { normalize as normalizeOptions } from "./options";
import { getReprinter } from "./patcher";
import types from "./types";
var namedTypes = types.namedTypes;
var isString = types.builtInTypes.string;
var isObject = types.builtInTypes.object;
var FastPath = require("./fast-path");
var util = require("./util");
import FastPath from "./fast-path";
import * as util from "./util";
function PrintResult(code, sourceMap) {
export interface PrintResultType {
code: string;
map?: any;
toString(): string;
}
interface PrintResultConstructor {
new(code: any, sourceMap?: any): PrintResultType;
}
const PrintResult = function PrintResult(this: PrintResultType, code: any, sourceMap?: any) {
assert.ok(this instanceof PrintResult);
isString.assert(code);
@ -25,9 +32,9 @@ function PrintResult(code, sourceMap) {
isObject.assert(sourceMap);
this.map = sourceMap;
}
}
} as any as PrintResultConstructor;
var PRp = PrintResult.prototype;
var PRp: PrintResultType = PrintResult.prototype;
var warnedAboutToString = false;
PRp.toString = function() {
@ -46,7 +53,16 @@ PRp.toString = function() {
var emptyPrintResult = new PrintResult("");
function Printer(config) {
interface PrinterType {
print(ast: any): PrintResultType;
printGenerically(ast: any): PrintResultType;
}
interface PrinterConstructor {
new(config?: any): PrinterType;
}
const Printer = function Printer(this: PrinterType, config?: any) {
assert.ok(this instanceof Printer);
const explicitTabWidth = config && config.tabWidth;
@ -59,14 +75,14 @@ function Printer(config) {
// Non-destructively modifies options with overrides, and returns a
// new print function that uses the modified options.
function makePrintFunctionWith(options, overrides) {
function makePrintFunctionWith(options: any, overrides: any) {
options = Object.assign({}, options, overrides);
return function (path) {
return function (path: any) {
return print(path, options);
};
}
function print(path, options) {
function print(path: any, options: any) {
assert.ok(path instanceof FastPath);
options = options || {};
@ -139,8 +155,8 @@ function Printer(config) {
}
// Print the entire AST generically.
function printGenerically(path) {
return printComments(path, function (path) {
function printGenerically(path: any) {
return printComments(path, function (path: any) {
return genericPrint(path, config, {
includeComments: true,
avoidRootParens: false
@ -160,11 +176,11 @@ function Printer(config) {
config.reuseWhitespace = oldReuseWhitespace;
return pr;
};
}
} as any as PrinterConstructor;
exports.Printer = Printer;
export { Printer };
function genericPrint(path, config, options, printPath) {
function genericPrint(path: any, config: any, options: any, printPath: any) {
assert.ok(path instanceof FastPath);
const node = path.getValue();
@ -206,7 +222,7 @@ function genericPrint(path, config, options, printPath) {
// functions in this file call the `config` object (that is, the
// configuration object originally passed into the Printer constructor).
// Its properties are documented in lib/options.js.
function genericPrintNoParens(path, options, print) {
function genericPrintNoParens(path: any, options: any, print: any) {
var n = path.getValue();
if (!n) {
@ -219,7 +235,7 @@ function genericPrintNoParens(path, options, print) {
namedTypes.Printable.assert(n);
var parts = [];
var parts: any[] = [];
switch (n.type) {
case "File":
@ -228,7 +244,7 @@ function genericPrintNoParens(path, options, print) {
case "Program":
// Babel 6
if (n.directives) {
path.each(function(childPath) {
path.each(function(childPath: any) {
parts.push(print(childPath), ";\n");
}, "directives");
}
@ -237,7 +253,7 @@ function genericPrintNoParens(path, options, print) {
parts.push(path.call(print, "interpreter"));
}
parts.push(path.call(function(bodyPath) {
parts.push(path.call(function(bodyPath: any) {
return printStatementSequence(bodyPath, options, print);
}, "body"));
@ -524,10 +540,10 @@ function genericPrintNoParens(path, options, print) {
if (n.specifiers &&
n.specifiers.length > 0) {
const unbracedSpecifiers = [];
const bracedSpecifiers = [];
const unbracedSpecifiers: any[] = [];
const bracedSpecifiers: any[] = [];
path.each(function (specifierPath) {
path.each(function (specifierPath: any) {
const spec = specifierPath.getValue();
if (spec.type === "ImportSpecifier") {
bracedSpecifiers.push(print(specifierPath));
@ -577,7 +593,7 @@ function genericPrintNoParens(path, options, print) {
}
case "BlockStatement":
var naked = path.call(function(bodyPath) {
var naked = path.call(function(bodyPath: any) {
return printStatementSequence(bodyPath, options, print);
}, "body");
@ -591,7 +607,7 @@ function genericPrintNoParens(path, options, print) {
parts.push("{\n");
// Babel 6
if (n.directives) {
path.each(function(childPath) {
path.each(function(childPath: any) {
parts.push(
print(childPath).indent(options.tabWidth),
";",
@ -671,7 +687,7 @@ function genericPrintNoParens(path, options, print) {
var i = 0;
fields.forEach(function(field) {
path.each(function(childPath) {
path.each(function(childPath: any) {
var lines = print(childPath);
if (!oneLine) {
@ -753,7 +769,7 @@ function genericPrintNoParens(path, options, print) {
case "ArrayExpression":
case "ArrayPattern":
var elems = n.elements,
var elems: any[] = n.elements,
len = elems.length;
var printed = path.map(print, "elements");
@ -769,7 +785,7 @@ function genericPrintNoParens(path, options, print) {
parts.push("[\n");
}
path.each(function(elemPath) {
path.each(function(elemPath: any) {
var i = elemPath.getName();
var elem = elemPath.getValue();
if (!elem) {
@ -911,7 +927,7 @@ function genericPrintNoParens(path, options, print) {
parts.push(n.kind, " ");
var maxLen = 0;
var printed = path.map(function(childPath) {
var printed = path.map(function(childPath: any) {
var lines = print(childPath);
maxLen = Math.max(lines.length, maxLen);
return lines;
@ -1044,7 +1060,7 @@ function genericPrintNoParens(path, options, print) {
return concat(parts);
case "DoExpression":
var statements = path.call(function(bodyPath) {
var statements = path.call(function(bodyPath: any) {
return printStatementSequence(bodyPath, options, print);
}, "body");
@ -1084,7 +1100,7 @@ function genericPrintNoParens(path, options, print) {
if (n.handler) {
parts.push(" ", path.call(print, "handler"));
} else if (n.handlers) {
path.each(function(handlerPath) {
path.each(function(handlerPath: any) {
parts.push(" ", print(handlerPath));
}, "handlers");
}
@ -1136,7 +1152,7 @@ function genericPrintNoParens(path, options, print) {
parts.push("default:");
if (n.consequent.length > 0) {
parts.push("\n", path.call(function(consequentPath) {
parts.push("\n", path.call(function(consequentPath: any) {
return printStatementSequence(consequentPath, options, print);
}, "consequent").indent(options.tabWidth));
}
@ -1197,7 +1213,7 @@ function genericPrintNoParens(path, options, print) {
}
var childLines = concat(
path.map(function(childPath) {
path.map(function(childPath: any) {
var child = childPath.getValue();
if (namedTypes.Literal.check(child) &&
@ -1223,9 +1239,9 @@ function genericPrintNoParens(path, options, print) {
case "JSXOpeningElement":
parts.push("<", path.call(print, "name"));
var attrParts = [];
var attrParts: any[] = [];
path.each(function(attrPath) {
path.each(function(attrPath: any) {
attrParts.push(" ", print(attrPath));
}, "attributes");
@ -1280,7 +1296,7 @@ function genericPrintNoParens(path, options, print) {
return concat([
"{\n",
path.call(function(bodyPath) {
path.call(function(bodyPath: any) {
return printStatementSequence(bodyPath, options, print);
}, "body").indent(options.tabWidth),
"\n}"
@ -1403,7 +1419,7 @@ function genericPrintNoParens(path, options, print) {
var expressions = path.map(print, "expressions");
parts.push("`");
path.each(function(childPath) {
path.each(function(childPath: any) {
var i = childPath.getName();
parts.push(print(childPath));
if (i < expressions.length) {
@ -1498,7 +1514,7 @@ function genericPrintNoParens(path, options, print) {
parts.push("[\n");
}
path.each(function(elemPath) {
path.each(function(elemPath: any) {
var i = elemPath.getName();
var elem = elemPath.getValue();
if (!elem) {
@ -2098,7 +2114,6 @@ function genericPrintNoParens(path, options, print) {
// in a type predicate, it takes the for u is U
var parent = path.getParentNode(0);
var prefix = ": ";
var isFunctionType = namedTypes.TSFunctionType.check(parent);
if (namedTypes.TSFunctionType.check(parent)) {
prefix = " => ";
}
@ -2383,7 +2398,7 @@ function genericPrintNoParens(path, options, print) {
}
case "TSModuleBlock":
return path.call(function (bodyPath) {
return path.call(function (bodyPath: any) {
return printStatementSequence(bodyPath, options, print);
}, "body");
@ -2424,12 +2439,10 @@ function genericPrintNoParens(path, options, print) {
debugger;
throw new Error("unknown type: " + JSON.stringify(n.type));
}
return p;
}
function printDecorators(path, printPath) {
const parts = [];
function printDecorators(path: any, printPath: any) {
const parts: any[] = [];
const node = path.getValue();
if (node.decorators &&
@ -2438,7 +2451,7 @@ function printDecorators(path, printPath) {
// responsible for printing node.decorators.
! util.getParentExportDeclaration(path)) {
path.each(function(decoratorPath) {
path.each(function(decoratorPath: any) {
parts.push(printPath(decoratorPath), "\n");
}, "decorators");
@ -2447,7 +2460,7 @@ function printDecorators(path, printPath) {
node.declaration.decorators) {
// Export declarations are responsible for printing any decorators
// that logically apply to node.declaration.
path.each(function(decoratorPath) {
path.each(function(decoratorPath: any) {
parts.push(printPath(decoratorPath), "\n");
}, "declaration", "decorators");
}
@ -2455,17 +2468,12 @@ function printDecorators(path, printPath) {
return concat(parts);
}
function printStatementSequence(path, options, print) {
var inClassBody =
namedTypes.ClassBody &&
namedTypes.ClassBody.check(path.getParentNode());
var filtered = [];
function printStatementSequence(path: any, options: any, print: any) {
var filtered: any[] = [];
var sawComment = false;
var sawStatement = false;
path.each(function(stmtPath) {
var i = stmtPath.getName();
path.each(function(stmtPath: any) {
var stmt = stmtPath.getValue();
// Just in case the AST has been modified to contain falsy
@ -2513,9 +2521,9 @@ function printStatementSequence(path, options, print) {
);
}
var prevTrailingSpace = null;
var prevTrailingSpace: any = null;
var len = filtered.length;
var parts = [];
var parts: any[] = [];
filtered.forEach(function(info, i) {
var printed = info.printed;
@ -2570,7 +2578,7 @@ function printStatementSequence(path, options, print) {
return concat(parts);
}
function maxSpace(s1, s2) {
function maxSpace(s1: any, s2: any) {
if (!s1 && !s2) {
return fromString("");
}
@ -2593,7 +2601,7 @@ function maxSpace(s1, s2) {
return spaceLines1;
}
function printMethod(path, options, print) {
function printMethod(path: any, options: any, print: any) {
var node = path.getNode();
var kind = node.kind;
var parts = [];
@ -2662,7 +2670,7 @@ function printMethod(path, options, print) {
parts.push(
path.call(print, "value", "typeParameters"),
"(",
path.call(function(valuePath) {
path.call(function(valuePath: any) {
return printFunctionParams(valuePath, options, print);
}, "value"),
")",
@ -2679,7 +2687,7 @@ function printMethod(path, options, print) {
return concat(parts);
}
function printArgumentsList(path, options, print) {
function printArgumentsList(path: any, options: any, print: any) {
var printed = path.map(print, "arguments");
var trailingComma = util.isTrailingCommaEnabled(options, "parameters");
@ -2696,7 +2704,7 @@ function printArgumentsList(path, options, print) {
return concat(["(", joined, ")"]);
}
function printFunctionParams(path, options, print) {
function printFunctionParams(path: any, options: any, print: any) {
var fun = path.getValue();
if (fun.params) {
@ -2708,7 +2716,7 @@ function printFunctionParams(path, options, print) {
}
if (fun.defaults) {
path.each(function(defExprPath) {
path.each(function(defExprPath: any) {
var i = defExprPath.getName();
var p = printed[i];
if (p && defExprPath.getValue()) {
@ -2738,7 +2746,7 @@ function printFunctionParams(path, options, print) {
return joined;
}
function printExportDeclaration(path, options, print) {
function printExportDeclaration(path: any, options: any, print: any) {
var decl = path.getValue();
var parts = ["export "];
if (decl.exportKind && decl.exportKind !== "value") {
@ -2766,10 +2774,10 @@ function printExportDeclaration(path, options, print) {
parts.push("{}");
} else if (decl.specifiers[0].type === 'ExportDefaultSpecifier') {
const unbracedSpecifiers = [];
const bracedSpecifiers = [];
const unbracedSpecifiers: any[] = [];
const bracedSpecifiers: any[] = [];
path.each(function (specifierPath) {
path.each(function (specifierPath: any) {
const spec = specifierPath.getValue();
if (spec.type === "ExportDefaultSpecifier") {
unbracedSpecifiers.push(print(specifierPath));
@ -2835,7 +2843,7 @@ function printExportDeclaration(path, options, print) {
return lines;
}
function printFlowDeclaration(path, parts) {
function printFlowDeclaration(path: any, parts: any) {
var parentExportDecl = util.getParentExportDeclaration(path);
if (parentExportDecl) {
@ -2853,8 +2861,8 @@ function printFlowDeclaration(path, parts) {
return concat(parts);
}
function printVariance(path, print) {
return path.call(function (variancePath) {
function printVariance(path: any, print: any) {
return path.call(function (variancePath: any) {
var value = variancePath.getValue();
if (value) {
@ -2873,7 +2881,7 @@ function printVariance(path, print) {
}, "variance");
}
function adjustClause(clause, options) {
function adjustClause(clause: any, options: any) {
if (clause.length > 1)
return concat([" ", clause]);
@ -2883,7 +2891,7 @@ function adjustClause(clause, options) {
]);
}
function lastNonSpaceCharacter(lines) {
function lastNonSpaceCharacter(lines: any) {
var pos = lines.lastPos();
do {
var ch = lines.charAt(pos);
@ -2892,17 +2900,17 @@ function lastNonSpaceCharacter(lines) {
} while (lines.prevPos(pos));
}
function endsWithBrace(lines) {
function endsWithBrace(lines: any) {
return lastNonSpaceCharacter(lines) === "}";
}
function swapQuotes(str) {
function swapQuotes(str: string) {
return str.replace(/['"]/g, function(m) {
return m === '"' ? '\'' : '"';
});
}
function nodeStr(str, options) {
function nodeStr(str: string, options: any) {
isString.assert(str);
switch (options.quote) {
case "auto":
@ -2917,7 +2925,7 @@ function nodeStr(str, options) {
}
}
function maybeAddSemicolon(lines) {
function maybeAddSemicolon(lines: any) {
var eoc = lastNonSpaceCharacter(lines);
if (!eoc || "\n};".indexOf(eoc) < 0)
return concat([lines, ";"]);

View file

@ -2,4 +2,6 @@
// custom types to the AST type system (in particular, the File type), but
// those types are now incorporated into ast-types, so this module doesn't
// have much to do anymore. Still, it might prove useful in the future.
module.exports = require("ast-types");
import astTypes from "ast-types";
export default astTypes;
export * from "ast-types";

View file

@ -1,26 +1,23 @@
var assert = require("assert");
var types = require("./types");
var getFieldValue = types.getFieldValue;
import assert from "assert";
import types from "./types";
var n = types.namedTypes;
var sourceMap = require("source-map");
import sourceMap from "source-map";
var SourceMapConsumer = sourceMap.SourceMapConsumer;
var SourceMapGenerator = sourceMap.SourceMapGenerator;
var hasOwn = Object.prototype.hasOwnProperty;
var util = exports;
function getOption(options, key, defaultValue) {
export function getOption(options: any, key: any, defaultValue: any) {
if (options && hasOwn.call(options, key)) {
return options[key];
}
return defaultValue;
}
util.getOption = getOption;
function getUnionOfKeys() {
var result = {};
var argc = arguments.length;
export function getUnionOfKeys(...args: any[]) {
var result: any = {};
var argc = args.length;
for (var i = 0; i < argc; ++i) {
var keys = Object.keys(arguments[i]);
var keys = Object.keys(args[i]);
var keyCount = keys.length;
for (var j = 0; j < keyCount; ++j) {
result[keys[j]] = true;
@ -28,22 +25,19 @@ function getUnionOfKeys() {
}
return result;
}
util.getUnionOfKeys = getUnionOfKeys;
function comparePos(pos1, pos2) {
export function comparePos(pos1: any, pos2: any) {
return (pos1.line - pos2.line) || (pos1.column - pos2.column);
}
util.comparePos = comparePos;
function copyPos(pos) {
export function copyPos(pos: any) {
return {
line: pos.line,
column: pos.column
};
}
util.copyPos = copyPos;
util.composeSourceMaps = function(formerMap, latterMap) {
export function composeSourceMaps(formerMap: any, latterMap: any) {
if (formerMap) {
if (!latterMap) {
return formerMap;
@ -59,7 +53,7 @@ util.composeSourceMaps = function(formerMap, latterMap) {
sourceRoot: latterMap.sourceRoot
});
var sourcesToContents = {};
var sourcesToContents: any = {};
smcLatter.eachMapping(function(mapping) {
var origPos = smcFormer.originalPositionFor({
@ -89,10 +83,10 @@ util.composeSourceMaps = function(formerMap, latterMap) {
}
});
return smg.toJSON();
return (smg as any).toJSON();
};
util.getTrueLoc = function(node, lines) {
export function getTrueLoc(node: any, lines: any) {
// 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
@ -106,7 +100,7 @@ util.getTrueLoc = function(node, lines) {
end: node.loc.end
};
function include(node) {
function include(node: any) {
expandLoc(result, node.loc);
}
@ -115,7 +109,7 @@ util.getTrueLoc = function(node, lines) {
// positions of the export declaration node.
if (node.declaration &&
node.declaration.decorators &&
util.isExportDeclaration(node)) {
isExportDeclaration(node)) {
node.declaration.decorators.forEach(include);
}
@ -141,7 +135,7 @@ util.getTrueLoc = function(node, lines) {
return result;
};
function expandLoc(parentLoc, childLoc) {
function expandLoc(parentLoc: any, childLoc: any) {
if (parentLoc && childLoc) {
if (comparePos(childLoc.start, parentLoc.start) < 0) {
parentLoc.start = childLoc.start;
@ -153,7 +147,7 @@ function expandLoc(parentLoc, childLoc) {
}
}
util.fixFaultyLocations = function(node, lines) {
export function fixFaultyLocations(node: any, lines: any) {
var loc = node.loc;
if (loc) {
if (loc.start.line < 1) {
@ -178,11 +172,11 @@ util.fixFaultyLocations = function(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) {
node.decorators.forEach(function (decorator: any) {
expandLoc(loc, decorator.loc);
});
} else if (node.declaration && util.isExportDeclaration(node)) {
} 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;
@ -191,7 +185,7 @@ util.fixFaultyLocations = function(node, lines) {
// (here, the export declaration) so that it includes node.decorators.
var decorators = node.declaration.decorators;
if (decorators) {
decorators.forEach(function (decorator) {
decorators.forEach(function (decorator: any) {
expandLoc(loc, decorator.loc);
});
}
@ -229,12 +223,12 @@ util.fixFaultyLocations = function(node, lines) {
}
};
function fixForLoopHead(node, lines) {
function fixForLoopHead(node: any, lines: any) {
if (node.type !== "ForStatement") {
return;
}
function fix(child) {
function fix(child: any) {
var loc = child && child.loc;
var start = loc && loc.start;
var end = loc && copyPos(loc.end);
@ -256,7 +250,7 @@ function fixForLoopHead(node, lines) {
fix(node.update);
}
function fixTemplateLiteral(node, lines) {
function fixTemplateLiteral(node: any, lines: any) {
if (node.type !== "TemplateLiteral") {
return;
}
@ -291,7 +285,7 @@ function fixTemplateLiteral(node, lines) {
// 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) {
node.expressions.forEach(function (expr: any, i: any) {
// 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
@ -321,7 +315,7 @@ function fixTemplateLiteral(node, lines) {
});
}
util.isExportDeclaration = function (node) {
export function isExportDeclaration(node: any) {
if (node) switch (node.type) {
case "ExportDeclaration":
case "ExportDefaultDeclaration":
@ -335,17 +329,17 @@ util.isExportDeclaration = function (node) {
return false;
};
util.getParentExportDeclaration = function (path) {
export function getParentExportDeclaration(path: any) {
var parentNode = path.getParentNode();
if (path.getName() === "declaration" &&
util.isExportDeclaration(parentNode)) {
isExportDeclaration(parentNode)) {
return parentNode;
}
return null;
};
util.isTrailingCommaEnabled = function(options, context) {
export function isTrailingCommaEnabled(options: any, context: any) {
var trailingComma = options.trailingComma;
if (typeof trailingComma === "object") {
return !!trailingComma[context];

60
main.ts
View file

@ -1,21 +1,35 @@
var types = require("./lib/types");
var parse = require("./lib/parser").parse;
var Printer = require("./lib/printer").Printer;
import fs from "fs";
import types, { ASTNode } from "./lib/types";
import { parse } from "./lib/parser";
import { Printer } from "./lib/printer";
import { Options } from "./lib/options";
function print(node, options) {
export interface Parser {
parse(source: string, options?: any): ASTNode;
}
function print(node: ASTNode, options?: Options) {
return new Printer(options).print(node);
}
function prettyPrint(node, options) {
function prettyPrint(node: ASTNode, options?: Options) {
return new Printer(options).printGenerically(node);
}
function run(transformer, options) {
interface Transformer {
(ast: ASTNode, callback: (ast: ASTNode) => void): void;
}
interface RunOptions extends Options {
writeback?(code: string): void;
}
function run(transformer: Transformer, options?: RunOptions) {
return runFile(process.argv[2], transformer, options);
}
function runFile(path, transformer, options) {
require("fs").readFile(path, "utf-8", function(err, code) {
function runFile(path: any, transformer: Transformer, options?: RunOptions) {
fs.readFile(path, "utf-8", function(err, code) {
if (err) {
console.error(err);
return;
@ -25,18 +39,28 @@ function runFile(path, transformer, options) {
});
}
function defaultWriteback(output) {
function defaultWriteback(output: string) {
process.stdout.write(output);
}
function runString(code, transformer, options) {
function runString(code: string, transformer: Transformer, options?: RunOptions) {
var writeback = options && options.writeback || defaultWriteback;
transformer(parse(code, options), function(node) {
transformer(parse(code, options), function(node: any) {
writeback(print(node, options).code);
});
}
Object.defineProperties(exports, {
interface Main {
parse: typeof parse;
visit: typeof types.visit;
print: typeof print;
prettyPrint: typeof prettyPrint;
types: typeof types;
run: typeof run;
}
const main = {} as Main;
Object.defineProperties(main, {
/**
* Parse a string of code into an augmented syntax tree suitable for
* arbitrary modification and reprinting.
@ -97,3 +121,15 @@ Object.defineProperties(exports, {
value: run
}
});
export default main;
// Type exports
export {
ASTNode,
NamedTypes,
Builders,
NodePath,
Type,
} from "./lib/types";
export { Options } from "./lib/options";

View file

@ -1,6 +1,12 @@
const getOption = require("../lib/util.js").getOption;
import { ParserOptions, ParserPlugin } from "@babel/parser";
import { getOption } from "../lib/util";
module.exports = function (options) {
export type Overrides = Partial<{
sourceType: ParserOptions["sourceType"];
strictMode: ParserOptions["strictMode"];
}>;
export default function getBabelOptions(options?: Overrides): ParserOptions & { plugins: ParserPlugin[] } {
// The goal here is to tolerate as much syntax as possible, since Recast
// is not in the business of forbidding anything. If you want your
// parser to be more restrictive for some reason, you can always pass
@ -22,7 +28,7 @@ module.exports = function (options) {
"doExpressions",
"dynamicImport",
"exportDefaultFrom",
"exportExtensions",
"exportExtensions" as any as ParserPlugin,
"exportNamespaceFrom",
"functionBind",
"functionSent",
@ -32,7 +38,7 @@ module.exports = function (options) {
"objectRestSpread",
"optionalCatchBinding",
"optionalChaining",
["pipelineOperator", { proposal: "minimal" }],
["pipelineOperator", { proposal: "minimal" }] as any as ParserPlugin,
"throwExpressions",
]
};

View file

@ -1,5 +1,3 @@
"use strict";
// This module is suitable for passing as options.parser when calling
// recast.parse to process JavaScript code with Acorn:
//
@ -7,11 +5,11 @@
// parser: require("recast/parsers/acorn")
// });
//
const getOption = require("../lib/util.js").getOption;
import { getOption } from "../lib/util";
exports.parse = function parse(source, options) {
const comments = [];
const tokens = [];
export function parse(source: string, options?: any) {
const comments: any[] = [];
const tokens: any[] = [];
const ast = require("acorn").parse(source, {
allowHashBang: true,
allowImportExportEverywhere: true,

View file

@ -1,8 +1,11 @@
"use strict";
import { parse as babelParse } from "@babel/parser";
import getBabelOptions, { Overrides } from "./_babel_options";
type BabelParser = { parse: typeof babelParse };
// Prefer the new @babel/parser package, but fall back to babylon if
// that's what's available.
const parser = exports.parser = function () {
export const parser = function (): BabelParser {
try {
return require("@babel/parser");
} catch (e) {
@ -17,8 +20,8 @@ const parser = exports.parser = function () {
// parser: require("recast/parsers/babel")
// });
//
exports.parse = function (source, options) {
options = require("./_babel_options.js")(options);
options.plugins.push("jsx", "flow");
return parser.parse(source, options);
export function parse(source: string, options?: Overrides) {
const babelOptions = getBabelOptions(options);
babelOptions.plugins.push("jsx", "flow");
return parser.parse(source, babelOptions);
};

View file

@ -1,2 +1 @@
"use strict";
Object.assign(exports, require("./babel.js"));
export * from "./babel";

View file

@ -7,10 +7,10 @@
// parser: require("recast/parsers/esprima")
// });
//
const getOption = require("../lib/util.js").getOption;
import { getOption } from "../lib/util";
exports.parse = function (source, options) {
const comments = [];
export function parse(source: string, options?: any) {
const comments: any[] = [];
const ast = require("esprima").parse(source, {
loc: true,
locations: true,
@ -21,7 +21,7 @@ exports.parse = function (source, options) {
tokens: true
});
if (! Array.isArray(ast.comments)) {
if (!Array.isArray(ast.comments)) {
ast.comments = comments;
}

View file

@ -1,6 +1,5 @@
"use strict";
const parser = require("./babel.js").parser;
import { parser } from "./babel";
import getBabelOptions, { Overrides } from "./_babel_options";
// This module is suitable for passing as options.parser when calling
// recast.parse to process Flow code:
@ -9,8 +8,8 @@ const parser = require("./babel.js").parser;
// parser: require("recast/parsers/flow")
// });
//
exports.parse = function parse(source, options) {
options = require("./_babel_options.js")(options);
options.plugins.push("jsx", "flow");
return parser.parse(source, options);
export function parse(source: string, options?: Overrides) {
const babelOptions = getBabelOptions(options);
babelOptions.plugins.push("jsx", "flow");
return parser.parse(source, babelOptions);
};

View file

@ -1,6 +1,5 @@
"use strict";
const parser = require("./babel.js").parser;
import { parser } from "./babel";
import getBabelOptions, { Overrides } from "./_babel_options";
// This module is suitable for passing as options.parser when calling
// recast.parse to process TypeScript code:
@ -9,8 +8,8 @@ const parser = require("./babel.js").parser;
// parser: require("recast/parsers/typescript")
// });
//
exports.parse = function parse(source, options) {
options = require("./_babel_options.js")(options);
options.plugins.push("typescript");
return parser.parse(source, options);
export function parse(source: string, options?: Overrides) {
const babelOptions = getBabelOptions(options);
babelOptions.plugins.push("typescript");
return parser.parse(source, babelOptions);
};

View file

@ -1,8 +1,8 @@
var assert = require("assert");
var recast = require("../main.js");
import assert from "assert";
import recast from "../main";
var n = recast.types.namedTypes;
var b = recast.types.builders;
var eol = require("os").EOL;
import { EOL as eol } from "os";
var nodeMajorVersion = parseInt(process.versions.node, 10);
describe("Babel", function () {
@ -18,7 +18,7 @@ describe("Babel", function () {
};
it("basic printing", function () {
function check(lines) {
function check(lines: any) {
var code = lines.join(eol);
var ast = recast.parse(code, parseOptions);
var output = recast.prettyPrint(ast, { tabWidth: 2 }).code;
@ -323,7 +323,7 @@ describe("Babel", function () {
);
});
function parseExpression(code) {
function parseExpression(code: any) {
return recast.parse(code, parseOptions).program.body[0].expression;
}
@ -376,7 +376,7 @@ describe("Babel", function () {
);
recast.types.visit(ast, {
visitIfStatement: function(path) {
visitIfStatement: function(path: any) {
path.replace(replacement);
return false;
}
@ -399,9 +399,9 @@ describe("Babel", function () {
it("tolerates circular references", function () {
var code = "function foo(bar = true) {}";
var ast = recast.parse(code, {
recast.parse(code, {
parser: {
parse: function (source) {
parse: function (source: any) {
return babelTransform(source, {
code: false,
ast: true,

View file

@ -1,13 +1,12 @@
"use strict";
var recast = require("../main");
import recast from "../main";
var n = recast.types.namedTypes;
var b = recast.types.builders;
var Printer = require("../lib/printer").Printer;
var fromString = require("../lib/lines").fromString;
var assert = require("assert");
var printer = new Printer;
var eol = require("os").EOL;
import { Printer } from "../lib/printer";
import { fromString } from "../lib/lines";
import assert from "assert";
import { EOL as eol } from "os";
var annotated = [
"function dup(/* string */ s,",
@ -30,7 +29,7 @@ describe("comments", function() {
].forEach(runTestsForParser);
});
function runTestsForParser(parserId) {
function runTestsForParser(parserId: any) {
if (nodeMajorVersion < 6) {
const parser = parserId.split("/").pop();
if (parser === "babel" ||
@ -44,7 +43,7 @@ function runTestsForParser(parserId) {
const parserName = parserId.split("/").pop();
const parser = require(parserId);
function pit(message, callback) {
function pit(message: any, callback: any) {
it("[" + parserName + "] " + message, callback);
}
@ -164,20 +163,20 @@ function runTestsForParser(parserId) {
const esprimaInfo = {
Property: n.Property,
propBuilder(key, value) {
propBuilder(key: any, value: any) {
return b.property("init", key, value);
},
literalBuilder(value) {
literalBuilder(value: any) {
return b.literal(value);
}
};
const babelInfo = {
Property: n.ObjectProperty,
propBuilder(key, value) {
propBuilder(key: any, value: any) {
return b.objectProperty(key, value);
},
literalBuilder(value) {
literalBuilder(value: any) {
if (typeof value === "string") {
return b.stringLiteral(value);
}
@ -188,13 +187,13 @@ function runTestsForParser(parserId) {
}
};
const info = {
const info = ({
acorn: esprimaInfo,
babel: babelInfo,
esprima: esprimaInfo,
flow: babelInfo,
typescript: babelInfo
}[parserName];
} as any)[parserName];
var props = assign.right.properties;
info.Property.arrayOf().assert(props);
@ -610,10 +609,10 @@ function runTestsForParser(parserId) {
const ast = recast.parse(code, { parser });
const array = ast.program.body[0].expression;
const stmt = ast.program.body[0];
let danglingComment;
let trailingComment;
let danglingComment: any;
let trailingComment: any;
function handleComment(comment) {
function handleComment(comment: any) {
if (comment.trailing) {
trailingComment = comment;
} else if (! comment.leading) {

View file

@ -1,10 +1,10 @@
var assert = require("assert");
var parse = require("../lib/parser").parse;
var Printer = require("../lib/printer").Printer;
var types = require("../lib/types");
import assert from "assert";
import { parse } from "../lib/parser";
import { Printer } from "../lib/printer";
import types from "../lib/types";
var n = types.namedTypes;
var b = types.builders;
var eol = require("os").EOL;
import { EOL as eol } from "os";
describe("ES6 Compatability", function() {
function convertShorthandMethod() {
@ -27,8 +27,6 @@ describe("ES6 Compatability", function() {
methodDecProperty.kind,
methodDecProperty.key,
methodDecProperty.value,
false,
false
);
var correctMethodProperty = b.property(
@ -41,8 +39,6 @@ describe("ES6 Compatability", function() {
methodDecProperty.value.generator,
methodDecProperty.value.expression
),
false,
false
);
assert.strictEqual(
@ -69,7 +65,7 @@ describe("ES6 Compatability", function() {
describe("import/export syntax", function() {
var printer = new Printer({ tabWidth: 2 });
function check(source) {
function check(source: string) {
var ast1 = parse(source);
var ast2 = parse(printer.printGenerically(ast1).code);
types.astNodesAreEquivalent.assert(ast1, ast2);
@ -140,7 +136,7 @@ describe("import/export syntax", function() {
});
it("should forbid invalid import/export syntax", function() {
function checkInvalid(source, expectedMessage) {
function checkInvalid(source: string, expectedMessage: string) {
try {
parse(source);
throw new Error("Parsing should have failed: " +

View file

@ -1,33 +1,44 @@
var assert = require("assert");
var fs = require("fs");
var path = require("path");
var types = require("../lib/types");
var main = require("../main");
import assert from "assert";
import fs from "fs";
import path from "path";
import types from "../lib/types";
import main from "../main";
function testFile(path) {
var nodeMajorVersion = parseInt(process.versions.node, 10);
function testFile(path: string, options: { parser?: any } = {}) {
fs.readFile(path, "utf-8", function(err, source) {
assert.equal(err, null);
assert.strictEqual(typeof source, "string");
var ast = main.parse(source);
var ast = main.parse(source, options);
types.astNodesAreEquivalent.assert(ast.original, ast);
var code = main.print(ast).code;
assert.strictEqual(source, code);
});
}
function addTest(name) {
function addTest(name: string) {
it(name, function() {
testFile(path.join(__dirname, "..", name + ".js"));
var filename = path.join(__dirname, "..", name);
if (path.extname(filename) === ".ts") {
// Babel 7 no longer supports Node 4 and 5.
if (nodeMajorVersion >= 6) {
testFile(filename, { parser: require("../parsers/typescript") });
}
} else {
testFile(filename);
}
});
}
describe("identity", function() {
// Add more tests here as need be.
addTest("test/data/regexp-props");
addTest("test/data/empty");
addTest("test/data/backbone");
addTest("test/lines");
addTest("lib/lines");
addTest("lib/printer");
addTest("test/data/regexp-props.js");
addTest("test/data/empty.js");
addTest("test/data/backbone.js");
addTest("test/lines.ts");
addTest("lib/lines.ts");
addTest("lib/printer.ts");
});

View file

@ -1,8 +1,8 @@
"use strict";
var parse = require("../lib/parser").parse;
var Printer = require("../lib/printer").Printer;
var types = require("../lib/types");
import { parse } from "../lib/parser";
import { Printer } from "../lib/printer";
import types from "../lib/types";
var nodeMajorVersion = parseInt(process.versions.node, 10);
(nodeMajorVersion >= 6 ? describe : xdescribe)
@ -12,7 +12,7 @@ var nodeMajorVersion = parseInt(process.versions.node, 10);
parser: require("../parsers/babel")
};
function check(source) {
function check(source: string) {
var ast1 = parse(source, parseOptions);
var ast2 = parse(
printer.printGenerically(ast1).code,

View file

@ -1,12 +1,10 @@
var assert = require("assert");
var fs = require("fs");
var path = require("path");
var linesModule = require("../lib/lines");
var fromString = linesModule.fromString;
var concat = linesModule.concat;
var eol = require("os").EOL;
import assert from "assert";
import fs from "fs";
import path from "path";
import { fromString, concat, countSpaces, LinesType } from "../lib/lines";
import { EOL as eol } from "os";
function check(a, b) {
function check(a: any, b: any) {
assert.strictEqual(a.toString({
lineTerminator: eol
}), b.toString({
@ -39,7 +37,7 @@ describe("lines", function() {
});
it("FromString", function() {
function checkIsCached(s) {
function checkIsCached(s: any) {
assert.strictEqual(fromString(s), fromString(s));
check(fromString(s), s);
}
@ -72,15 +70,13 @@ describe("lines", function() {
code);
});
function testEachPosHelper(lines, code) {
var lengths = [];
function testEachPosHelper(lines: any, code: any) {
check(lines, code);
var chars = [];
var chars: any[] = [];
var emptyCount = 0;
function iterator(pos) {
function iterator(pos: any) {
var ch = lines.charAt(pos);
if (ch === "")
emptyCount += 1;
@ -132,7 +128,7 @@ describe("lines", function() {
var code = String(CharAtTest).replace(/\r\n/g, "\n");
var lines = fromString(code);
function compare(pos) {
function compare(pos: any) {
assert.strictEqual(
lines.charAt(pos),
lines.bootstrapCharAt(pos));
@ -148,7 +144,7 @@ describe("lines", function() {
indented = original.indentTail(4),
reference = fromString(" ab" + eol + " c");
function compareIndented(pos) {
function compareIndented(pos: any) {
var c = indented.charAt(pos);
check(c, reference.charAt(pos));
check(c, indented.bootstrapCharAt(pos));
@ -217,7 +213,7 @@ describe("lines", function() {
});
it("Empty", function() {
function c(s) {
function c(s: any) {
var lines = fromString(s);
check(lines, s);
assert.strictEqual(
@ -277,9 +273,9 @@ describe("lines", function() {
checkAllSlices(lines);
});
function checkAllSlices(lines) {
lines.eachPos(function(start) {
lines.eachPos(function(end) {
function checkAllSlices(lines: any) {
lines.eachPos(function(start: any) {
lines.eachPos(function(end: any) {
check(lines.slice(start, end),
lines.bootstrapSlice(start, end));
check(lines.sliceString(start, end),
@ -288,7 +284,7 @@ describe("lines", function() {
});
}
function getSourceLocation(lines) {
function getSourceLocation(lines: any) {
return { start: lines.firstPos(),
end: lines.lastPos() };
}
@ -297,7 +293,7 @@ describe("lines", function() {
var code = String(GetSourceLocationTest),
lines = fromString(code);
function verify(indent) {
function verify(indent: any) {
var indented = lines.indentTail(indent),
loc = getSourceLocation(indented),
string = indented.toString(),
@ -319,9 +315,9 @@ describe("lines", function() {
it("Trim", function() {
var string = " xxx " + eol + " ";
var options = { tabWidth: 4 };
var lines = fromString(string);
fromString(string);
function test(string) {
function test(string: string) {
var lines = fromString(string, options);
check(lines.trimLeft(), fromString(string.replace(/^\s+/, ""), options));
check(lines.trimRight(), fromString(string.replace(/\s+$/, ""), options));
@ -351,14 +347,14 @@ describe("lines", function() {
});
it("CountSpaces", function() {
var count = linesModule.countSpaces;
var count = countSpaces;
assert.strictEqual(count(""), 0);
assert.strictEqual(count(" "), 1);
assert.strictEqual(count(" "), 2);
assert.strictEqual(count(" "), 3);
function check(s, tabWidth, result) {
function check(s: string, tabWidth: number, result: number) {
assert.strictEqual(count(s, tabWidth), result);
}
@ -407,7 +403,7 @@ describe("lines", function() {
"}"
].join(eol);
function checkUnchanged(lines, code) {
function checkUnchanged(lines: LinesType, code: string) {
check(lines.toString(tabOpts), code);
check(lines.toString(noTabOpts), code);
check(lines.indent(3).indent(-5).indent(2).toString(tabOpts), code);
@ -500,7 +496,12 @@ describe("lines", function() {
});
it("GuessTabWidth", function GuessTabWidthTest(done) {
var lines = fromString(String(GuessTabWidthTest));
var lines;
lines = fromString([
"function identity(x) {",
" return x;",
"}"
].join(eol));
assert.strictEqual(lines.guessTabWidth(), 4);
lines = fromString([

View file

@ -1,15 +1,14 @@
var assert = require("assert");
var sourceMap = require("source-map");
var recast = require("..");
var types = require("../lib/types");
import assert from "assert";
import sourceMap from "source-map";
import recast from "../main";
import types from "../lib/types";
var n = types.namedTypes;
var b = types.builders;
var NodePath = types.NodePath;
var fromString = require("../lib/lines").fromString;
var parse = require("../lib/parser").parse;
var Printer = require("../lib/printer").Printer;
var Mapping = require("../lib/mapping");
var eol = require("os").EOL;
import { fromString } from "../lib/lines";
import { parse } from "../lib/parser";
import { Printer } from "../lib/printer";
import { EOL as eol } from "os";
describe("source maps", function() {
it("should generate correct mappings", function() {
@ -19,7 +18,7 @@ describe("source maps", function() {
"}"
].join(eol);
var lines = fromString(code);
fromString(code);
var ast = parse(code, {
sourceFileName: "source.js"
});
@ -55,7 +54,7 @@ describe("source maps", function() {
var smc = new sourceMap.SourceMapConsumer(printed.map);
function check(origLine, origCol, genLine, genCol, lastColumn) {
function check(origLine: any, origCol: any, genLine: any, genCol: any, lastColumn: any) {
assert.deepEqual(smc.originalPositionFor({
line: genLine,
column: genCol
@ -85,7 +84,7 @@ describe("source maps", function() {
});
it("should compose with inputSourceMap", function() {
function addUseStrict(ast) {
function addUseStrict(ast: any) {
return recast.visit(ast, {
visitFunction: function(path) {
path.get("body", "body").unshift(
@ -96,7 +95,7 @@ describe("source maps", function() {
});
}
function stripConsole(ast) {
function stripConsole(ast: any) {
return recast.visit(ast, {
visitCallExpression: function(path) {
var node = path.value;
@ -107,6 +106,7 @@ describe("source maps", function() {
path.parent.replace();
return false;
}
return;
}
});
}

View file

@ -1,22 +1,23 @@
var assert = require("assert");
var esprima = require("esprima");
var parse = require("../lib/parser").parse;
var Printer = require("../lib/printer").Printer;
var NodePath = require("ast-types").NodePath;
var types = require("../lib/types");
import assert from "assert";
import * as esprima from "esprima";
import { parse } from "../lib/parser";
import { Printer } from "../lib/printer";
import astTypes from "ast-types";
var NodePath = astTypes.NodePath;
import types from "../lib/types";
var n = types.namedTypes;
var b = types.builders;
var printer = new Printer;
var eol = require("os").EOL;
import { EOL as eol } from "os";
function parseExpression(expr) {
var ast = esprima.parse(expr);
function parseExpression(expr: any) {
var ast: any = esprima.parse(expr);
n.Program.assert(ast);
ast = ast.body[0];
return n.ExpressionStatement.check(ast) ? ast.expression : ast;
}
function check(expr) {
function check(expr: any) {
const ast = parse(expr);
const reprinted = printer.print(ast).code;
assert.strictEqual(reprinted, expr);

View file

@ -1,15 +1,12 @@
var assert = require("assert");
var parse = require("../lib/parser").parse;
var getReprinter = require("../lib/patcher").getReprinter;
var Printer = require("../lib/printer").Printer;
var printComments = require("../lib/comments").printComments;
var linesModule = require("../lib/lines");
var fromString = linesModule.fromString;
var concat = linesModule.concat;
var types = require("../lib/types");
import assert from "assert";
import { parse } from "../lib/parser";
import { getReprinter } from "../lib/patcher";
import { Printer } from "../lib/printer";
import { fromString } from "../lib/lines";
import types from "../lib/types";
var namedTypes = types.namedTypes;
var FastPath = require("../lib/fast-path");
var eol = require("os").EOL;
import FastPath from "../lib/fast-path";
import { EOL as eol } from "os";
var nodeMajorVersion = parseInt(process.versions.node, 10);
// Esprima seems unable to handle unnamed top-level functions, so declare
@ -27,7 +24,7 @@ describe("parser", function() {
var types = require("../lib/types");
var b = types.builders;
var parser = {
parse: function(code) {
parse: function() {
var program = b.program([
b.expressionStatement(b.identifier("surprise"))
]);
@ -36,7 +33,7 @@ describe("parser", function() {
}
};
function check(options) {
function check(options?: any) {
var ast = parse("ignored", options);
var printer = new Printer;
@ -52,7 +49,7 @@ describe("parser", function() {
});
});
function runTestsForParser(parserId) {
function runTestsForParser(parserId: string) {
const parserName = parserId.split("/").pop();
if (nodeMajorVersion < 6 &&
@ -63,12 +60,16 @@ function runTestsForParser(parserId) {
return;
}
if (!parserName) {
return;
}
const parser = require(parserId);
it("[" + parserName + "] empty source", function () {
var printer = new Printer;
function check(code) {
function check(code: string) {
var ast = parse(code, { parser });
assert.strictEqual(printer.print(ast).code, code);
}
@ -82,7 +83,7 @@ function runTestsForParser(parserId) {
check(" ");
});
const lineCommentTypes = {
const lineCommentTypes: { [name: string]: string } = {
acorn: "Line",
babel: "CommentLine",
esprima: "Line",
@ -162,7 +163,9 @@ function runTestsForParser(parserId) {
types.visit(ast, {
visitFunctionDeclaration: function(path) {
path.node.body.body.reverse();
if (namedTypes.BlockStatement.check(path.node.body)) {
path.node.body.body.reverse();
}
this.traverse(path);
}
});
@ -176,11 +179,11 @@ function runTestsForParser(parserId) {
});
it("[" + parserName + "] TabHandling", function() {
function check(code, tabWidth) {
function check(code: string, tabWidth: number) {
var lines = fromString(code, { tabWidth: tabWidth });
assert.strictEqual(lines.length, 1);
types.visit(parse(code, {
types.visit<{ check(s: any, loc: any): any }>(parse(code, {
tabWidth: tabWidth,
parser,
}), {
@ -216,7 +219,7 @@ function runTestsForParser(parserId) {
it("[" + parserName + "] Only comment followed by space", function () {
const printer = new Printer;
function check(code) {
function check(code: string) {
const ast = parse(code, { parser });
assert.strictEqual(
printer.print(ast).code,

View file

@ -1,15 +1,13 @@
var assert = require("assert");
var recast = require("..");
var types = require("../lib/types");
import assert from "assert";
import recast from "../main";
import types from "../lib/types";
var n = types.namedTypes;
var b = types.builders;
var patcherModule = require("../lib/patcher");
var getReprinter = patcherModule.getReprinter;
var Patcher = patcherModule.Patcher;
var fromString = require("../lib/lines").fromString;
var parse = require("../lib/parser").parse;
var FastPath = require("../lib/fast-path");
var eol = require("os").EOL;
import { getReprinter, Patcher } from "../lib/patcher";
import { fromString } from "../lib/lines";
import { parse } from "../lib/parser";
import FastPath from "../lib/fast-path";
import { EOL as eol } from "os";
var code = [
"// file comment",
@ -20,7 +18,7 @@ var code = [
"});"
];
function loc(sl, sc, el, ec) {
function loc(sl: number, sc: number, el: number, ec: number) {
return {
start: { line: sl, column: sc },
end: { line: el, column: ec }
@ -77,14 +75,14 @@ describe("patcher", function() {
].join(eol);
it("GetIndent", function() {
function check(indent) {
function check(indent: number) {
var lines = fromString(trickyCode).indent(indent);
var file = parse(lines.toString());
var reprinter = FastPath.from(file).call(function(bodyPath) {
var reprinter = FastPath.from(file).call(function(bodyPath: any) {
return getReprinter(bodyPath);
}, "program", "body", 0, "body");
var reprintedLines = reprinter(function(path) {
var reprintedLines = reprinter(function() {
assert.ok(false, "should not have called print function");
});

View file

@ -1,6 +1,6 @@
var path = require("path");
var fs = require("fs");
var recast = require("..");
import path from "path";
import fs from "fs";
import recast from "../main";
var source = fs.readFileSync(
path.join(__dirname, "data", "backbone.js"),
@ -11,7 +11,7 @@ var start = +new Date;
var ast = recast.parse(source);
var types = Object.create(null);
var parseTime = new Date - start;
var parseTime = +new Date - start;
console.log("parse", parseTime, "ms");
recast.visit(ast, {
@ -21,12 +21,12 @@ recast.visit(ast, {
}
});
var visitTime = new Date - start - parseTime;
var visitTime = +new Date - start - parseTime;
console.log("visit", visitTime, "ms");
recast.prettyPrint(ast).code;
var printTime = new Date - start - visitTime - parseTime;
var printTime = +new Date - start - visitTime - parseTime;
console.log("print", printTime, "ms");
console.log("total", new Date - start, "ms");
console.log("total", +new Date - start, "ms");

View file

@ -1,11 +1,13 @@
var assert = require("assert");
var recast = require("..");
var parse = require("../lib/parser").parse;
var Printer = require("../lib/printer").Printer;
var n = require("../lib/types").namedTypes;
var b = require("../lib/types").builders;
var fromString = require("../lib/lines").fromString;
var eol = require("os").EOL;
import assert from "assert";
import recast from "../main";
import { parse } from "../lib/parser";
import { Printer } from "../lib/printer";
import types from "../lib/types";
var n = types.namedTypes;
var b = types.builders;
import { fromString } from "../lib/lines";
import { EOL as eol } from "os";
var linesModule = require("../lib/lines");
var nodeMajorVersion = parseInt(process.versions.node, 10);
describe("printer", function() {
@ -333,7 +335,7 @@ describe("printer", function() {
"var x, y, z;"
);
var z = varDecl.declarations.pop();
var z: any = varDecl.declarations.pop();
varDecl.declarations.pop();
varDecl.declarations.push(z);
@ -481,11 +483,9 @@ describe("printer", function() {
b.blockStatement([]),
false,
false,
false,
undefined
);
funExpr.defaults = [undefined, b.literal(1)];
funExpr.defaults = [null, b.literal(1)];
funExpr.rest = b.identifier('d');
assert.strictEqual(
@ -496,12 +496,9 @@ describe("printer", function() {
var arrowFunExpr = b.arrowFunctionExpression(
[b.identifier('b'), b.identifier('c')],
b.blockStatement([]),
false,
false,
false,
undefined);
false);
arrowFunExpr.defaults = [undefined, b.literal(1)];
arrowFunExpr.defaults = [null, b.literal(1)];
arrowFunExpr.rest = b.identifier('d');
assert.strictEqual(
@ -626,8 +623,6 @@ describe("printer", function() {
b.blockStatement(ast.program.body)
);
var linesModule = require("../lib/lines");
assert.strictEqual(
printer.print(funDecl).code,
linesModule.concat([
@ -1362,7 +1357,7 @@ describe("printer", function() {
var lines = fromString(code);
var ast = parse(code, {
esprima: {
parse: function(source, options) {
parse: function(source: string, options?: any) {
var program = require("esprima").parse(source, options);
n.Program.assert(program);
// Expand ast.program.loc to include any
@ -1454,11 +1449,11 @@ describe("printer", function() {
recast.visit(ast, {
visitTaggedTemplateExpression: function (path) {
function replaceIdWithNodeId(path) {
function replaceIdWithNodeId(path: any) {
path.replace(path.value.replace(/\bid\b/g, "nodeID"));
}
path.get("quasi", "quasis").each(function (quasiPath) {
path.get("quasi", "quasis").each(function (quasiPath: any) {
replaceIdWithNodeId(quasiPath.get("value", "cooked"));
replaceIdWithNodeId(quasiPath.get("value", "raw"));
});
@ -1527,7 +1522,6 @@ describe("printer", function() {
b.identifier('key'),
b.stringTypeAnnotation(),
b.stringTypeAnnotation(),
false
)
])
);
@ -1592,7 +1586,7 @@ describe("printer", function() {
var babelParser = require("@babel/parser");
var parseOptions = {
parser: {
parse: function (source) {
parse: function (source: string) {
return babelParser.parse(source, {
sourceType: 'module',
plugins: ['flow'],
@ -1663,7 +1657,7 @@ describe("printer", function() {
});
it("prints no extra semicolons in for-loop heads (#377)", function () {
function check(head, parser) {
function check(head: any, parser: any) {
var source = "for (" + head + ") console.log(i);";
var ast = recast.parse(source, { parser: parser });
var loop = ast.program.body[0];
@ -1686,7 +1680,7 @@ describe("printer", function() {
assert.strictEqual(newHead.split(";").length, 3);
}
function checkWith(parser) {
function checkWith(parser: any) {
check("let i = 0; i < 1; i++", parser);
check("let i = 0 ; i < 1; i++", parser);
check("let i = 0; ; i++", parser);

View file

@ -27,4 +27,4 @@ fi
cd .. # back to the recast/test/ directory
exec mocha --reporter spec --full-trace $@ run.js
exec mocha --require ts-node/register/transpile-only --reporter spec --full-trace $@ run.ts

View file

@ -1,16 +1,16 @@
require("./babel.js");
require("./comments.js");
require("./es6tests.js");
require("./identity.js");
require("./jsx.js");
require("./lines.js");
require("./mapping.js");
require("./parens.js");
require("./parser.js");
require("./patcher.js");
require("./perf.js");
require("./printer.js");
require("./syntax.js");
require("./type-syntax.js");
require("./typescript.js");
require("./visit.js");
import "./babel";
import "./comments";
import "./es6tests";
import "./identity";
import "./jsx";
import "./lines";
import "./mapping";
import "./parens";
import "./parser";
import "./patcher";
import "./perf";
import "./printer";
import "./syntax";
import "./type-syntax";
import "./typescript";
import "./visit";

View file

@ -1,23 +1,26 @@
var assert = require("assert");
var fs = require("fs");
var path = require("path");
var types = require("../lib/types");
var parse = require("../lib/parser").parse;
import assert from "assert";
import fs from "fs";
import path from "path";
import types from "../lib/types";
import { parse } from "../lib/parser";
var hasOwn = Object.prototype.hasOwnProperty;
describe("syntax", function() {
// Babel 7 no longer supports Node 4 or 5.
var nodeMajorVersion = parseInt(process.versions.node, 10);
(nodeMajorVersion >= 6 ? describe : xdescribe)
("syntax", function() {
// Make sure we handle all possible node types in Syntax, and no additional
// types that are not present in Syntax.
it("Completeness", function(done) {
var printer = path.join(__dirname, "../lib/printer.js");
var printer = path.join(__dirname, "../lib/printer.ts");
fs.readFile(printer, "utf-8", function(err, data) {
assert.ok(!err);
var ast = parse(data);
var ast = parse(data, { parser: require("../parsers/typescript") });
assert.ok(ast);
var typeNames = {};
var typeNames: { [name: string]: string } = {};
types.visit(ast, {
visitFunctionDeclaration(path) {
var decl = path.node;
@ -27,7 +30,7 @@ describe("syntax", function() {
visitSwitchCase(path) {
var test = path.node.test;
if (test &&
test.type === "Literal" &&
test.type === "StringLiteral" &&
typeof test.value === "string") {
var name = test.value;
typeNames[name] = name;

View file

@ -1,10 +1,8 @@
var assert = require("assert");
var parse = require("../lib/parser").parse;
var Printer = require("../lib/printer").Printer;
var types = require("../lib/types");
var n = types.namedTypes;
var b = types.builders;
var eol = require("os").EOL;
import assert from "assert";
import { parse } from "../lib/parser";
import { Printer } from "../lib/printer";
import types from "../lib/types";
import { EOL as eol } from "os";
describe("type syntax", function() {
var printer = new Printer({ tabWidth: 2, quote: 'single', flowObjectCommas: false });
@ -15,7 +13,7 @@ describe("type syntax", function() {
parser: require("flow-parser")
};
function check(source, parseOptions) {
function check(source: string, parseOptions?: any) {
parseOptions = parseOptions || esprimaParserParseOptions;
var ast1 = parse(source, parseOptions);
var code = printer.printGenerically(ast1).code;

View file

@ -1,24 +1,17 @@
"use strict";
import assert from "assert";
import path from "path";
import fs from "fs";
import recast from "../main";
import types from "../lib/types";
import {EOL as eol} from "os";
import * as parser from "../parsers/typescript";
const nodeMajorVersion = parseInt(process.versions.node, 10);
if (nodeMajorVersion < 6) {
// Babel 7 no longer supports Node 4 or 5.
return;
}
const assert = require("assert");
const path = require("path");
const fs = require("fs");
const recast = require("../main.js");
const parse = require("../lib/parser").parse;
const Printer = require("../lib/printer").Printer;
const types = require("../lib/types");
const eol = require("os").EOL;
const parser = require("../parsers/typescript");
describe("TypeScript", function() {
// Babel 7 no longer supports Node 4 or 5.
var nodeMajorVersion = parseInt(process.versions.node, 10);
(nodeMajorVersion >= 6 ? describe : xdescribe)
("TypeScript", function() {
it('basic printing', function() {
function check(lines) {
function check(lines: any) {
const code = lines.join(eol);
const ast = recast.parse(code, { parser });
const output = recast.prettyPrint(ast, { tabWidth: 2 }).code;
@ -313,11 +306,16 @@ testReprinting(
"Reprinting GraphQL-Tools TypeScript files"
);
function testReprinting(pattern, description) {
function testReprinting(pattern: any, description: any) {
// Babel no longer supports Node 4 or 5.
if (nodeMajorVersion < 6) {
return;
}
describe(description, function () {
require("glob").sync(pattern, {
cwd: __dirname
}).forEach(file => it(file, function () {
}).forEach((file: any) => it(file, function () {
if (file.indexOf("/tsx/") >= 0 ||
file.endsWith("stitching/errors.ts") ||
file.endsWith("decorators/type-arguments-invalid/input.js")) {
@ -342,13 +340,13 @@ function testReprinting(pattern, description) {
});
}
function tryToParseFile(source, absPath) {
function tryToParseFile(source: any, absPath: any) {
try {
return recast.parse(source, { parser });
} catch (e1) {
try {
var options = JSON.parse(fs.readFileSync(
path.join(path.dirname(absPath), "options.json")));
path.join(path.dirname(absPath), "options.json")).toString());
} catch (e2) {
if (e2.code !== "ENOENT") {
console.error(e2);

View file

@ -1,10 +1,10 @@
var assert = require("assert");
var types = require("../lib/types");
import assert from "assert";
import types, { Visitor } from "../lib/types";
var namedTypes = types.namedTypes;
var builders = types.builders;
var parse = require("../lib/parser").parse;
var Printer = require("../lib/printer").Printer;
var eol = require("os").EOL;
import { parse } from "../lib/parser";
import { Printer } from "../lib/printer";
import { EOL as eol } from "os";
var lines = [
"// file comment",
@ -36,10 +36,10 @@ describe("types.visit", function() {
withThis.replace(thisExp, "self")
);
var propNames = [];
var methods = {
var propNames: any[] = [];
var methods: Visitor = {
visitProperty: function(path) {
var key = path.node.key;
var key: any = path.node.key;
propNames.push(key.value || key.name);
this.traverse(path);
}
@ -57,6 +57,7 @@ describe("types.visit", function() {
}
this.traverse(path);
return;
}
});
@ -99,7 +100,7 @@ describe("types.visit", function() {
var ast = parse(source);
var printer = new Printer;
var funExpr;
var funExpr: any;
types.visit(ast, {
visitFunctionExpression: function(path) {
assert.strictEqual(typeof funExpr, "undefined");