This commit is contained in:
Jake Bailey 2023-01-17 17:20:51 -08:00 коммит произвёл GitHub
Родитель 436833aba1
Коммит 22b362ceac
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
60 изменённых файлов: 1263 добавлений и 869 удалений

Просмотреть файл

@ -1163,7 +1163,7 @@ function convertToReusableCompilerOptionValue(option: CommandLineOption | undefi
if (option) {
Debug.assert(option.type !== "listOrElement");
if (option.type === "list") {
const values = value as readonly (string | number)[];
const values = value as readonly string[];
if (option.element.isFilePath && values.length) {
return values.map(relativeToBuildInfo);
}

Просмотреть файл

@ -2174,7 +2174,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
if (jsxFragmentPragma) {
const chosenPragma = isArray(jsxFragmentPragma) ? jsxFragmentPragma[0] : jsxFragmentPragma;
file.localJsxFragmentFactory = parseIsolatedEntityName(chosenPragma.arguments.factory, languageVersion);
visitNode(file.localJsxFragmentFactory, markAsSynthetic);
visitNode(file.localJsxFragmentFactory, markAsSynthetic, isEntityName);
if (file.localJsxFragmentFactory) {
return file.localJsxFragmentNamespace = getFirstIdentifier(file.localJsxFragmentFactory).escapedText;
}
@ -2220,14 +2220,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
if (jsxPragma) {
const chosenPragma = isArray(jsxPragma) ? jsxPragma[0] : jsxPragma;
file.localJsxFactory = parseIsolatedEntityName(chosenPragma.arguments.factory, languageVersion);
visitNode(file.localJsxFactory, markAsSynthetic);
visitNode(file.localJsxFactory, markAsSynthetic, isEntityName);
if (file.localJsxFactory) {
return file.localJsxNamespace = getFirstIdentifier(file.localJsxFactory).escapedText;
}
}
}
function markAsSynthetic(node: Node): VisitResult<Node> {
function markAsSynthetic<T extends Node>(node: T): VisitResult<T> {
setTextRangePosEnd(node, -1, -1);
return visitEachChild(node, markAsSynthetic, nullTransformationContext);
}
@ -4026,7 +4026,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return valueSymbol;
}
const result = createSymbol(valueSymbol.flags | typeSymbol.flags, valueSymbol.escapedName);
result.declarations = deduplicate(concatenate(valueSymbol.declarations, typeSymbol.declarations), equateValues);
Debug.assert(valueSymbol.declarations || typeSymbol.declarations);
result.declarations = deduplicate(concatenate(valueSymbol.declarations!, typeSymbol.declarations), equateValues);
result.parent = valueSymbol.parent || typeSymbol.parent;
if (valueSymbol.valueDeclaration) result.valueDeclaration = valueSymbol.valueDeclaration;
if (typeSymbol.members) result.members = new Map(typeSymbol.members);
@ -4980,7 +4981,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
function resolveExternalModuleSymbol(moduleSymbol: Symbol, dontResolveAlias?: boolean): Symbol;
function resolveExternalModuleSymbol(moduleSymbol: Symbol | undefined, dontResolveAlias?: boolean): Symbol | undefined;
function resolveExternalModuleSymbol(moduleSymbol: Symbol, dontResolveAlias?: boolean): Symbol | undefined {
function resolveExternalModuleSymbol(moduleSymbol: Symbol | undefined, dontResolveAlias?: boolean): Symbol | undefined {
if (moduleSymbol?.exports) {
const exportEquals = resolveSymbol(moduleSymbol.exports.get(InternalSymbolName.ExportEquals), dontResolveAlias);
const exported = getCommonJsExportEquals(getMergedSymbol(exportEquals), getMergedSymbol(moduleSymbol));
@ -6330,7 +6331,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
if (objectFlags & ObjectFlags.Reference) {
Debug.assert(!!(type.flags & TypeFlags.Object));
return (type as TypeReference).node ? visitAndTransformType(type, typeReferenceToTypeNode) : typeReferenceToTypeNode(type as TypeReference);
return (type as TypeReference).node ? visitAndTransformType(type as TypeReference, typeReferenceToTypeNode) : typeReferenceToTypeNode(type as TypeReference);
}
if (type.flags & TypeFlags.TypeParameter || objectFlags & ObjectFlags.ClassOrInterface) {
if (type.flags & TypeFlags.TypeParameter && contains(context.inferTypeParameters, type)) {
@ -6584,11 +6585,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
}
function visitAndTransformType<T extends TypeNode>(type: Type, transform: (type: Type) => T) {
function visitAndTransformType<T extends Type>(type: T, transform: (type: T) => TypeNode) {
const typeId = type.id;
const isConstructorObject = getObjectFlags(type) & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & SymbolFlags.Class;
const id = getObjectFlags(type) & ObjectFlags.Reference && (type as TypeReference).node ? "N" + getNodeId((type as TypeReference).node!) :
type.flags & TypeFlags.Conditional ? "N" + getNodeId((type as ConditionalType).root.node) :
const id = getObjectFlags(type) & ObjectFlags.Reference && (type as TypeReference & T).node ? "N" + getNodeId((type as TypeReference & T).node!) :
type.flags & TypeFlags.Conditional ? "N" + getNodeId((type as ConditionalType & T).root.node) :
type.symbol ? (isConstructorObject ? "+" : "") + getSymbolId(type.symbol) :
undefined;
// Since instantiations of the same anonymous type have the same symbol, tracking symbols instead
@ -6611,7 +6612,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
context.truncating = true;
}
context.approximateLength += cachedResult.addedLength;
return deepCloneOrReuseNode(cachedResult.node) as T;
return deepCloneOrReuseNode(cachedResult.node);
}
let depth: number | undefined;
@ -6635,20 +6636,24 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
return result;
function deepCloneOrReuseNode(node: Node): Node {
function deepCloneOrReuseNode<T extends Node>(node: T): T {
if (!nodeIsSynthesized(node) && getParseTreeNode(node) === node) {
return node;
}
return setTextRange(factory.cloneNode(visitEachChild(node, deepCloneOrReuseNode, nullTransformationContext, deepCloneOrReuseNodes)), node);
}
function deepCloneOrReuseNodes<T extends Node>(nodes: NodeArray<T>, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray<T>;
function deepCloneOrReuseNodes<T extends Node>(nodes: NodeArray<T> | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray<T> | undefined;
function deepCloneOrReuseNodes<T extends Node>(nodes: NodeArray<T> | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray<T> | undefined {
function deepCloneOrReuseNodes(
nodes: NodeArray<Node> | undefined,
visitor: Visitor,
test?: (node: Node) => boolean,
start?: number,
count?: number,
): NodeArray<Node> | undefined {
if (nodes && nodes.length === 0) {
// Ensure we explicitly make a copy of an empty array; visitNodes will not do this unless the array has elements,
// which can lead to us reusing the same empty NodeArray more than once within the same AST during type noding.
return setTextRange(factory.createNodeArray<T>(/*nodes*/ undefined, nodes.hasTrailingComma), nodes);
return setTextRange(factory.createNodeArray(/*nodes*/ undefined, nodes.hasTrailingComma), nodes);
}
return visitNodes(nodes, visitor, test, start, count);
}
@ -7956,13 +7961,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
let hadError = false;
const file = getSourceFileOfNode(existing);
const transformed = visitNode(existing, visitExistingNodeTreeSymbols);
const transformed = visitNode(existing, visitExistingNodeTreeSymbols, isTypeNode);
if (hadError) {
return undefined;
}
return transformed === existing ? setTextRange(factory.cloneNode(existing), existing) : transformed;
function visitExistingNodeTreeSymbols<T extends Node>(node: T): Node {
function visitExistingNodeTreeSymbols(node: Node): Node {
// We don't _actually_ support jsdoc namepath types, emit `any` instead
if (isJSDocAllType(node) || node.kind === SyntaxKind.JSDocNamepathType) {
return factory.createKeywordTypeNode(SyntaxKind.AnyKeyword);
@ -7971,16 +7976,16 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return factory.createKeywordTypeNode(SyntaxKind.UnknownKeyword);
}
if (isJSDocNullableType(node)) {
return factory.createUnionTypeNode([visitNode(node.type, visitExistingNodeTreeSymbols), factory.createLiteralTypeNode(factory.createNull())]);
return factory.createUnionTypeNode([visitNode(node.type, visitExistingNodeTreeSymbols, isTypeNode), factory.createLiteralTypeNode(factory.createNull())]);
}
if (isJSDocOptionalType(node)) {
return factory.createUnionTypeNode([visitNode(node.type, visitExistingNodeTreeSymbols), factory.createKeywordTypeNode(SyntaxKind.UndefinedKeyword)]);
return factory.createUnionTypeNode([visitNode(node.type, visitExistingNodeTreeSymbols, isTypeNode), factory.createKeywordTypeNode(SyntaxKind.UndefinedKeyword)]);
}
if (isJSDocNonNullableType(node)) {
return visitNode(node.type, visitExistingNodeTreeSymbols);
}
if (isJSDocVariadicType(node)) {
return factory.createArrayTypeNode(visitNode((node as JSDocVariadicType).type, visitExistingNodeTreeSymbols));
return factory.createArrayTypeNode(visitNode(node.type, visitExistingNodeTreeSymbols, isTypeNode));
}
if (isJSDocTypeLiteral(node)) {
return factory.createTypeLiteralNode(map(node.jsDocPropertyTags, t => {
@ -7992,7 +7997,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
/*modifiers*/ undefined,
name,
t.isBracketed || t.typeExpression && isJSDocOptionalType(t.typeExpression.type) ? factory.createToken(SyntaxKind.QuestionToken) : undefined,
overrideTypeNode || (t.typeExpression && visitNode(t.typeExpression.type, visitExistingNodeTreeSymbols)) || factory.createKeywordTypeNode(SyntaxKind.AnyKeyword)
overrideTypeNode || (t.typeExpression && visitNode(t.typeExpression.type, visitExistingNodeTreeSymbols, isTypeNode)) || factory.createKeywordTypeNode(SyntaxKind.AnyKeyword)
);
}));
}
@ -8007,9 +8012,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
/*dotdotdotToken*/ undefined,
"x",
/*questionToken*/ undefined,
visitNode(node.typeArguments![0], visitExistingNodeTreeSymbols)
visitNode(node.typeArguments![0], visitExistingNodeTreeSymbols, isTypeNode)
)],
visitNode(node.typeArguments![1], visitExistingNodeTreeSymbols)
visitNode(node.typeArguments![1], visitExistingNodeTreeSymbols, isTypeNode)
)]);
}
if (isJSDocFunctionType(node)) {
@ -8017,30 +8022,30 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
let newTypeNode: TypeNode | undefined;
return factory.createConstructorTypeNode(
/*modifiers*/ undefined,
visitNodes(node.typeParameters, visitExistingNodeTreeSymbols),
visitNodes(node.typeParameters, visitExistingNodeTreeSymbols, isTypeParameterDeclaration),
mapDefined(node.parameters, (p, i) => p.name && isIdentifier(p.name) && p.name.escapedText === "new" ? (newTypeNode = p.type, undefined) : factory.createParameterDeclaration(
/*modifiers*/ undefined,
getEffectiveDotDotDotForParameter(p),
getNameForJSDocFunctionParameter(p, i),
p.questionToken,
visitNode(p.type, visitExistingNodeTreeSymbols),
visitNode(p.type, visitExistingNodeTreeSymbols, isTypeNode),
/*initializer*/ undefined
)),
visitNode(newTypeNode || node.type, visitExistingNodeTreeSymbols) || factory.createKeywordTypeNode(SyntaxKind.AnyKeyword)
visitNode(newTypeNode || node.type, visitExistingNodeTreeSymbols, isTypeNode) || factory.createKeywordTypeNode(SyntaxKind.AnyKeyword)
);
}
else {
return factory.createFunctionTypeNode(
visitNodes(node.typeParameters, visitExistingNodeTreeSymbols),
visitNodes(node.typeParameters, visitExistingNodeTreeSymbols, isTypeParameterDeclaration),
map(node.parameters, (p, i) => factory.createParameterDeclaration(
/*modifiers*/ undefined,
getEffectiveDotDotDotForParameter(p),
getNameForJSDocFunctionParameter(p, i),
p.questionToken,
visitNode(p.type, visitExistingNodeTreeSymbols),
visitNode(p.type, visitExistingNodeTreeSymbols, isTypeNode),
/*initializer*/ undefined
)),
visitNode(node.type, visitExistingNodeTreeSymbols) || factory.createKeywordTypeNode(SyntaxKind.AnyKeyword)
visitNode(node.type, visitExistingNodeTreeSymbols, isTypeNode) || factory.createKeywordTypeNode(SyntaxKind.AnyKeyword)
);
}
}
@ -8797,7 +8802,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
/*isTypeOnly*/ false,
factory.createNamedExports([factory.createExportSpecifier(/*isTypeOnly*/ false, d.expression, factory.createIdentifier(InternalSymbolName.Default))])
) : d);
const exportModifierStripped = every(defaultReplaced, d => hasSyntacticModifier(d, ModifierFlags.Export)) ? map(defaultReplaced, removeExportModifier) : defaultReplaced;
const exportModifierStripped = every(defaultReplaced, d => hasSyntacticModifier(d, ModifierFlags.Export)) ? map(defaultReplaced as Extract<HasModifiers, Statement>[], removeExportModifier) : defaultReplaced;
fakespace = factory.updateModuleDeclaration(
fakespace,
fakespace.modifiers,
@ -9015,7 +9020,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
case SyntaxKind.ImportEqualsDeclaration:
// This _specifically_ only exists to handle json declarations - where we make aliases, but since
// we emit no declarations for the json document, must not refer to it in the declarations
if (target.escapedName === InternalSymbolName.ExportEquals && some(target.declarations, isJsonSourceFile)) {
if (target.escapedName === InternalSymbolName.ExportEquals && some(target.declarations, d => isSourceFile(d) && isJsonSourceFile(d))) {
serializeMaybeAliasAssignment(symbol);
break;
}
@ -20155,7 +20160,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return true;
}
function isRelatedToWorker(source: Type, target: Type, reportErrors: boolean) {
function isRelatedToWorker(source: Type, target: Type, reportErrors?: boolean) {
return isRelatedTo(source, target, RecursionFlags.Both, reportErrors);
}
@ -22658,7 +22663,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
function getCombinedTypeFlags(types: Type[]): TypeFlags {
return reduceLeft(types, (flags, t) => flags | (t.flags & TypeFlags.Union ? getCombinedTypeFlags((t as UnionType).types) : t.flags), 0);
return reduceLeft(types, (flags, t) => flags | (t.flags & TypeFlags.Union ? getCombinedTypeFlags((t as UnionType).types) : t.flags), 0 as TypeFlags);
}
function getCommonSupertype(types: Type[]): Type {
@ -24014,7 +24019,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
inferWithPriority(getSubstitutionIntersection(source as SubstitutionType), target, InferencePriority.SubstituteSource); // Make substitute inference at a lower priority
}
else if (target.flags & TypeFlags.Conditional) {
invokeOnce(source, target, inferToConditionalType);
invokeOnce(source, (target as ConditionalType), inferToConditionalType);
}
else if (target.flags & TypeFlags.UnionOrIntersection) {
inferToMultipleTypes(source, (target as UnionOrIntersectionType).types, target.flags);
@ -24076,7 +24081,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
priority = savePriority;
}
function invokeOnce(source: Type, target: Type, action: (source: Type, target: Type) => void) {
function invokeOnce<Source extends Type, Target extends Type>(source: Source, target: Target, action: (source: Source, target: Target) => void) {
const key = source.id + "," + target.id;
const status = visited && visited.get(key);
if (status !== undefined) {
@ -29108,9 +29113,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return getStrictOptionValue(compilerOptions, "noImplicitAny")
? reduceLeft(
signatures,
(left, right) =>
(left: Signature | undefined, right) =>
left === right || !left ? left
: compareTypeParametersIdentical(left.typeParameters, right.typeParameters) ? combineSignaturesOfIntersectionMembers(left, right)
: compareTypeParametersIdentical(left.typeParameters, right!.typeParameters) ? combineSignaturesOfIntersectionMembers(left, right!)
: undefined)
: undefined;
}

Просмотреть файл

@ -2880,7 +2880,7 @@ export function convertToOptionsWithAbsolutePaths(options: CompilerOptions, toAb
function convertToOptionValueWithAbsolutePaths(option: CommandLineOption | undefined, value: CompilerOptionsValue, toAbsolutePath: (path: string) => string) {
if (option && !isNullOrUndefined(value)) {
if (option.type === "list") {
const values = value as readonly (string | number)[];
const values = value as readonly string[];
if (option.element.isFilePath && values.length) {
return values.map(toAbsolutePath);
}
@ -3846,7 +3846,8 @@ function validateSpecs(specs: readonly string[], errors: Push<Diagnostic>, disal
}
}
function specToDiagnostic(spec: string, disallowTrailingRecursion?: boolean): [DiagnosticMessage, string] | undefined {
function specToDiagnostic(spec: CompilerOptionsValue, disallowTrailingRecursion?: boolean): [DiagnosticMessage, string] | undefined {
Debug.assert(typeof spec === "string");
if (disallowTrailingRecursion && invalidTrailingRecursionPattern.test(spec)) {
return [Diagnostics.File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, spec];
}

Просмотреть файл

@ -142,6 +142,11 @@ export function intersperse<T>(input: T[], element: T): T[] {
*
* @internal
*/
export function every<T, U extends T>(array: readonly T[], callback: (element: T, index: number) => element is U): array is readonly U[];
/** @internal */
export function every<T, U extends T>(array: readonly T[] | undefined, callback: (element: T, index: number) => element is U): array is readonly U[] | undefined;
/** @internal */
export function every<T>(array: readonly T[] | undefined, callback: (element: T, index: number) => boolean): boolean;
export function every<T>(array: readonly T[] | undefined, callback: (element: T, index: number) => boolean): boolean {
if (array) {
for (let i = 0; i < array.length; i++) {
@ -478,7 +483,7 @@ export function sameFlatMap<T>(array: T[], mapfn: (x: T, i: number) => T | reado
/** @internal */
export function sameFlatMap<T>(array: readonly T[], mapfn: (x: T, i: number) => T | readonly T[]): readonly T[];
/** @internal */
export function sameFlatMap<T>(array: T[], mapfn: (x: T, i: number) => T | T[]): T[] {
export function sameFlatMap<T>(array: readonly T[], mapfn: (x: T, i: number) => T | readonly T[]): readonly T[] {
let result: T[] | undefined;
if (array) {
for (let i = 0; i < array.length; i++) {
@ -703,11 +708,19 @@ export function concatenate<T>(array1: T[], array2: T[]): T[];
/** @internal */
export function concatenate<T>(array1: readonly T[], array2: readonly T[]): readonly T[];
/** @internal */
export function concatenate<T>(array1: T[] | undefined, array2: T[] | undefined): T[];
export function concatenate<T>(array1: T[], array2: T[] | undefined): T[]; // eslint-disable-line @typescript-eslint/unified-signatures
/** @internal */
export function concatenate<T>(array1: readonly T[] | undefined, array2: readonly T[] | undefined): readonly T[];
export function concatenate<T>(array1: T[] | undefined, array2: T[]): T[]; // eslint-disable-line @typescript-eslint/unified-signatures
/** @internal */
export function concatenate<T>(array1: T[], array2: T[]): T[] {
export function concatenate<T>(array1: readonly T[], array2: readonly T[] | undefined): readonly T[]; // eslint-disable-line @typescript-eslint/unified-signatures
/** @internal */
export function concatenate<T>(array1: readonly T[] | undefined, array2: readonly T[]): readonly T[]; // eslint-disable-line @typescript-eslint/unified-signatures
/** @internal */
export function concatenate<T>(array1: T[] | undefined, array2: T[] | undefined): T[] | undefined;
/** @internal */
export function concatenate<T>(array1: readonly T[] | undefined, array2: readonly T[] | undefined): readonly T[] | undefined;
/** @internal */
export function concatenate<T>(array1: readonly T[] | undefined, array2: readonly T[] | undefined): readonly T[] | undefined {
if (!some(array2)) return array1;
if (!some(array1)) return array2;
return [...array1, ...array2];
@ -856,7 +869,7 @@ export function detectSortCaseSensitivity(array: readonly string[], useEslintOrd
/** @internal */
export function detectSortCaseSensitivity<T>(array: readonly T[], useEslintOrdering: boolean, getString: (element: T) => string): SortKind;
/** @internal */
export function detectSortCaseSensitivity<T>(array: readonly T[], useEslintOrdering: boolean, getString?: (element: T) => string): SortKind {
export function detectSortCaseSensitivity<T>(array: readonly T[], useEslintOrdering?: boolean, getString?: (element: T) => string): SortKind {
let kind = SortKind.Both;
if (array.length < 2) return kind;
const caseSensitiveComparer = getString
@ -915,7 +928,7 @@ export function compact<T>(array: T[]): T[]; // eslint-disable-line @typescript-
/** @internal */
export function compact<T>(array: readonly T[]): readonly T[]; // eslint-disable-line @typescript-eslint/unified-signatures
/** @internal */
export function compact<T>(array: T[]): T[] {
export function compact<T>(array: readonly T[]): readonly T[] {
let result: T[] | undefined;
if (array) {
for (let i = 0; i < array.length; i++) {
@ -998,11 +1011,12 @@ export function append<T>(to: T[] | undefined, value: T | undefined): T[] | unde
/** @internal */
export function append<T>(to: Push<T>, value: T | undefined): void;
/** @internal */
export function append<T>(to: T[], value: T | undefined): T[] | undefined {
if (value === undefined) return to;
export function append<T>(to: Push<T> | T[] | undefined, value: T | undefined): T[] | undefined {
// If to is Push<T>, return value is void, so safe to cast to T[].
if (value === undefined) return to as T[];
if (to === undefined) return [value];
to.push(value);
return to;
return to as T[];
}
/**
@ -1315,7 +1329,7 @@ export function reduceLeft<T, U>(array: readonly T[] | undefined, f: (memo: U, v
/** @internal */
export function reduceLeft<T>(array: readonly T[], f: (memo: T, value: T, i: number) => T): T | undefined;
/** @internal */
export function reduceLeft<T>(array: T[], f: (memo: T, value: T, i: number) => T, initial?: T, start?: number, count?: number): T | undefined {
export function reduceLeft<T>(array: readonly T[] | undefined, f: (memo: T, value: T, i: number) => T, initial?: T, start?: number, count?: number): T | undefined {
if (array && array.length > 0) {
const size = array.length;
if (size > 0) {
@ -1867,11 +1881,7 @@ export function isNumber(x: unknown): x is number {
}
/** @internal */
export function tryCast<TOut extends TIn, TIn = any>(value: TIn | undefined, test: (value: TIn) => value is TOut): TOut | undefined;
/** @internal */
export function tryCast<T>(value: T, test: (value: T) => boolean): T | undefined;
/** @internal */
export function tryCast<T>(value: T, test: (value: T) => boolean): T | undefined {
export function tryCast<TOut extends TIn, TIn = any>(value: TIn | undefined, test: (value: TIn) => value is TOut): TOut | undefined {
return value !== undefined && test(value) ? value : undefined;
}

Просмотреть файл

@ -275,13 +275,13 @@ export namespace Debug {
export function assertEachNode<T extends Node, U extends T>(nodes: readonly T[], test: (node: T) => node is U, message?: string, stackCrawlMark?: AnyFunction): asserts nodes is readonly U[];
export function assertEachNode<T extends Node, U extends T>(nodes: NodeArray<T> | undefined, test: (node: T) => node is U, message?: string, stackCrawlMark?: AnyFunction): asserts nodes is NodeArray<U> | undefined;
export function assertEachNode<T extends Node, U extends T>(nodes: readonly T[] | undefined, test: (node: T) => node is U, message?: string, stackCrawlMark?: AnyFunction): asserts nodes is readonly U[] | undefined;
export function assertEachNode(nodes: readonly Node[], test: (node: Node) => boolean, message?: string, stackCrawlMark?: AnyFunction): void;
export function assertEachNode(nodes: readonly Node[] | undefined, test: (node: Node) => boolean, message?: string, stackCrawlMark?: AnyFunction) {
export function assertEachNode(nodes: readonly Node[], test: ((node: Node) => boolean) | undefined, message?: string, stackCrawlMark?: AnyFunction): void;
export function assertEachNode(nodes: readonly Node[] | undefined, test: ((node: Node) => boolean) | undefined, message?: string, stackCrawlMark?: AnyFunction) {
if (shouldAssertFunction(AssertionLevel.Normal, "assertEachNode")) {
assert(
test === undefined || every(nodes, test),
message || "Unexpected node.",
() => `Node array did not pass test '${getFunctionName(test)}'.`,
() => `Node array did not pass test '${getFunctionName(test!)}'.`,
stackCrawlMark || assertEachNode);
}
}

Просмотреть файл

@ -279,6 +279,7 @@ import {
JSDocVariadicType,
JsxAttribute,
JsxAttributes,
JsxAttributeValue,
JsxClosingElement,
JsxClosingFragment,
JsxElement,
@ -1402,10 +1403,10 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
let hasWrittenComment = false;
let commentsDisabled = !!printerOptions.removeComments;
let lastSubstitution: Node | undefined;
let currentParenthesizerRule: ((node: Node) => Node) | undefined;
let currentParenthesizerRule: ParenthesizerRule<any> | undefined;
const { enter: enterComment, exit: exitComment } = performance.createTimerIf(extendedDiagnostics, "commentTime", "beforeComment", "afterComment");
const parenthesizer = factory.parenthesizer;
const typeArgumentParenthesizerRuleSelector: OrdinalParentheizerRuleSelector<Node> = {
const typeArgumentParenthesizerRuleSelector: OrdinalParentheizerRuleSelector<TypeNode> = {
select: index => index === 0 ? parenthesizer.parenthesizeLeadingTypeArgument : undefined
};
const emitBinaryExpression = createEmitBinaryExpression();
@ -1676,9 +1677,9 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
return currentLineMap || (currentLineMap = getLineStarts(Debug.checkDefined(currentSourceFile)));
}
function emit(node: Node, parenthesizerRule?: (node: Node) => Node): void;
function emit(node: Node | undefined, parenthesizerRule?: (node: Node) => Node): void;
function emit(node: Node | undefined, parenthesizerRule?: (node: Node) => Node) {
function emit<T extends Node>(node: T, parenthesizerRule?: (node: T) => T): void;
function emit<T extends Node>(node: T | undefined, parenthesizerRule?: (node: T) => T): void;
function emit<T extends Node>(node: T | undefined, parenthesizerRule?: (node: T) => T) {
if (node === undefined) return;
const prevSourceFileTextKind = recordBundleFileInternalSectionStart(node);
pipelineEmit(EmitHint.Unspecified, node, parenthesizerRule);
@ -1692,14 +1693,14 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
pipelineEmit(EmitHint.IdentifierName, node, /*parenthesizerRule*/ undefined);
}
function emitExpression(node: Expression, parenthesizerRule?: (node: Expression) => Expression): void;
function emitExpression(node: Expression | undefined, parenthesizerRule?: (node: Expression) => Expression): void;
function emitExpression(node: Expression | undefined, parenthesizerRule?: (node: Expression) => Expression) {
function emitExpression<T extends Expression>(node: T, parenthesizerRule?: (node: T) => T): void;
function emitExpression<T extends Expression>(node: T | undefined, parenthesizerRule?: (node: T) => T): void;
function emitExpression<T extends Expression>(node: T | undefined, parenthesizerRule?: (node: T) => T) {
if (node === undefined) return;
pipelineEmit(EmitHint.Expression, node, parenthesizerRule);
}
function emitJsxAttributeValue(node: StringLiteral | JsxExpression): void {
function emitJsxAttributeValue(node: JsxAttributeValue): void {
pipelineEmit(isStringLiteral(node) ? EmitHint.JsxAttributeValue : EmitHint.Unspecified, node);
}
@ -1713,7 +1714,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
preserveSourceNewlines = savedPreserveSourceNewlines;
}
function pipelineEmit(emitHint: EmitHint, node: Node, parenthesizerRule?: (node: Node) => Node) {
function pipelineEmit<T extends Node>(emitHint: EmitHint, node: T, parenthesizerRule?: (node: T) => T) {
currentParenthesizerRule = parenthesizerRule;
const pipelinePhase = getPipelinePhase(PipelinePhase.Notification, emitHint, node);
pipelinePhase(emitHint, node);
@ -3668,7 +3669,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
emitSignatureAndBody(node, emitSignatureHead);
}
function emitSignatureAndBody(node: FunctionLikeDeclaration, emitSignatureHead: (node: SignatureDeclaration) => void) {
function emitSignatureAndBody<T extends FunctionLikeDeclaration>(node: T, emitSignatureHead: (node: T) => void) {
const body = node.body;
if (body) {
if (isBlock(body)) {
@ -3702,7 +3703,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
}
function emitSignatureHead(node: FunctionDeclaration | FunctionExpression | MethodDeclaration | AccessorDeclaration | ConstructorDeclaration) {
function emitSignatureHead(node: SignatureDeclaration) {
emitTypeParameters(node, node.typeParameters);
emitParameters(node, node.parameters);
emitTypeAnnotation(node.type);
@ -4906,7 +4907,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
}
}
function emitList(parentNode: Node | undefined, children: NodeArray<Node> | undefined, format: ListFormat, parenthesizerRule?: ParenthesizerRuleOrSelector<Node>, start?: number, count?: number) {
function emitList<Child extends Node, Children extends NodeArray<Child>>(parentNode: Node | undefined, children: Children | undefined, format: ListFormat, parenthesizerRule?: ParenthesizerRuleOrSelector<Child>, start?: number, count?: number) {
emitNodeList(
emit,
parentNode,
@ -4917,11 +4918,11 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
count);
}
function emitExpressionList(parentNode: Node | undefined, children: NodeArray<Node> | undefined, format: ListFormat, parenthesizerRule?: ParenthesizerRuleOrSelector<Expression>, start?: number, count?: number) {
function emitExpressionList<Child extends Node, Children extends NodeArray<Child>>(parentNode: Node | undefined, children: Children | undefined, format: ListFormat, parenthesizerRule?: ParenthesizerRuleOrSelector<Child>, start?: number, count?: number) {
emitNodeList(emitExpression, parentNode, children, format, parenthesizerRule, start, count);
}
function emitNodeList(emit: (node: Node, parenthesizerRule?: ((node: Node) => Node) | undefined) => void, parentNode: Node | undefined, children: NodeArray<Node> | undefined, format: ListFormat, parenthesizerRule: ParenthesizerRuleOrSelector<Node> | undefined, start = 0, count = children ? children.length - start : 0) {
function emitNodeList<Child extends Node, Children extends NodeArray<Child>>(emit: EmitFunction, parentNode: Node | undefined, children: Children | undefined, format: ListFormat, parenthesizerRule: ParenthesizerRuleOrSelector<Child> | undefined, start = 0, count = children ? children.length - start : 0) {
const isUndefined = children === undefined;
if (isUndefined && format & ListFormat.OptionalIfUndefined) {
return;
@ -4971,7 +4972,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
*
* NOTE: You probably don't want to call this directly and should be using `emitList` or `emitExpressionList` instead.
*/
function emitNodeListItems(emit: (node: Node, parenthesizerRule?: ((node: Node) => Node) | undefined) => void, parentNode: Node | undefined, children: readonly Node[], format: ListFormat, parenthesizerRule: ParenthesizerRuleOrSelector<Node> | undefined, start: number, count: number, hasTrailingComma: boolean, childrenTextRange: TextRange | undefined) {
function emitNodeListItems<Child extends Node>(emit: EmitFunction, parentNode: Node | undefined, children: readonly Child[], format: ListFormat, parenthesizerRule: ParenthesizerRuleOrSelector<Child> | undefined, start: number, count: number, hasTrailingComma: boolean, childrenTextRange: TextRange | undefined) {
// Write the opening line terminator or leading whitespace.
const mayEmitInterveningComments = (format & ListFormat.NoInterveningComments) === 0;
let shouldEmitInterveningComments = mayEmitInterveningComments;
@ -6118,7 +6119,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
: `//${comment.text}`;
}
function emitBodyWithDetachedComments(node: Node, detachedRange: TextRange, emitCallback: (node: Node) => void) {
function emitBodyWithDetachedComments<T extends Node>(node: T, detachedRange: TextRange, emitCallback: (node: T) => void) {
enterComment();
const { pos, end } = detachedRange;
const emitFlags = getEmitFlags(node);
@ -6351,7 +6352,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
}
}
function emitComment(text: string, lineMap: number[], writer: EmitTextWriter, commentPos: number, commentEnd: number, newLine: string) {
function emitComment(text: string, lineMap: readonly number[], writer: EmitTextWriter, commentPos: number, commentEnd: number, newLine: string) {
if (!currentSourceFile || !shouldWriteComment(currentSourceFile.text, commentPos)) return;
emitPos(commentPos);
writeCommentRange(text, lineMap, writer, commentPos, commentEnd, newLine);
@ -6577,20 +6578,23 @@ type ParenthesizerRule<T extends Node> = (node: T) => T;
type ParenthesizerRuleOrSelector<T extends Node> = OrdinalParentheizerRuleSelector<T> | ParenthesizerRule<T>;
function emitListItemNoParenthesizer(node: Node, emit: (node: Node, parenthesizerRule?: ((node: Node) => Node) | undefined) => void, _parenthesizerRule: ParenthesizerRuleOrSelector<Node> | undefined, _index: number) {
type EmitFunction = <T extends Node>(node: T, parenthesizerRule?: ParenthesizerRule<T>) => void;
type EmitListItemFunction<T extends Node> = (node: Node, emit: EmitFunction, parenthesizerRule: ParenthesizerRuleOrSelector<T> | undefined, index: number) => void;
function emitListItemNoParenthesizer(node: Node, emit: EmitFunction, _parenthesizerRule: ParenthesizerRuleOrSelector<Node> | undefined, _index: number) {
emit(node);
}
function emitListItemWithParenthesizerRuleSelector(node: Node, emit: (node: Node, parenthesizerRule?: ((node: Node) => Node) | undefined) => void, parenthesizerRuleSelector: OrdinalParentheizerRuleSelector<Node>, index: number) {
emit(node, parenthesizerRuleSelector.select(index));
function emitListItemWithParenthesizerRuleSelector(node: Node, emit: EmitFunction, parenthesizerRuleSelector: OrdinalParentheizerRuleSelector<Node> | undefined, index: number) {
emit(node, parenthesizerRuleSelector!.select(index));
}
function emitListItemWithParenthesizerRule(node: Node, emit: (node: Node, parenthesizerRule?: ((node: Node) => Node) | undefined) => void, parenthesizerRule: ParenthesizerRule<Node> | undefined, _index: number) {
function emitListItemWithParenthesizerRule(node: Node, emit: EmitFunction, parenthesizerRule: ParenthesizerRule<Node> | undefined, _index: number) {
emit(node, parenthesizerRule);
}
function getEmitListItem<T extends Node, R extends ParenthesizerRuleOrSelector<T> | undefined>(emit: (node: Node, parenthesizerRule?: ((node: Node) => Node) | undefined) => void, parenthesizerRule: R): (node: Node, emit: (node: Node, parenthesizerRule?: ((node: Node) => Node) | undefined) => void, parenthesizerRule: R, index: number) => void {
return emit.length === 1 ? emitListItemNoParenthesizer :
typeof parenthesizerRule === "object" ? emitListItemWithParenthesizerRuleSelector :
emitListItemWithParenthesizerRule;
function getEmitListItem<T extends Node>(emit: EmitFunction, parenthesizerRule: ParenthesizerRuleOrSelector<T> | undefined): EmitListItemFunction<T> {
return emit.length === 1 ? emitListItemNoParenthesizer as EmitListItemFunction<T> :
typeof parenthesizerRule === "object" ? emitListItemWithParenthesizerRuleSelector as EmitListItemFunction<T> :
emitListItemWithParenthesizerRule as EmitListItemFunction<T>;
}

Просмотреть файл

@ -11,9 +11,9 @@ import {
* @internal
*/
export interface BaseNodeFactory {
createBaseSourceFileNode(kind: SyntaxKind): Node;
createBaseIdentifierNode(kind: SyntaxKind): Node;
createBasePrivateIdentifierNode(kind: SyntaxKind): Node;
createBaseSourceFileNode(kind: SyntaxKind.SourceFile): Node;
createBaseIdentifierNode(kind: SyntaxKind.Identifier): Node;
createBasePrivateIdentifierNode(kind: SyntaxKind.PrivateIdentifier): Node;
createBaseTokenNode(kind: SyntaxKind): Node;
createBaseNode(kind: SyntaxKind): Node;
}
@ -24,11 +24,11 @@ export interface BaseNodeFactory {
* @internal
*/
export function createBaseNodeFactory(): BaseNodeFactory {
let NodeConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node;
let TokenConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node;
let IdentifierConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node;
let PrivateIdentifierConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node;
let SourceFileConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node;
let NodeConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node;
let TokenConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node;
let IdentifierConstructor: new (kind: SyntaxKind.Identifier, pos: number, end: number) => Node;
let PrivateIdentifierConstructor: new (kind: SyntaxKind.PrivateIdentifier, pos: number, end: number) => Node;
let SourceFileConstructor: new (kind: SyntaxKind.SourceFile, pos: number, end: number) => Node;
return {
createBaseSourceFileNode,
@ -38,15 +38,15 @@ export function createBaseNodeFactory(): BaseNodeFactory {
createBaseNode
};
function createBaseSourceFileNode(kind: SyntaxKind): Node {
function createBaseSourceFileNode(kind: SyntaxKind.SourceFile): Node {
return new (SourceFileConstructor || (SourceFileConstructor = objectAllocator.getSourceFileConstructor()))(kind, /*pos*/ -1, /*end*/ -1);
}
function createBaseIdentifierNode(kind: SyntaxKind): Node {
function createBaseIdentifierNode(kind: SyntaxKind.Identifier): Node {
return new (IdentifierConstructor || (IdentifierConstructor = objectAllocator.getIdentifierConstructor()))(kind, /*pos*/ -1, /*end*/ -1);
}
function createBasePrivateIdentifierNode(kind: SyntaxKind): Node {
function createBasePrivateIdentifierNode(kind: SyntaxKind.PrivateIdentifier): Node {
return new (PrivateIdentifierConstructor || (PrivateIdentifierConstructor = objectAllocator.getPrivateIdentifierConstructor()))(kind, /*pos*/ -1, /*end*/ -1);
}

Просмотреть файл

@ -6883,9 +6883,9 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode
* @param statementOffset The offset at which to begin the copy.
* @param visitor Optional callback used to visit any custom prologue directives.
*/
function copyCustomPrologue(source: readonly Statement[], target: Push<Statement>, statementOffset: number, visitor?: (node: Node) => VisitResult<Node>, filter?: (node: Node) => boolean): number;
function copyCustomPrologue(source: readonly Statement[], target: Push<Statement>, statementOffset: number | undefined, visitor?: (node: Node) => VisitResult<Node>, filter?: (node: Node) => boolean): number | undefined;
function copyCustomPrologue(source: readonly Statement[], target: Push<Statement>, statementOffset: number | undefined, visitor?: (node: Node) => VisitResult<Node>, filter: (node: Node) => boolean = returnTrue): number | undefined {
function copyCustomPrologue(source: readonly Statement[], target: Push<Statement>, statementOffset: number, visitor?: (node: Node) => VisitResult<Node>, filter?: (node: Statement) => boolean): number;
function copyCustomPrologue(source: readonly Statement[], target: Push<Statement>, statementOffset: number | undefined, visitor?: (node: Node) => VisitResult<Node>, filter?: (node: Statement) => boolean): number | undefined;
function copyCustomPrologue(source: readonly Statement[], target: Push<Statement>, statementOffset: number | undefined, visitor?: (node: Node) => VisitResult<Node>, filter: (node: Statement) => boolean = returnTrue): number | undefined {
const numStatements = source.length;
while (statementOffset !== undefined && statementOffset < numStatements) {
const statement = source[statementOffset];

Просмотреть файл

@ -1455,7 +1455,7 @@ export function createBinaryExpressionTrampoline<TOuterState, TState, TResult>(
const machine = new BinaryExpressionStateMachine(onEnter, onLeft, onOperator, onRight, onExit, foldState);
return trampoline;
function trampoline(node: BinaryExpression, outerState?: TOuterState) {
function trampoline(node: BinaryExpression, outerState: TOuterState) {
const resultHolder: { value: TResult } = { value: undefined! };
const stateStack: BinaryExpressionState[] = [BinaryExpressionState.enter];
const nodeStack: BinaryExpression[] = [node];

Просмотреть файл

@ -406,11 +406,11 @@ const enum SpeculationKind {
Reparse
}
let NodeConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node;
let TokenConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node;
let IdentifierConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node;
let PrivateIdentifierConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node;
let SourceFileConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node;
let NodeConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node;
let TokenConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node;
let IdentifierConstructor: new (kind: SyntaxKind.Identifier, pos: number, end: number) => Node;
let PrivateIdentifierConstructor: new (kind: SyntaxKind.PrivateIdentifier, pos: number, end: number) => Node;
let SourceFileConstructor: new (kind: SyntaxKind.SourceFile, pos: number, end: number) => Node;
/**
* NOTE: You should not use this, it is only exported to support `createNode` in `~/src/deprecatedCompat/deprecations.ts`.
@ -1426,9 +1426,9 @@ namespace Parser {
// capture constructors in 'initializeState' to avoid null checks
let NodeConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node;
let TokenConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node;
let IdentifierConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node;
let PrivateIdentifierConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node;
let SourceFileConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node;
let IdentifierConstructor: new (kind: SyntaxKind.Identifier, pos: number, end: number) => Identifier;
let PrivateIdentifierConstructor: new (kind: SyntaxKind.PrivateIdentifier, pos: number, end: number) => PrivateIdentifier;
let SourceFileConstructor: new (kind: SyntaxKind.SourceFile, pos: number, end: number) => SourceFile;
function countNode(node: Node) {
nodeCount++;
@ -2543,9 +2543,9 @@ namespace Parser {
function createMissingNode<T extends Node>(kind: T["kind"], reportAtCurrentPosition: false, diagnosticMessage?: DiagnosticMessage, arg0?: any): T;
function createMissingNode<T extends Node>(kind: T["kind"], reportAtCurrentPosition: boolean, diagnosticMessage: DiagnosticMessage, arg0?: any): T;
function createMissingNode<T extends Node>(kind: T["kind"], reportAtCurrentPosition: boolean, diagnosticMessage: DiagnosticMessage, arg0?: any): T {
function createMissingNode<T extends Node>(kind: T["kind"], reportAtCurrentPosition: boolean, diagnosticMessage?: DiagnosticMessage, arg0?: any): T {
if (reportAtCurrentPosition) {
parseErrorAtPosition(scanner.getStartPos(), 0, diagnosticMessage, arg0);
parseErrorAtPosition(scanner.getStartPos(), 0, diagnosticMessage!, arg0);
}
else if (diagnosticMessage) {
parseErrorAtCurrentToken(diagnosticMessage, arg0);
@ -9639,7 +9639,9 @@ namespace IncrementalParser {
}
}
function moveElementEntirelyPastChangeRange(element: IncrementalElement, isArray: boolean, delta: number, oldText: string, newText: string, aggressiveChecks: boolean) {
function moveElementEntirelyPastChangeRange(element: IncrementalNode, isArray: false, delta: number, oldText: string, newText: string, aggressiveChecks: boolean): void;
function moveElementEntirelyPastChangeRange(element: IncrementalNodeArray, isArray: true, delta: number, oldText: string, newText: string, aggressiveChecks: boolean): void;
function moveElementEntirelyPastChangeRange(element: IncrementalNode | IncrementalNodeArray, isArray: boolean, delta: number, oldText: string, newText: string, aggressiveChecks: boolean) {
if (isArray) {
visitArray(element as IncrementalNodeArray);
}
@ -9666,7 +9668,7 @@ namespace IncrementalParser {
Debug.assert(text === newText.substring(node.pos, node.end));
}
forEachChild(node, visitNode, visitArray);
forEachChild(node, visitNode as (node: Node) => void, visitArray as (nodes: NodeArray<Node>) => void);
if (hasJSDocNodes(node)) {
for (const jsDocComment of node.jsDoc!) {
visitNode(jsDocComment as Node as IncrementalNode);
@ -9819,7 +9821,7 @@ namespace IncrementalParser {
// Adjust the pos or end (or both) of the intersecting element accordingly.
adjustIntersectingElement(child, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta);
forEachChild(child, visitNode, visitArray);
forEachChild(child, visitNode as (node: Node) => void, visitArray as (nodes: NodeArray<Node>) => void);
if (hasJSDocNodes(child)) {
for (const jsDocComment of child.jsDoc!) {
visitNode(jsDocComment as Node as IncrementalNode);

Просмотреть файл

@ -967,14 +967,14 @@ export function forEachAncestorDirectory<T>(directory: Path, callback: (director
/** @internal */
export function forEachAncestorDirectory<T>(directory: string, callback: (directory: string) => T | undefined): T | undefined;
/** @internal */
export function forEachAncestorDirectory<T>(directory: Path, callback: (directory: Path) => T | undefined): T | undefined {
export function forEachAncestorDirectory<T, P extends string>(directory: P, callback: (directory: P) => T | undefined): T | undefined {
while (true) {
const result = callback(directory);
if (result !== undefined) {
return result;
}
const parentPath = getDirectoryPath(directory);
const parentPath = getDirectoryPath(directory) as P;
if (parentPath === directory) {
return undefined;
}

Просмотреть файл

@ -1540,7 +1540,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
}
let actualResolveTypeReferenceDirectiveNamesWorker: <T extends FileReference | string>(
typeDirectiveNames: T[],
typeDirectiveNames: readonly T[],
containingFile: string,
redirectedReference: ResolvedProjectReference | undefined,
options: CompilerOptions,
@ -1879,7 +1879,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
return result;
}
function resolveTypeReferenceDirectiveNamesWorker<T extends FileReference | string>(typeDirectiveNames: T[], containingFile: string | SourceFile, reusedNames: readonly T[] | undefined): readonly ResolvedTypeReferenceDirectiveWithFailedLookupLocations[] {
function resolveTypeReferenceDirectiveNamesWorker<T extends FileReference | string>(typeDirectiveNames: readonly T[], containingFile: string | SourceFile, reusedNames: readonly T[] | undefined): readonly ResolvedTypeReferenceDirectiveWithFailedLookupLocations[] {
if (!typeDirectiveNames.length) return [];
const containingSourceFile = !isString(containingFile) ? containingFile : undefined;
const containingFileName = !isString(containingFile) ? getNormalizedAbsolutePath(containingFile.originalFileName, currentDirectory) : containingFile;
@ -2113,7 +2113,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
function resolveTypeReferenceDirectiveNamesReusingOldState(typeDirectiveNames: readonly FileReference[], containingFile: SourceFile): readonly ResolvedTypeReferenceDirectiveWithFailedLookupLocations[];
function resolveTypeReferenceDirectiveNamesReusingOldState(typeDirectiveNames: string[], containingFile: string): readonly ResolvedTypeReferenceDirectiveWithFailedLookupLocations[];
function resolveTypeReferenceDirectiveNamesReusingOldState<T extends string | FileReference>(typeDirectiveNames: T[], containingFile: string | SourceFile): readonly ResolvedTypeReferenceDirectiveWithFailedLookupLocations[] {
function resolveTypeReferenceDirectiveNamesReusingOldState<T extends string | FileReference>(typeDirectiveNames: readonly T[], containingFile: string | SourceFile): readonly ResolvedTypeReferenceDirectiveWithFailedLookupLocations[] {
if (structureIsReused === StructureIsReused.Not) {
// If the old program state does not permit reusing resolutions and `file` does not contain locally defined ambient modules,
// the best we can do is fallback to the default logic.
@ -3077,7 +3077,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
return result;
}
function getDeclarationDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): readonly DiagnosticWithLocation[] {
function getDeclarationDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken | undefined): readonly DiagnosticWithLocation[] {
return sourceFile.isDeclarationFile ? [] : getDeclarationDiagnosticsWorker(sourceFile, cancellationToken);
}

Просмотреть файл

@ -884,28 +884,24 @@ function iterateCommentRanges<T, U>(reduce: boolean, text: string, pos: number,
export function forEachLeadingCommentRange<U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean) => U): U | undefined;
export function forEachLeadingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T): U | undefined;
export function forEachLeadingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state?: T): U | undefined {
return iterateCommentRanges(/*reduce*/ false, text, pos, /*trailing*/ false, cb, state);
return iterateCommentRanges(/*reduce*/ false, text, pos, /*trailing*/ false, cb, state!);
}
export function forEachTrailingCommentRange<U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean) => U): U | undefined;
export function forEachTrailingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T): U | undefined;
export function forEachTrailingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state?: T): U | undefined {
return iterateCommentRanges(/*reduce*/ false, text, pos, /*trailing*/ true, cb, state);
return iterateCommentRanges(/*reduce*/ false, text, pos, /*trailing*/ true, cb, state!);
}
export function reduceEachLeadingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial: U) {
export function reduceEachLeadingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T, initial: U) {
return iterateCommentRanges(/*reduce*/ true, text, pos, /*trailing*/ false, cb, state, initial);
}
export function reduceEachTrailingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial: U) {
export function reduceEachTrailingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T, initial: U) {
return iterateCommentRanges(/*reduce*/ true, text, pos, /*trailing*/ true, cb, state, initial);
}
function appendCommentRange(pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, _state: any, comments: CommentRange[]) {
if (!comments) {
comments = [];
}
function appendCommentRange(pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, _state: any, comments: CommentRange[] = []) {
comments.push({ kind, pos, end, hasTrailingNewLine });
return comments;
}

Просмотреть файл

@ -1,4 +1,5 @@
import {
BaseType,
clear,
EntityNameOrEntityNameExpression,
forEach,
@ -9,7 +10,6 @@ import {
IndexType,
InterfaceType,
MappedType,
Node,
ObjectFlags,
ObjectType,
ResolvedType,
@ -31,10 +31,10 @@ export function createGetSymbolWalker(
getRestTypeOfSignature: (sig: Signature) => Type,
getTypePredicateOfSignature: (sig: Signature) => TypePredicate | undefined,
getReturnTypeOfSignature: (sig: Signature) => Type,
getBaseTypes: (type: Type) => Type[],
getBaseTypes: (type: InterfaceType) => BaseType[],
resolveStructuredTypeMembers: (type: ObjectType) => ResolvedType,
getTypeOfSymbol: (sym: Symbol) => Type,
getResolvedSymbol: (node: Node) => Symbol,
getResolvedSymbol: (node: Identifier) => Symbol,
getConstraintOfTypeParameter: (typeParameter: TypeParameter) => Type | undefined,
getFirstIdentifier: (node: EntityNameOrEntityNameExpression) => Identifier,
getTypeArguments: (type: TypeReference) => readonly Type[]) {
@ -214,3 +214,4 @@ export function createGetSymbolWalker(
}
}
}

Просмотреть файл

@ -1296,7 +1296,6 @@ export function patchWriteFileEnsuringDirectory(sys: System) {
path => sys.directoryExists(path));
}
/** @internal */
export type BufferEncoding = "ascii" | "utf8" | "utf-8" | "utf16le" | "ucs2" | "ucs-2" | "base64" | "latin1" | "binary" | "hex";
/** @internal */

Просмотреть файл

@ -9,7 +9,6 @@ import {
AssignmentPattern,
AutoAccessorPropertyDeclaration,
BinaryExpression,
BindingOrAssignmentElement,
Bundle,
CallExpression,
chainBundle,
@ -70,6 +69,7 @@ import {
isArrowFunction,
isAssignmentExpression,
isAutoAccessorPropertyDeclaration,
isBindingOrAssignmentElement,
isCallChain,
isClassDeclaration,
isClassElement,
@ -392,7 +392,7 @@ export function transformClassFields(context: TransformationContext): (x: Source
return visited;
}
function visitor(node: Node): VisitResult<Node> {
function visitor(node: Node): VisitResult<Node | undefined> {
if (!(node.transformFlags & TransformFlags.ContainsClassFields) &&
!(node.transformFlags & TransformFlags.ContainsLexicalThisOrSuper)) {
return node;
@ -455,7 +455,7 @@ export function transformClassFields(context: TransformationContext): (x: Source
/**
* Visits a node in an expression whose result is discarded.
*/
function discardedValueVisitor(node: Node): VisitResult<Node> {
function discardedValueVisitor(node: Node): VisitResult<Node | undefined> {
switch (node.kind) {
case SyntaxKind.PrefixUnaryExpression:
case SyntaxKind.PostfixUnaryExpression:
@ -470,7 +470,7 @@ export function transformClassFields(context: TransformationContext): (x: Source
/**
* Visits a node in a {@link HeritageClause}.
*/
function heritageClauseVisitor(node: Node): VisitResult<Node> {
function heritageClauseVisitor(node: Node): VisitResult<Node | undefined> {
switch (node.kind) {
case SyntaxKind.HeritageClause:
return visitEachChild(node, heritageClauseVisitor, context);
@ -484,7 +484,7 @@ export function transformClassFields(context: TransformationContext): (x: Source
/**
* Visits the assignment target of a destructuring assignment.
*/
function assignmentTargetVisitor(node: Node): VisitResult<Node> {
function assignmentTargetVisitor(node: Node): VisitResult<Node | undefined> {
switch (node.kind) {
case SyntaxKind.ObjectLiteralExpression:
case SyntaxKind.ArrayLiteralExpression:
@ -497,7 +497,7 @@ export function transformClassFields(context: TransformationContext): (x: Source
/**
* Visits a member of a class.
*/
function classElementVisitor(node: Node): VisitResult<Node> {
function classElementVisitor(node: Node): VisitResult<Node | undefined> {
switch (node.kind) {
case SyntaxKind.Constructor:
return visitConstructorDeclaration(node as ConstructorDeclaration);
@ -568,6 +568,7 @@ export function transformClassFields(context: TransformationContext): (x: Source
const info = accessPrivateIdentifier(node.left);
if (info) {
const receiver = visitNode(node.right, visitor, isExpression);
Debug.assert(receiver);
return setOriginalNode(
context.getEmitHelperFactory().createClassPrivateFieldInHelper(info.brandCheckIdentifier, receiver),
@ -594,6 +595,7 @@ export function transformClassFields(context: TransformationContext): (x: Source
function visitComputedPropertyName(node: ComputedPropertyName) {
let expression = visitNode(node.expression, visitor, isExpression);
Debug.assert(expression);
if (some(pendingExpressions)) {
if (isParenthesizedExpression(expression)) {
expression = factory.updateParenthesizedExpression(expression, factory.inlineExpressions([...pendingExpressions, expression.expression]));
@ -702,6 +704,7 @@ export function transformClassFields(context: TransformationContext): (x: Source
const temp = factory.createTempVariable(hoistVariableDeclaration);
setSourceMapRange(temp, name.expression);
const expression = visitNode(name.expression, visitor, isExpression);
Debug.assert(expression);
const assignment = factory.createAssignment(temp, expression);
setSourceMapRange(assignment, name.expression);
getterName = factory.updateComputedPropertyName(name, factory.inlineExpressions([assignment, temp]));
@ -814,7 +817,7 @@ export function transformClassFields(context: TransformationContext): (x: Source
}
function createPrivateIdentifierAccess(info: PrivateIdentifierInfo, receiver: Expression): Expression {
return createPrivateIdentifierAccessHelper(info, visitNode(receiver, visitor, isExpression));
return createPrivateIdentifierAccessHelper(info, Debug.checkDefined(visitNode(receiver, visitor, isExpression)));
}
function createPrivateIdentifierAccessHelper(info: PrivateIdentifierInfo, receiver: Expression): Expression {
@ -898,7 +901,7 @@ export function transformClassFields(context: TransformationContext): (x: Source
// converts `super[x]` into `Reflect.get(_baseTemp, x, _classTemp)`
const superProperty = factory.createReflectGetCall(
superClassReference,
visitNode(node.argumentExpression, visitor, isExpression),
Debug.checkDefined(visitNode(node.argumentExpression, visitor, isExpression)),
classConstructor
);
setOriginalNode(superProperty, node.expression);
@ -918,6 +921,7 @@ export function transformClassFields(context: TransformationContext): (x: Source
let info: PrivateIdentifierInfo | undefined;
if (info = accessPrivateIdentifier(operand.name)) {
const receiver = visitNode(operand.expression, visitor, isExpression);
Debug.assert(receiver);
const { readExpression, initializeExpression } = createCopiableReceiverExpr(receiver);
let expression: Expression = createPrivateIdentifierAccess(info, readExpression);
@ -971,7 +975,7 @@ export function transformClassFields(context: TransformationContext): (x: Source
}
else {
getterName = factory.createTempVariable(hoistVariableDeclaration);
setterName = factory.createAssignment(getterName, visitNode(operand.argumentExpression, visitor, isExpression));
setterName = factory.createAssignment(getterName, Debug.checkDefined(visitNode(operand.argumentExpression, visitor, isExpression)));
}
}
if (setterName && getterName) {
@ -1008,7 +1012,7 @@ export function transformClassFields(context: TransformationContext): (x: Source
function visitExpressionStatement(node: ExpressionStatement) {
return factory.updateExpressionStatement(
node,
visitNode(node.expression, discardedValueVisitor, isExpression)
Debug.checkDefined(visitNode(node.expression, discardedValueVisitor, isExpression))
);
}
@ -1032,17 +1036,17 @@ export function transformClassFields(context: TransformationContext): (x: Source
if (isCallChain(node)) {
return factory.updateCallChain(
node,
factory.createPropertyAccessChain(visitNode(target, visitor), node.questionDotToken, "call"),
factory.createPropertyAccessChain(Debug.checkDefined(visitNode(target, visitor, isExpression)), node.questionDotToken, "call"),
/*questionDotToken*/ undefined,
/*typeArguments*/ undefined,
[visitNode(thisArg, visitor, isExpression), ...visitNodes(node.arguments, visitor, isExpression)]
[Debug.checkDefined(visitNode(thisArg, visitor, isExpression)), ...visitNodes(node.arguments, visitor, isExpression)]
);
}
return factory.updateCallExpression(
node,
factory.createPropertyAccessExpression(visitNode(target, visitor), "call"),
factory.createPropertyAccessExpression(Debug.checkDefined(visitNode(target, visitor, isExpression)), "call"),
/*typeArguments*/ undefined,
[visitNode(thisArg, visitor, isExpression), ...visitNodes(node.arguments, visitor, isExpression)]
[Debug.checkDefined(visitNode(thisArg, visitor, isExpression)), ...visitNodes(node.arguments, visitor, isExpression)]
);
}
@ -1055,7 +1059,7 @@ export function transformClassFields(context: TransformationContext): (x: Source
// converts `super.f(...)` into `Reflect.get(_baseTemp, "f", _classTemp).call(_classTemp, ...)`
const invocation = factory.createFunctionCallCall(
visitNode(node.expression, visitor, isExpression),
Debug.checkDefined(visitNode(node.expression, visitor, isExpression)),
currentClassLexicalEnvironment.classConstructor,
visitNodes(node.arguments, visitor, isExpression)
);
@ -1075,12 +1079,12 @@ export function transformClassFields(context: TransformationContext): (x: Source
return factory.updateTaggedTemplateExpression(
node,
factory.createCallExpression(
factory.createPropertyAccessExpression(visitNode(target, visitor), "bind"),
factory.createPropertyAccessExpression(Debug.checkDefined(visitNode(target, visitor, isExpression)), "bind"),
/*typeArguments*/ undefined,
[visitNode(thisArg, visitor, isExpression)]
[Debug.checkDefined(visitNode(thisArg, visitor, isExpression))]
),
/*typeArguments*/ undefined,
visitNode(node.template, visitor, isTemplateLiteral)
Debug.checkDefined(visitNode(node.template, visitor, isTemplateLiteral))
);
}
if (shouldTransformSuperInStaticInitializers &&
@ -1090,7 +1094,7 @@ export function transformClassFields(context: TransformationContext): (x: Source
// converts `` super.f`x` `` into `` Reflect.get(_baseTemp, "f", _classTemp).bind(_classTemp)`x` ``
const invocation = factory.createFunctionBindCall(
visitNode(node.tag, visitor, isExpression),
Debug.checkDefined(visitNode(node.tag, visitor, isExpression)),
currentClassLexicalEnvironment.classConstructor,
[]
);
@ -1100,7 +1104,7 @@ export function transformClassFields(context: TransformationContext): (x: Source
node,
invocation,
/*typeArguments*/ undefined,
visitNode(node.template, visitor, isTemplateLiteral)
Debug.checkDefined(visitNode(node.template, visitor, isTemplateLiteral))
);
}
return visitEachChild(node, visitor, context);
@ -1137,9 +1141,9 @@ export function transformClassFields(context: TransformationContext): (x: Source
pendingExpressions = undefined;
node = factory.updateBinaryExpression(
node,
visitNode(node.left, assignmentTargetVisitor),
Debug.checkDefined(visitNode(node.left, assignmentTargetVisitor, isExpression)),
node.operatorToken,
visitNode(node.right, visitor)
Debug.checkDefined(visitNode(node.right, visitor, isExpression))
);
const expr = some(pendingExpressions) ?
factory.inlineExpressions(compact([...pendingExpressions, node])) :
@ -1176,7 +1180,7 @@ export function transformClassFields(context: TransformationContext): (x: Source
node,
visitInvalidSuperProperty(node.left),
node.operatorToken,
visitNode(node.right, visitor, isExpression));
Debug.checkDefined(visitNode(node.right, visitor, isExpression)));
}
if (classConstructor && superClassReference) {
let setterName =
@ -1204,6 +1208,7 @@ export function transformClassFields(context: TransformationContext): (x: Source
setOriginalNode(superPropertyGet, node.left);
setTextRange(superPropertyGet, node.left);
Debug.assert(expression);
expression = factory.createBinaryExpression(
superPropertyGet,
getNonAssignmentOperatorForCompoundAssignment(node.operatorToken.kind),
@ -1214,10 +1219,12 @@ export function transformClassFields(context: TransformationContext): (x: Source
const temp = valueIsDiscarded ? undefined : factory.createTempVariable(hoistVariableDeclaration);
if (temp) {
Debug.assert(expression);
expression = factory.createAssignment(temp, expression);
setTextRange(temp, node);
}
Debug.assert(expression);
expression = factory.createReflectSetCall(
superClassReference,
setterName,
@ -1246,8 +1253,8 @@ export function transformClassFields(context: TransformationContext): (x: Source
}
function createPrivateIdentifierAssignment(info: PrivateIdentifierInfo, receiver: Expression, right: Expression, operator: AssignmentOperator): Expression {
receiver = visitNode(receiver, visitor, isExpression);
right = visitNode(right, visitor, isExpression);
receiver = Debug.checkDefined(visitNode(receiver, visitor, isExpression));
right = Debug.checkDefined(visitNode(right, visitor, isExpression));
if (isCompoundAssignment(operator)) {
const { readExpression, initializeExpression } = createCopiableReceiverExpr(receiver);
@ -1361,7 +1368,7 @@ export function transformClassFields(context: TransformationContext): (x: Source
node,
factory.createAssignment(
temp,
visitNode(node.expression, visitor, isExpression)
Debug.checkDefined(visitNode(node.expression, visitor, isExpression))
),
/*typeArguments*/ undefined
);
@ -2071,7 +2078,7 @@ export function transformClassFields(context: TransformationContext): (x: Source
factory.updateElementAccessExpression(
node,
factory.createVoidZero(),
visitNode(node.argumentExpression, visitor, isExpression));
Debug.checkDefined(visitNode(node.argumentExpression, visitor, isExpression)));
}
function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) {
@ -2215,6 +2222,7 @@ export function transformClassFields(context: TransformationContext): (x: Source
function getPropertyNameExpressionIfNeeded(name: PropertyName, shouldHoist: boolean): Expression | undefined {
if (isComputedPropertyName(name)) {
const expression = visitNode(name.expression, visitor, isExpression);
Debug.assert(expression);
const innerExpression = skipPartiallyEmittedExpressions(expression);
const inlinable = isSimpleInlineableExpression(innerExpression);
const alreadyTransformed = isAssignmentExpression(innerExpression) && isGeneratedIdentifier(innerExpression.left);
@ -2542,7 +2550,7 @@ export function transformClassFields(context: TransformationContext): (x: Source
// differently inside the function.
if (isThisProperty(node) || isSuperProperty(node) || !isSimpleCopiableExpression(node.expression)) {
receiver = factory.createTempVariable(hoistVariableDeclaration, /*reservedInNestedScopes*/ true);
getPendingExpressions().push(factory.createBinaryExpression(receiver, SyntaxKind.EqualsToken, visitNode(node.expression, visitor, isExpression)));
getPendingExpressions().push(factory.createBinaryExpression(receiver, SyntaxKind.EqualsToken, Debug.checkDefined(visitNode(node.expression, visitor, isExpression))));
}
return factory.createAssignmentTargetWrapper(
parameter,
@ -2555,7 +2563,8 @@ export function transformClassFields(context: TransformationContext): (x: Source
);
}
function visitArrayAssignmentTarget(node: BindingOrAssignmentElement) {
function visitArrayAssignmentTarget(node: Node) {
Debug.assertNode(node, isBindingOrAssignmentElement);
const target = getTargetOfBindingOrAssignmentElement(node);
if (target) {
let wrapped: LeftHandSideExpression | undefined;
@ -2595,7 +2604,7 @@ export function transformClassFields(context: TransformationContext): (x: Source
node,
wrapped,
node.operatorToken,
visitNode(node.right, visitor, isExpression)
Debug.checkDefined(visitNode(node.right, visitor, isExpression))
);
}
else if (isSpreadElement(node)) {
@ -2649,16 +2658,16 @@ export function transformClassFields(context: TransformationContext): (x: Source
const initializer = getInitializerOfBindingOrAssignmentElement(node);
return factory.updatePropertyAssignment(
node,
visitNode(node.name, visitor, isPropertyName),
Debug.checkDefined(visitNode(node.name, visitor, isPropertyName)),
wrapped ?
initializer ? factory.createAssignment(wrapped, visitNode(initializer, visitor)) : wrapped :
visitNode(node.initializer, assignmentTargetVisitor, isExpression)
initializer ? factory.createAssignment(wrapped, Debug.checkDefined(visitNode(initializer, visitor, isExpression))) : wrapped :
Debug.checkDefined(visitNode(node.initializer, assignmentTargetVisitor, isExpression))
);
}
if (isSpreadAssignment(node)) {
return factory.updateSpreadAssignment(
node,
wrapped || visitNode(node.expression, assignmentTargetVisitor, isExpression)
wrapped || Debug.checkDefined(visitNode(node.expression, assignmentTargetVisitor, isExpression))
);
}
Debug.assert(wrapped === undefined, "Should not have generated a wrapped target");

Просмотреть файл

@ -93,13 +93,17 @@ import {
InterfaceDeclaration,
isAnyImportSyntax,
isArray,
isArrayBindingElement,
isBindingElement,
isBindingPattern,
isClassDeclaration,
isClassElement,
isDeclaration,
isEntityName,
isEntityNameExpression,
isExportAssignment,
isExportDeclaration,
isExpressionWithTypeArguments,
isExternalModule,
isExternalModuleAugmentation,
isExternalModuleIndicator,
@ -131,15 +135,18 @@ import {
isSourceFile,
isSourceFileJS,
isSourceFileNotJson,
isStatement,
isStringANonContextualKeyword,
isStringLiteral,
isStringLiteralLike,
isTupleTypeNode,
isTypeAliasDeclaration,
isTypeElement,
isTypeNode,
isTypeParameterDeclaration,
isTypeQueryNode,
isUnparsedSource,
isVariableDeclaration,
last,
LateBoundDeclaration,
LateVisibilityPaintedStatement,
@ -277,7 +284,7 @@ export function transformDeclarations(context: TransformationContext) {
let enclosingDeclaration: Node;
let necessaryTypeReferences: Set<[specifier: string, mode: ResolutionMode]> | undefined;
let lateMarkedStatements: LateVisibilityPaintedStatement[] | undefined;
let lateStatementReplacementMap: Map<NodeId, VisitResult<LateVisibilityPaintedStatement | ExportAssignment>>;
let lateStatementReplacementMap: Map<NodeId, VisitResult<LateVisibilityPaintedStatement | ExportAssignment | undefined>>;
let suppressNewDiagnosticContexts: boolean;
let exportedModulesFromDeclarationEmit: Symbol[] | undefined;
@ -502,7 +509,7 @@ export function transformDeclarations(context: TransformationContext) {
if (isExternalOrCommonJsModule(sourceFile) || isJsonSourceFile(sourceFile)) {
resultHasExternalModuleIndicator = false; // unused in external module bundle emit (all external modules are within module blocks, therefore are known to be modules)
needsDeclare = false;
const statements = isSourceFileJS(sourceFile) ? factory.createNodeArray(transformDeclarationsForJS(sourceFile, /*bundled*/ true)) : visitNodes(sourceFile.statements, visitDeclarationStatements);
const statements = isSourceFileJS(sourceFile) ? factory.createNodeArray(transformDeclarationsForJS(sourceFile, /*bundled*/ true)) : visitNodes(sourceFile.statements, visitDeclarationStatements, isStatement);
const newFile = factory.updateSourceFile(sourceFile, [factory.createModuleDeclaration(
[factory.createModifier(SyntaxKind.DeclareKeyword)],
factory.createStringLiteral(getResolvedExternalModuleName(context.getEmitHost(), sourceFile)),
@ -511,7 +518,7 @@ export function transformDeclarations(context: TransformationContext) {
return newFile;
}
needsDeclare = true;
const updated = isSourceFileJS(sourceFile) ? factory.createNodeArray(transformDeclarationsForJS(sourceFile)) : visitNodes(sourceFile.statements, visitDeclarationStatements);
const updated = isSourceFileJS(sourceFile) ? factory.createNodeArray(transformDeclarationsForJS(sourceFile)) : visitNodes(sourceFile.statements, visitDeclarationStatements, isStatement);
return factory.updateSourceFile(sourceFile, transformAndReplaceLatePaintedStatements(updated), /*isDeclarationFile*/ true, /*referencedFiles*/ [], /*typeReferences*/ [], /*hasNoDefaultLib*/ false, /*libReferences*/ []);
}
), mapDefined(node.prepends, prepend => {
@ -560,7 +567,7 @@ export function transformDeclarations(context: TransformationContext) {
emittedImports = filter(combinedStatements, isAnyImportSyntax);
}
else {
const statements = visitNodes(node.statements, visitDeclarationStatements);
const statements = visitNodes(node.statements, visitDeclarationStatements, isStatement);
combinedStatements = setTextRange(factory.createNodeArray(transformAndReplaceLatePaintedStatements(statements)), node.statements);
refs.forEach(referenceVisitor);
emittedImports = filter(combinedStatements, isAnyImportSyntax);
@ -676,14 +683,14 @@ export function transformDeclarations(context: TransformationContext) {
}
else {
if (name.kind === SyntaxKind.ArrayBindingPattern) {
return factory.updateArrayBindingPattern(name, visitNodes(name.elements, visitBindingElement));
return factory.updateArrayBindingPattern(name, visitNodes(name.elements, visitBindingElement, isArrayBindingElement));
}
else {
return factory.updateObjectBindingPattern(name, visitNodes(name.elements, visitBindingElement));
return factory.updateObjectBindingPattern(name, visitNodes(name.elements, visitBindingElement, isBindingElement));
}
}
function visitBindingElement<T extends ArrayBindingElement>(elem: T): T;
function visitBindingElement<T extends Node>(elem: T): T;
function visitBindingElement(elem: ArrayBindingElement): ArrayBindingElement {
if (elem.kind === SyntaxKind.OmittedExpression) {
return elem;
@ -767,10 +774,10 @@ export function transformDeclarations(context: TransformationContext) {
(resolver.isRequiredInitializedParameter(node) ||
resolver.isOptionalUninitializedParameterProperty(node));
if (type && !shouldUseResolverType) {
return visitNode(type, visitDeclarationSubtree);
return visitNode(type, visitDeclarationSubtree, isTypeNode);
}
if (!getParseTreeNode(node)) {
return type ? visitNode(type, visitDeclarationSubtree) : factory.createKeywordTypeNode(SyntaxKind.AnyKeyword);
return type ? visitNode(type, visitDeclarationSubtree, isTypeNode) : factory.createKeywordTypeNode(SyntaxKind.AnyKeyword);
}
if (node.kind === SyntaxKind.SetAccessor) {
// Set accessors with no associated type node (from it's param or get accessor return) are `any` since they are never contextually typed right now
@ -891,7 +898,7 @@ export function transformDeclarations(context: TransformationContext) {
}
function ensureTypeParams(node: Node, params: NodeArray<TypeParameterDeclaration> | undefined) {
return hasEffectiveModifier(node, ModifierFlags.Private) ? undefined : visitNodes(params, visitDeclarationSubtree);
return hasEffectiveModifier(node, ModifierFlags.Private) ? undefined : visitNodes(params, visitDeclarationSubtree, isTypeParameterDeclaration);
}
function isEnclosingDeclaration(node: Node) {
@ -1061,13 +1068,13 @@ export function transformDeclarations(context: TransformationContext) {
// And lastly, we need to get the final form of all those indetermine import declarations from before and add them to the output list
// (and remove them from the set to examine for outter declarations)
return visitNodes(statements, visitLateVisibilityMarkedStatements);
return visitNodes(statements, visitLateVisibilityMarkedStatements, isStatement);
function visitLateVisibilityMarkedStatements(statement: Statement) {
if (isLateVisibilityPaintedStatement(statement)) {
const key = getOriginalNodeId(statement);
if (lateStatementReplacementMap.has(key)) {
const result = lateStatementReplacementMap.get(key);
const result = lateStatementReplacementMap.get(key) as Statement | readonly Statement[] | undefined;
lateStatementReplacementMap.delete(key);
if (result) {
if (isArray(result) ? some(result, needsScopeMarker) : needsScopeMarker(result)) {
@ -1085,7 +1092,7 @@ export function transformDeclarations(context: TransformationContext) {
}
}
function visitDeclarationSubtree(input: Node): VisitResult<Node> {
function visitDeclarationSubtree(input: Node): VisitResult<Node | undefined> {
if (shouldStripInternal(input)) return;
if (isDeclaration(input)) {
if (isDeclarationAndNotVisible(input)) return;
@ -1254,7 +1261,7 @@ export function transformDeclarations(context: TransformationContext) {
input,
ensureModifiers(input),
updateParamsList(input, input.parameters),
visitNode(input.type, visitDeclarationSubtree) || factory.createKeywordTypeNode(SyntaxKind.AnyKeyword)
visitNode(input.type, visitDeclarationSubtree, isTypeNode) || factory.createKeywordTypeNode(SyntaxKind.AnyKeyword)
));
}
case SyntaxKind.VariableDeclaration: {
@ -1274,20 +1281,24 @@ export function transformDeclarations(context: TransformationContext) {
case SyntaxKind.ConditionalType: {
// We have to process conditional types in a special way because for visibility purposes we need to push a new enclosingDeclaration
// just for the `infer` types in the true branch. It's an implicit declaration scope that only applies to _part_ of the type.
const checkType = visitNode(input.checkType, visitDeclarationSubtree);
const extendsType = visitNode(input.extendsType, visitDeclarationSubtree);
const checkType = visitNode(input.checkType, visitDeclarationSubtree, isTypeNode);
const extendsType = visitNode(input.extendsType, visitDeclarationSubtree, isTypeNode);
const oldEnclosingDecl = enclosingDeclaration;
enclosingDeclaration = input.trueType;
const trueType = visitNode(input.trueType, visitDeclarationSubtree);
const trueType = visitNode(input.trueType, visitDeclarationSubtree, isTypeNode);
enclosingDeclaration = oldEnclosingDecl;
const falseType = visitNode(input.falseType, visitDeclarationSubtree);
const falseType = visitNode(input.falseType, visitDeclarationSubtree, isTypeNode);
Debug.assert(checkType);
Debug.assert(extendsType);
Debug.assert(trueType);
Debug.assert(falseType);
return cleanup(factory.updateConditionalTypeNode(input, checkType, extendsType, trueType, falseType));
}
case SyntaxKind.FunctionType: {
return cleanup(factory.updateFunctionTypeNode(input, visitNodes(input.typeParameters, visitDeclarationSubtree), updateParamsList(input, input.parameters), visitNode(input.type, visitDeclarationSubtree)));
return cleanup(factory.updateFunctionTypeNode(input, visitNodes(input.typeParameters, visitDeclarationSubtree, isTypeParameterDeclaration), updateParamsList(input, input.parameters), Debug.checkDefined(visitNode(input.type, visitDeclarationSubtree, isTypeNode))));
}
case SyntaxKind.ConstructorType: {
return cleanup(factory.updateConstructorTypeNode(input, ensureModifiers(input), visitNodes(input.typeParameters, visitDeclarationSubtree), updateParamsList(input, input.parameters), visitNode(input.type, visitDeclarationSubtree)));
return cleanup(factory.updateConstructorTypeNode(input, ensureModifiers(input), visitNodes(input.typeParameters, visitDeclarationSubtree, isTypeParameterDeclaration), updateParamsList(input, input.parameters), Debug.checkDefined(visitNode(input.type, visitDeclarationSubtree, isTypeNode))));
}
case SyntaxKind.ImportType: {
if (!isLiteralImportTypeNode(input)) return cleanup(input);
@ -1334,7 +1345,7 @@ export function transformDeclarations(context: TransformationContext) {
return node.parent.kind === SyntaxKind.MethodDeclaration && hasEffectiveModifier(node.parent, ModifierFlags.Private);
}
function visitDeclarationStatements(input: Node): VisitResult<Node> {
function visitDeclarationStatements(input: Node): VisitResult<Node | undefined> {
if (!isPreservedDeclarationStatement(input)) {
// return undefined for unmatched kinds to omit them from the tree
return;
@ -1441,7 +1452,7 @@ export function transformDeclarations(context: TransformationContext) {
ensureModifiers(input),
input.name,
visitNodes(input.typeParameters, visitDeclarationSubtree, isTypeParameterDeclaration),
visitNode(input.type, visitDeclarationSubtree, isTypeNode)
Debug.checkDefined(visitNode(input.type, visitDeclarationSubtree, isTypeNode))
));
needsDeclare = previousNeedsDeclare;
return clean;
@ -1453,7 +1464,7 @@ export function transformDeclarations(context: TransformationContext) {
input.name,
ensureTypeParams(input, input.typeParameters),
transformHeritageClauses(input.heritageClauses),
visitNodes(input.members, visitDeclarationSubtree)
visitNodes(input.members, visitDeclarationSubtree, isTypeElement)
));
}
case SyntaxKind.FunctionDeclaration: {
@ -1553,7 +1564,7 @@ export function transformDeclarations(context: TransformationContext) {
const oldHasScopeFix = resultHasScopeMarker;
resultHasScopeMarker = false;
needsScopeFixMarker = false;
const statements = visitNodes(inner.statements, visitDeclarationStatements);
const statements = visitNodes(inner.statements, visitDeclarationStatements, isStatement);
let lateStatements = transformAndReplaceLatePaintedStatements(statements);
if (input.flags & NodeFlags.Ambient) {
needsScopeFixMarker = false; // If it was `declare`'d everything is implicitly exported already, ignore late printed "privates"
@ -1567,7 +1578,7 @@ export function transformDeclarations(context: TransformationContext) {
lateStatements = factory.createNodeArray([...lateStatements, createEmptyExports(factory)]);
}
else {
lateStatements = visitNodes(lateStatements, stripExportModifiers);
lateStatements = visitNodes(lateStatements, stripExportModifiers, isStatement);
}
}
const body = factory.updateModuleBlock(inner, lateStatements);
@ -1658,7 +1669,7 @@ export function transformDeclarations(context: TransformationContext) {
/*initializer*/ undefined
)
] : undefined;
const memberNodes = concatenate(concatenate(privateIdentifier, parameterProperties), visitNodes(input.members, visitDeclarationSubtree));
const memberNodes = concatenate(concatenate(privateIdentifier, parameterProperties), visitNodes(input.members, visitDeclarationSubtree, isClassElement));
const members = factory.createNodeArray(memberNodes);
const extendsClause = getEffectiveBaseTypeNode(input);
@ -1678,11 +1689,11 @@ export function transformDeclarations(context: TransformationContext) {
if (clause.token === SyntaxKind.ExtendsKeyword) {
const oldDiag = getSymbolAccessibilityDiagnostic;
getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(clause.types[0]);
const newClause = factory.updateHeritageClause(clause, map(clause.types, t => factory.updateExpressionWithTypeArguments(t, newId, visitNodes(t.typeArguments, visitDeclarationSubtree))));
const newClause = factory.updateHeritageClause(clause, map(clause.types, t => factory.updateExpressionWithTypeArguments(t, newId, visitNodes(t.typeArguments, visitDeclarationSubtree, isTypeNode))));
getSymbolAccessibilityDiagnostic = oldDiag;
return newClause;
}
return factory.updateHeritageClause(clause, visitNodes(factory.createNodeArray(filter(clause.types, t => isEntityNameExpression(t.expression) || t.expression.kind === SyntaxKind.NullKeyword)), visitDeclarationSubtree));
return factory.updateHeritageClause(clause, visitNodes(factory.createNodeArray(filter(clause.types, t => isEntityNameExpression(t.expression) || t.expression.kind === SyntaxKind.NullKeyword)), visitDeclarationSubtree, isExpressionWithTypeArguments));
}));
return [statement, cleanup(factory.updateClassDeclaration(
input,
@ -1741,7 +1752,7 @@ export function transformDeclarations(context: TransformationContext) {
function transformVariableStatement(input: VariableStatement) {
if (!forEach(input.declarationList.declarations, getBindingNameVisible)) return;
const nodes = visitNodes(input.declarationList.declarations, visitDeclarationSubtree);
const nodes = visitNodes(input.declarationList.declarations, visitDeclarationSubtree, isVariableDeclaration);
if (!length(nodes)) return;
return factory.updateVariableStatement(input, factory.createNodeArray(ensureModifiers(input)), factory.updateVariableDeclarationList(input.declarationList, nodes));
}
@ -1832,7 +1843,7 @@ export function transformDeclarations(context: TransformationContext) {
function transformHeritageClauses(nodes: NodeArray<HeritageClause> | undefined) {
return factory.createNodeArray(filter(map(nodes, clause => factory.updateHeritageClause(clause, visitNodes(factory.createNodeArray(filter(clause.types, t => {
return isEntityNameExpression(t.expression) || (clause.token === SyntaxKind.ExtendsKeyword && t.expression.kind === SyntaxKind.NullKeyword);
})), visitDeclarationSubtree))), clause => clause.types && !!clause.types.length));
})), visitDeclarationSubtree, isExpressionWithTypeArguments))), clause => clause.types && !!clause.types.length));
}
}

Просмотреть файл

@ -2,9 +2,7 @@ import {
__String,
addRange,
append,
ArrayBindingElement,
ArrayBindingOrAssignmentPattern,
BindingElement,
BindingName,
BindingOrAssignmentElement,
BindingOrAssignmentElementTarget,
@ -24,9 +22,11 @@ import {
Identifier,
idText,
isArrayBindingElement,
isArrayBindingOrAssignmentElement,
isArrayBindingOrAssignmentPattern,
isBindingElement,
isBindingName,
isBindingOrAssignmentElement,
isBindingOrAssignmentPattern,
isComputedPropertyName,
isDeclarationBindingElement,
@ -36,6 +36,7 @@ import {
isExpression,
isIdentifier,
isLiteralExpression,
isObjectBindingOrAssignmentElement,
isObjectBindingOrAssignmentPattern,
isOmittedExpression,
isPropertyNameLiteral,
@ -73,7 +74,7 @@ interface FlattenContext {
createArrayBindingOrAssignmentPattern: (elements: BindingOrAssignmentElement[]) => ArrayBindingOrAssignmentPattern;
createObjectBindingOrAssignmentPattern: (elements: BindingOrAssignmentElement[]) => ObjectBindingOrAssignmentPattern;
createArrayBindingOrAssignmentElement: (node: Identifier) => BindingOrAssignmentElement;
visitor?: (node: Node) => VisitResult<Node>;
visitor: (node: Node) => VisitResult<Node | undefined>;
}
/** @internal */
@ -97,7 +98,7 @@ export const enum FlattenLevel {
*/
export function flattenDestructuringAssignment(
node: VariableDeclaration | DestructuringAssignment,
visitor: ((node: Node) => VisitResult<Node>) | undefined,
visitor: ((node: Node) => VisitResult<Node | undefined>),
context: TransformationContext,
level: FlattenLevel,
needsValue?: boolean,
@ -112,7 +113,7 @@ export function flattenDestructuringAssignment(
value = node.right;
}
else {
return visitNode(value, visitor, isExpression);
return Debug.checkDefined(visitNode(value, visitor, isExpression));
}
}
}
@ -133,6 +134,7 @@ export function flattenDestructuringAssignment(
if (value) {
value = visitNode(value, visitor, isExpression);
Debug.assert(value);
if (isIdentifier(value) && bindingOrAssignmentElementAssignsToName(node, value.escapedText) ||
bindingOrAssignmentElementContainsNonLiteralComputedName(node)) {
@ -176,12 +178,12 @@ export function flattenDestructuringAssignment(
expressions = append(expressions, expression);
}
function emitBindingOrAssignment(target: BindingOrAssignmentElementTarget, value: Expression, location: TextRange, original: Node) {
function emitBindingOrAssignment(target: BindingOrAssignmentElementTarget, value: Expression, location: TextRange, original: Node | undefined) {
Debug.assertNode(target, createAssignmentCallback ? isIdentifier : isExpression);
const expression = createAssignmentCallback
? createAssignmentCallback(target as Identifier, value, location)
: setTextRange(
context.factory.createAssignment(visitNode(target as Expression, visitor, isExpression), value),
context.factory.createAssignment(Debug.checkDefined(visitNode(target as Expression, visitor, isExpression)), value),
location
);
expression.original = original;
@ -238,7 +240,7 @@ function bindingOrAssignmentPatternContainsNonLiteralComputedName(pattern: Bindi
*/
export function flattenDestructuringBinding(
node: VariableDeclaration | ParameterDeclaration,
visitor: (node: Node) => VisitResult<Node>,
visitor: (node: Node) => VisitResult<Node | undefined>,
context: TransformationContext,
level: FlattenLevel,
rval?: Expression,
@ -266,7 +268,7 @@ export function flattenDestructuringBinding(
bindingOrAssignmentElementContainsNonLiteralComputedName(node))) {
// If the right-hand value of the assignment is also an assignment target then
// we need to cache the right-hand value.
initializer = ensureIdentifier(flattenContext, visitNode(initializer, flattenContext.visitor), /*reuseIdentifierExpressions*/ false, initializer);
initializer = ensureIdentifier(flattenContext, Debug.checkDefined(visitNode(initializer, flattenContext.visitor, isExpression)), /*reuseIdentifierExpressions*/ false, initializer);
node = context.factory.updateVariableDeclaration(node, node.name, /*exclamationToken*/ undefined, /*type*/ undefined, initializer);
}
}
@ -395,7 +397,7 @@ function flattenObjectBindingOrAssignmentPattern(flattenContext: FlattenContext,
&& !(element.transformFlags & (TransformFlags.ContainsRestOrSpread | TransformFlags.ContainsObjectRestOrSpread))
&& !(getTargetOfBindingOrAssignmentElement(element)!.transformFlags & (TransformFlags.ContainsRestOrSpread | TransformFlags.ContainsObjectRestOrSpread))
&& !isComputedPropertyName(propertyName)) {
bindingElements = append(bindingElements, visitNode(element, flattenContext.visitor));
bindingElements = append(bindingElements, visitNode(element, flattenContext.visitor, isBindingOrAssignmentElement));
}
else {
if (bindingElements) {
@ -542,7 +544,7 @@ function createDefaultValueCheck(flattenContext: FlattenContext, value: Expressi
*/
function createDestructuringPropertyAccess(flattenContext: FlattenContext, value: Expression, propertyName: PropertyName): LeftHandSideExpression {
if (isComputedPropertyName(propertyName)) {
const argumentExpression = ensureIdentifier(flattenContext, visitNode(propertyName.expression, flattenContext.visitor), /*reuseIdentifierExpressions*/ false, /*location*/ propertyName);
const argumentExpression = ensureIdentifier(flattenContext, Debug.checkDefined(visitNode(propertyName.expression, flattenContext.visitor, isExpression)), /*reuseIdentifierExpressions*/ false, /*location*/ propertyName);
return flattenContext.context.factory.createElementAccessExpression(value, argumentExpression);
}
else if (isStringOrNumericLiteralLike(propertyName)) {
@ -585,19 +587,21 @@ function ensureIdentifier(flattenContext: FlattenContext, value: Expression, reu
function makeArrayBindingPattern(factory: NodeFactory, elements: BindingOrAssignmentElement[]) {
Debug.assertEachNode(elements, isArrayBindingElement);
return factory.createArrayBindingPattern(elements as ArrayBindingElement[]);
return factory.createArrayBindingPattern(elements);
}
function makeArrayAssignmentPattern(factory: NodeFactory, elements: BindingOrAssignmentElement[]) {
Debug.assertEachNode(elements, isArrayBindingOrAssignmentElement);
return factory.createArrayLiteralExpression(map(elements, factory.converters.convertToArrayAssignmentElement));
}
function makeObjectBindingPattern(factory: NodeFactory, elements: BindingOrAssignmentElement[]) {
Debug.assertEachNode(elements, isBindingElement);
return factory.createObjectBindingPattern(elements as BindingElement[]);
return factory.createObjectBindingPattern(elements);
}
function makeObjectAssignmentPattern(factory: NodeFactory, elements: BindingOrAssignmentElement[]) {
Debug.assertEachNode(elements, isObjectBindingOrAssignmentElement);
return factory.createObjectLiteralExpression(map(elements, factory.converters.convertToObjectAssignmentElement));
}

Просмотреть файл

@ -46,7 +46,6 @@ import {
filter,
first,
firstOrUndefined,
flatMap,
flatten,
flattenDestructuringAssignment,
flattenDestructuringBinding,
@ -125,6 +124,7 @@ import {
isSuperProperty,
isSwitchStatement,
isTryStatement,
isVariableDeclaration,
isVariableDeclarationList,
isVariableStatement,
isWithStatement,
@ -352,7 +352,7 @@ interface ConvertedLoopState {
loopOutParameters: LoopOutParameter[];
}
type LoopConverter = (node: IterationStatement, outermostLabeledStatement: LabeledStatement | undefined, convertedLoopBodyStatements: Statement[] | undefined, ancestorFacts: HierarchyFacts) => Statement;
type LoopConverter<T extends IterationStatement> = (node: T, outermostLabeledStatement: LabeledStatement | undefined, convertedLoopBodyStatements: Statement[] | undefined, ancestorFacts: HierarchyFacts) => Statement;
// Facts we track as we traverse the tree
const enum HierarchyFacts {
@ -582,15 +582,15 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
|| (getEmitFlags(node) & EmitFlags.TypeScriptClassWrapper) !== 0;
}
function visitor(node: Node): VisitResult<Node> {
function visitor(node: Node): VisitResult<Node | undefined> {
return shouldVisitNode(node) ? visitorWorker(node, /*expressionResultIsUnused*/ false) : node;
}
function visitorWithUnusedExpressionResult(node: Node): VisitResult<Node> {
function visitorWithUnusedExpressionResult(node: Node): VisitResult<Node | undefined> {
return shouldVisitNode(node) ? visitorWorker(node, /*expressionResultIsUnused*/ true) : node;
}
function classWrapperStatementVisitor(node: Node): VisitResult<Node> {
function classWrapperStatementVisitor(node: Node): VisitResult<Node | undefined> {
if (shouldVisitNode(node)) {
const original = getOriginalNode(node);
if (isPropertyDeclaration(original) && hasStaticModifier(original)) {
@ -607,14 +607,14 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
return node;
}
function callExpressionVisitor(node: Node): VisitResult<Node> {
function callExpressionVisitor(node: Node): VisitResult<Node | undefined> {
if (node.kind === SyntaxKind.SuperKeyword) {
return visitSuperKeyword(/*isExpressionOfCall*/ true);
}
return visitor(node);
}
function visitorWorker(node: Node, expressionResultIsUnused: boolean): VisitResult<Node> {
function visitorWorker(node: Node, expressionResultIsUnused: boolean): VisitResult<Node | undefined> {
switch (node.kind) {
case SyntaxKind.StaticKeyword:
return undefined; // elide static keyword
@ -818,7 +818,7 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
factory.createPropertyAssignment(
factory.createIdentifier("value"),
node.expression
? visitNode(node.expression, visitor, isExpression)
? Debug.checkDefined(visitNode(node.expression, visitor, isExpression))
: factory.createVoidZero()
)
]
@ -1057,7 +1057,7 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
outer,
/*typeArguments*/ undefined,
extendsClauseElement
? [visitNode(extendsClauseElement.expression, visitor, isExpression)]
? [Debug.checkDefined(visitNode(extendsClauseElement.expression, visitor, isExpression))]
: []
)
);
@ -1567,7 +1567,7 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
factory.createExpressionStatement(
factory.createAssignment(
factory.getGeneratedNameForNode(parameter),
visitNode(initializer, visitor, isExpression)
Debug.checkDefined(visitNode(initializer, visitor, isExpression))
)
),
EmitFlags.CustomPrologue
@ -1587,7 +1587,7 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
* @param initializer The initializer for the parameter.
*/
function insertDefaultValueAssignmentForInitializer(statements: Statement[], parameter: ParameterDeclaration, name: Identifier, initializer: Expression): void {
initializer = visitNode(initializer, visitor, isExpression);
initializer = Debug.checkDefined(visitNode(initializer, visitor, isExpression));
const statement = factory.createIfStatement(
factory.createTypeCheck(factory.cloneNode(name), "undefined"),
setEmitFlags(
@ -1928,6 +1928,7 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
const sourceMapRange = getSourceMapRange(member);
const memberFunction = transformFunctionLikeToExpression(member, /*location*/ member, /*name*/ undefined, container);
const propertyName = visitNode(member.name, visitor, isPropertyName);
Debug.assert(propertyName);
let e: Expression;
if (!isPrivateIdentifier(propertyName) && getUseDefineForClassFields(context.getCompilerOptions())) {
const name = isComputedPropertyName(propertyName) ? propertyName.expression
@ -1984,6 +1985,7 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
setSourceMapRange(target, firstAccessor.name);
const visitedAccessorName = visitNode(firstAccessor.name, visitor, isPropertyName);
Debug.assert(visitedAccessorName);
if (isPrivateIdentifier(visitedAccessorName)) {
return Debug.failBadSyntaxKind(visitedAccessorName, "Encountered unhandled private identifier while transforming ES2015.");
}
@ -2316,9 +2318,9 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
if (node.operatorToken.kind === SyntaxKind.CommaToken) {
return factory.updateBinaryExpression(
node,
visitNode(node.left, visitorWithUnusedExpressionResult, isExpression),
Debug.checkDefined(visitNode(node.left, visitorWithUnusedExpressionResult, isExpression)),
node.operatorToken,
visitNode(node.right, expressionResultIsUnused ? visitorWithUnusedExpressionResult : visitor, isExpression)
Debug.checkDefined(visitNode(node.right, expressionResultIsUnused ? visitorWithUnusedExpressionResult : visitor, isExpression))
);
}
return visitEachChild(node, visitor, context);
@ -2338,6 +2340,7 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
const visited = visitNode(element, i < node.elements.length - 1 ? visitorWithUnusedExpressionResult : visitor, isExpression);
if (result || visited !== element) {
result ||= node.elements.slice(0, i);
Debug.assert(visited);
result.push(visited);
}
}
@ -2370,7 +2373,7 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
);
}
else {
assignment = factory.createBinaryExpression(decl.name, SyntaxKind.EqualsToken, visitNode(decl.initializer, visitor, isExpression));
assignment = factory.createBinaryExpression(decl.name, SyntaxKind.EqualsToken, Debug.checkDefined(visitNode(decl.initializer, visitor, isExpression)));
setTextRange(assignment, decl);
}
@ -2404,9 +2407,9 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
enableSubstitutionsForBlockScopedBindings();
}
const declarations = flatMap(node.declarations, node.flags & NodeFlags.Let
const declarations = visitNodes(node.declarations, node.flags & NodeFlags.Let
? visitVariableDeclarationInLetDeclarationList
: visitVariableDeclaration);
: visitVariableDeclaration, isVariableDeclaration);
const declarationList = factory.createVariableDeclarationList(declarations);
setOriginalNode(declarationList, node);
@ -2558,14 +2561,14 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
convertedLoopState!.labels!.set(idText(node.label), false);
}
function visitLabeledStatement(node: LabeledStatement): VisitResult<Statement> {
function visitLabeledStatement(node: LabeledStatement): VisitResult<Statement | undefined> {
if (convertedLoopState && !convertedLoopState.labels) {
convertedLoopState.labels = new Map<string, boolean>();
}
const statement = unwrapInnermostStatementOfLabel(node, convertedLoopState && recordLabel);
return isIterationStatement(statement, /*lookInLabeledStatements*/ false)
? visitIterationStatement(statement, /*outermostLabeledStatement*/ node)
: factory.restoreEnclosingLabel(visitNode(statement, visitor, isStatement, factory.liftToBlock), node, convertedLoopState && resetLabel);
: factory.restoreEnclosingLabel(Debug.checkDefined(visitNode(statement, visitor, isStatement, factory.liftToBlock)), node, convertedLoopState && resetLabel);
}
function visitIterationStatement(node: IterationStatement, outermostLabeledStatement: LabeledStatement) {
@ -2582,7 +2585,7 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
}
}
function visitIterationStatementWithFacts(excludeFacts: HierarchyFacts, includeFacts: HierarchyFacts, node: IterationStatement, outermostLabeledStatement: LabeledStatement | undefined, convert?: LoopConverter) {
function visitIterationStatementWithFacts<T extends IterationStatement>(excludeFacts: HierarchyFacts, includeFacts: HierarchyFacts, node: T, outermostLabeledStatement: LabeledStatement | undefined, convert?: LoopConverter<T>) {
const ancestorFacts = enterSubtree(excludeFacts, includeFacts);
const updated = convertIterationStatementBodyIfNecessary(node, outermostLabeledStatement, ancestorFacts, convert);
exitSubtree(ancestorFacts, HierarchyFacts.None, HierarchyFacts.None);
@ -2611,7 +2614,7 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
visitNode(node.initializer, visitorWithUnusedExpressionResult, isForInitializer),
visitNode(node.condition, visitor, isExpression),
visitNode(node.incrementor, visitorWithUnusedExpressionResult, isExpression),
visitNode(node.statement, visitor, isStatement, factory.liftToBlock)
Debug.checkDefined(visitNode(node.statement, visitor, isStatement, factory.liftToBlock))
);
}
@ -2632,7 +2635,7 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
compilerOptions.downlevelIteration ? convertForOfStatementForIterable : convertForOfStatementForArray);
}
function convertForOfStatementHead(node: ForOfStatement, boundValue: Expression, convertedLoopBodyStatements: Statement[]) {
function convertForOfStatementHead(node: ForOfStatement, boundValue: Expression, convertedLoopBodyStatements: Statement[] | undefined) {
const statements: Statement[] = [];
const initializer = node.initializer;
if (isVariableDeclarationList(initializer)) {
@ -2702,7 +2705,7 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
}
else {
setTextRangeEnd(assignment, initializer.end);
statements.push(setTextRange(factory.createExpressionStatement(visitNode(assignment, visitor, isExpression)), moveRangeEnd(initializer, -1)));
statements.push(setTextRange(factory.createExpressionStatement(Debug.checkDefined(visitNode(assignment, visitor, isExpression))), moveRangeEnd(initializer, -1)));
}
}
@ -2711,6 +2714,7 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
}
else {
const statement = visitNode(node.statement, visitor, isStatement, factory.liftToBlock);
Debug.assert(statement);
if (isBlock(statement)) {
return factory.updateBlock(statement, setTextRange(factory.createNodeArray(concatenate(statements, statement.statements)), statement.statements));
}
@ -2731,7 +2735,7 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
);
}
function convertForOfStatementForArray(node: ForOfStatement, outermostLabeledStatement: LabeledStatement, convertedLoopBodyStatements: Statement[]): Statement {
function convertForOfStatementForArray(node: ForOfStatement, outermostLabeledStatement: LabeledStatement | undefined, convertedLoopBodyStatements: Statement[] | undefined): Statement {
// The following ES6 code:
//
// for (let v of expr) { }
@ -2754,6 +2758,7 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
// for-of bodies are always emitted as blocks.
const expression = visitNode(node.expression, visitor, isExpression);
Debug.assert(expression);
// In the case where the user wrote an identifier as the RHS, like this:
//
@ -2801,8 +2806,9 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
return factory.restoreEnclosingLabel(forStatement, outermostLabeledStatement, convertedLoopState && resetLabel);
}
function convertForOfStatementForIterable(node: ForOfStatement, outermostLabeledStatement: LabeledStatement, convertedLoopBodyStatements: Statement[], ancestorFacts: HierarchyFacts): Statement {
function convertForOfStatementForIterable(node: ForOfStatement, outermostLabeledStatement: LabeledStatement | undefined, convertedLoopBodyStatements: Statement[] | undefined, ancestorFacts: HierarchyFacts): Statement {
const expression = visitNode(node.expression, visitor, isExpression);
Debug.assert(expression);
const iterator = isIdentifier(expression) ? factory.getGeneratedNameForNode(expression) : factory.createTempVariable(/*recordTempVariable*/ undefined);
const result = isIdentifier(expression) ? factory.getGeneratedNameForNode(iterator) : factory.createTempVariable(/*recordTempVariable*/ undefined);
const errorRecord = factory.createUniqueName("e");
@ -3029,7 +3035,7 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
}
}
function convertIterationStatementBodyIfNecessary(node: IterationStatement, outermostLabeledStatement: LabeledStatement | undefined, ancestorFacts: HierarchyFacts, convert?: LoopConverter): VisitResult<Statement> {
function convertIterationStatementBodyIfNecessary<T extends IterationStatement>(node: T, outermostLabeledStatement: LabeledStatement | undefined, ancestorFacts: HierarchyFacts, convert?: LoopConverter<T>): VisitResult<Statement> {
if (!shouldConvertIterationStatement(node)) {
let saveAllowedNonLabeledJumps: Jump | undefined;
if (convertedLoopState) {
@ -3083,7 +3089,7 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
}
}
else {
const clone = convertIterationStatementCore(node, initializerFunction, visitNode(node.statement, visitor, isStatement, factory.liftToBlock));
const clone = convertIterationStatementCore(node, initializerFunction, Debug.checkDefined(visitNode(node.statement, visitor, isStatement, factory.liftToBlock)));
loop = factory.restoreEnclosingLabel(clone, outermostLabeledStatement, convertedLoopState && resetLabel);
}
@ -3118,16 +3124,16 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
return factory.updateForOfStatement(
node,
/*awaitModifier*/ undefined,
visitNode(node.initializer, visitor, isForInitializer),
visitNode(node.expression, visitor, isExpression),
Debug.checkDefined(visitNode(node.initializer, visitor, isForInitializer)),
Debug.checkDefined(visitNode(node.expression, visitor, isExpression)),
convertedLoopBody);
}
function convertForInStatement(node: ForInStatement, convertedLoopBody: Statement) {
return factory.updateForInStatement(
node,
visitNode(node.initializer, visitor, isForInitializer),
visitNode(node.expression, visitor, isExpression),
Debug.checkDefined(visitNode(node.initializer, visitor, isForInitializer)),
Debug.checkDefined(visitNode(node.expression, visitor, isExpression)),
convertedLoopBody);
}
@ -3135,13 +3141,13 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
return factory.updateDoStatement(
node,
convertedLoopBody,
visitNode(node.expression, visitor, isExpression));
Debug.checkDefined(visitNode(node.expression, visitor, isExpression)));
}
function convertWhileStatement(node: WhileStatement, convertedLoopBody: Statement) {
return factory.updateWhileStatement(
node,
visitNode(node.expression, visitor, isExpression),
Debug.checkDefined(visitNode(node.expression, visitor, isExpression)),
convertedLoopBody);
}
@ -3347,11 +3353,11 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
/*typeParameters*/ undefined,
/*parameters*/ undefined,
/*type*/ undefined,
visitNode(
Debug.checkDefined(visitNode(
factory.createBlock(statements, /*multiLine*/ true),
visitor,
isBlock
)
))
),
emitFlags
)
@ -3421,7 +3427,7 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
if (node.incrementor) {
statements.push(factory.createIfStatement(
currentState.conditionVariable,
factory.createExpressionStatement(visitNode(node.incrementor, visitor, isExpression)),
factory.createExpressionStatement(Debug.checkDefined(visitNode(node.incrementor, visitor, isExpression))),
factory.createExpressionStatement(factory.createAssignment(currentState.conditionVariable, factory.createTrue()))
));
}
@ -3434,12 +3440,13 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
if (shouldConvertConditionOfForStatement(node)) {
statements.push(factory.createIfStatement(
factory.createPrefixUnaryExpression(SyntaxKind.ExclamationToken, visitNode(node.condition, visitor, isExpression)),
visitNode(factory.createBreakStatement(), visitor, isStatement)
factory.createPrefixUnaryExpression(SyntaxKind.ExclamationToken, Debug.checkDefined(visitNode(node.condition, visitor, isExpression))),
Debug.checkDefined(visitNode(factory.createBreakStatement(), visitor, isStatement))
));
}
}
Debug.assert(statement);
if (isBlock(statement)) {
addRange(statements, statement.statements);
}
@ -3732,9 +3739,9 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
createMemberAccessForPropertyName(
factory,
receiver,
visitNode(property.name, visitor, isPropertyName)
Debug.checkDefined(visitNode(property.name, visitor, isPropertyName))
),
visitNode(property.initializer, visitor, isExpression)
Debug.checkDefined(visitNode(property.initializer, visitor, isExpression))
);
setTextRange(expression, property);
if (startsOnNewLine) {
@ -3755,7 +3762,7 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
createMemberAccessForPropertyName(
factory,
receiver,
visitNode(property.name, visitor, isPropertyName)
Debug.checkDefined(visitNode(property.name, visitor, isPropertyName))
),
factory.cloneNode(property.name)
);
@ -3778,7 +3785,7 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
createMemberAccessForPropertyName(
factory,
receiver,
visitNode(method.name, visitor, isPropertyName)
Debug.checkDefined(visitNode(method.name, visitor, isPropertyName))
),
transformFunctionLikeToExpression(method, /*location*/ method, /*name*/ undefined, container)
);
@ -3929,7 +3936,7 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
return factory.updateCallExpression(
node,
visitNode(node.expression, callExpressionVisitor, isExpression),
Debug.checkDefined(visitNode(node.expression, callExpressionVisitor, isExpression)),
/*typeArguments*/ undefined,
visitNodes(node.arguments, visitor, isExpression)
);
@ -4127,8 +4134,8 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
// _super.prototype.m.apply(this, a.concat([b]))
resultingCall = factory.createFunctionApplyCall(
visitNode(target, callExpressionVisitor, isExpression),
node.expression.kind === SyntaxKind.SuperKeyword ? thisArg : visitNode(thisArg, visitor, isExpression),
Debug.checkDefined(visitNode(target, callExpressionVisitor, isExpression)),
node.expression.kind === SyntaxKind.SuperKeyword ? thisArg : Debug.checkDefined(visitNode(thisArg, visitor, isExpression)),
transformAndSpreadElements(node.arguments, /*isArgumentList*/ true, /*multiLine*/ false, /*hasTrailingComma*/ false)
);
}
@ -4144,8 +4151,8 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
// _super.prototype.m.call(this, a)
resultingCall = setTextRange(
factory.createFunctionCallCall(
visitNode(target, callExpressionVisitor, isExpression),
node.expression.kind === SyntaxKind.SuperKeyword ? thisArg : visitNode(thisArg, visitor, isExpression),
Debug.checkDefined(visitNode(target, callExpressionVisitor, isExpression)),
node.expression.kind === SyntaxKind.SuperKeyword ? thisArg : Debug.checkDefined(visitNode(thisArg, visitor, isExpression)),
visitNodes(node.arguments, visitor, isExpression)
),
node
@ -4185,7 +4192,7 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
const { target, thisArg } = factory.createCallBinding(factory.createPropertyAccessExpression(node.expression, "bind"), hoistVariableDeclaration);
return factory.createNewExpression(
factory.createFunctionApplyCall(
visitNode(target, visitor, isExpression),
Debug.checkDefined(visitNode(target, visitor, isExpression)),
thisArg,
transformAndSpreadElements(factory.createNodeArray([factory.createVoidZero(), ...node.arguments!]), /*isArgumentList*/ true, /*multiLine*/ false, /*hasTrailingComma*/ false)
),
@ -4288,8 +4295,10 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
return map(chunk, visitExpressionOfSpread);
}
function visitExpressionOfSpread(node: SpreadElement): SpreadSegment {
function visitExpressionOfSpread(node: Expression): SpreadSegment {
Debug.assertNode(node, isSpreadElement);
let expression = visitNode(node.expression, visitor, isExpression);
Debug.assert(expression);
// We don't need to pack already packed array literals, or existing calls to the `__read` helper.
const isCallToReadHelper = isCallToHelper(expression, "___read" as __String);
@ -4376,7 +4385,7 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
function visitTemplateExpression(node: TemplateExpression): Expression {
let expression: Expression = factory.createStringLiteral(node.head.text);
for (const span of node.templateSpans) {
const args = [visitNode(span.expression, visitor, isExpression)];
const args = [Debug.checkDefined(visitNode(span.expression, visitor, isExpression))];
if (span.literal.text.length > 0) {
args.push(factory.createStringLiteral(span.literal.text));

Просмотреть файл

@ -42,6 +42,7 @@ import {
getNodeId,
getOriginalNode,
insertStatementsAfterStandardPrologue,
isAwaitKeyword,
isBlock,
isConciseBody,
isEffectiveStrictModeSourceFile,
@ -51,13 +52,13 @@ import {
isFunctionLike,
isFunctionLikeDeclaration,
isIdentifier,
isModifier,
isModifierLike,
isNodeWithPossibleHoistedDeclaration,
isOmittedExpression,
isPropertyAccessExpression,
isStatement,
isSuperProperty,
isToken,
isVariableDeclarationList,
LeftHandSideExpression,
map,
@ -202,7 +203,7 @@ export function transformES2017(context: TransformationContext): (x: SourceFile
return visitEachChild(node, visitor, context);
}
function visitor(node: Node): VisitResult<Node> {
function visitor(node: Node): VisitResult<Node | undefined> {
if ((node.transformFlags & TransformFlags.ContainsES2017) === 0) {
return node;
}
@ -253,7 +254,7 @@ export function transformES2017(context: TransformationContext): (x: SourceFile
}
}
function asyncBodyVisitor(node: Node): VisitResult<Node> {
function asyncBodyVisitor(node: Node): VisitResult<Node | undefined> {
if (isNodeWithPossibleHoistedDeclaration(node)) {
switch (node.kind) {
case SyntaxKind.VariableStatement:
@ -325,8 +326,8 @@ export function transformES2017(context: TransformationContext): (x: SourceFile
node,
isVariableDeclarationListWithCollidingName(node.initializer)
? visitVariableDeclarationListWithCollidingNames(node.initializer, /*hasReceiver*/ true)!
: visitNode(node.initializer, visitor, isForInitializer),
visitNode(node.expression, visitor, isExpression),
: Debug.checkDefined(visitNode(node.initializer, visitor, isForInitializer)),
Debug.checkDefined(visitNode(node.expression, visitor, isExpression)),
visitIterationBody(node.statement, asyncBodyVisitor, context)
);
}
@ -334,11 +335,11 @@ export function transformES2017(context: TransformationContext): (x: SourceFile
function visitForOfStatementInAsyncBody(node: ForOfStatement) {
return factory.updateForOfStatement(
node,
visitNode(node.awaitModifier, visitor, isToken),
visitNode(node.awaitModifier, visitor, isAwaitKeyword),
isVariableDeclarationListWithCollidingName(node.initializer)
? visitVariableDeclarationListWithCollidingNames(node.initializer, /*hasReceiver*/ true)!
: visitNode(node.initializer, visitor, isForInitializer),
visitNode(node.expression, visitor, isExpression),
: Debug.checkDefined(visitNode(node.initializer, visitor, isForInitializer)),
Debug.checkDefined(visitNode(node.expression, visitor, isExpression)),
visitIterationBody(node.statement, asyncBodyVisitor, context)
);
}
@ -383,7 +384,7 @@ export function transformES2017(context: TransformationContext): (x: SourceFile
function visitConstructorDeclaration(node: ConstructorDeclaration) {
return factory.updateConstructorDeclaration(
node,
visitNodes(node.modifiers, visitor, isModifierLike),
visitNodes(node.modifiers, visitor, isModifier),
visitParameterList(node.parameters, visitor, context),
transformMethodBody(node)
);
@ -468,7 +469,7 @@ export function transformES2017(context: TransformationContext): (x: SourceFile
function visitFunctionExpression(node: FunctionExpression): Expression {
return factory.updateFunctionExpression(
node,
visitNodes(node.modifiers, visitor, isModifierLike),
visitNodes(node.modifiers, visitor, isModifier),
node.asteriskToken,
node.name,
/*typeParameters*/ undefined,
@ -491,7 +492,7 @@ export function transformES2017(context: TransformationContext): (x: SourceFile
function visitArrowFunction(node: ArrowFunction) {
return factory.updateArrowFunction(
node,
visitNodes(node.modifiers, visitor, isModifierLike),
visitNodes(node.modifiers, visitor, isModifier),
/*typeParameters*/ undefined,
visitParameterList(node.parameters, visitor, context),
/*type*/ undefined,
@ -561,7 +562,7 @@ export function transformES2017(context: TransformationContext): (x: SourceFile
),
node
);
return visitNode(converted, visitor, isExpression);
return Debug.checkDefined(visitNode(converted, visitor, isExpression));
}
function collidesWithParameterName({ name }: VariableDeclaration | BindingElement): boolean {
@ -728,7 +729,7 @@ export function transformES2017(context: TransformationContext): (x: SourceFile
return factory.updateBlock(body, visitNodes(body.statements, asyncBodyVisitor, isStatement, start));
}
else {
return factory.converters.convertToFunctionBlock(visitNode(body, asyncBodyVisitor, isConciseBody));
return factory.converters.convertToFunctionBlock(Debug.checkDefined(visitNode(body, asyncBodyVisitor, isConciseBody)));
}
}

Просмотреть файл

@ -61,9 +61,9 @@ import {
isParameter,
isPropertyAccessExpression,
isPropertyName,
isQuestionToken,
isStatement,
isSuperProperty,
isToken,
isVariableDeclarationList,
LabeledStatement,
LeftHandSideExpression,
@ -95,7 +95,6 @@ import {
SyntaxKind,
TaggedTemplateExpression,
TextRange,
Token,
TransformationContext,
TransformFlags,
unwrapInnermostStatementOfLabel,
@ -240,7 +239,7 @@ export function transformES2018(context: TransformationContext): (x: SourceFile
return visitorWorker(node, /*expressionResultIsUnused*/ true);
}
function visitorNoAsyncModifier(node: Node): VisitResult<Node> {
function visitorNoAsyncModifier(node: Node): VisitResult<Node | undefined> {
if (node.kind === SyntaxKind.AsyncKeyword) {
return undefined;
}
@ -1041,7 +1040,7 @@ export function transformES2018(context: TransformationContext): (x: SourceFile
? undefined
: node.asteriskToken,
visitNode(node.name, visitor, isPropertyName),
visitNode<Token<SyntaxKind.QuestionToken>>(/*questionToken*/ undefined, visitor, isToken),
visitNode(/*questionToken*/ undefined, visitor, isQuestionToken),
/*typeParameters*/ undefined,
visitParameterList(node.parameters, parameterVisitor, context),
/*type*/ undefined,

Просмотреть файл

@ -408,7 +408,7 @@ export function transformGenerators(context: TransformationContext): (x: SourceF
*
* @param node The node to visit.
*/
function visitor(node: Node): VisitResult<Node> {
function visitor(node: Node): VisitResult<Node | undefined> {
const transformFlags = node.transformFlags;
if (inStatementContainingYield) {
return visitJavaScriptInStatementContainingYield(node);
@ -432,7 +432,7 @@ export function transformGenerators(context: TransformationContext): (x: SourceF
*
* @param node The node to visit.
*/
function visitJavaScriptInStatementContainingYield(node: Node): VisitResult<Node> {
function visitJavaScriptInStatementContainingYield(node: Node): VisitResult<Node | undefined> {
switch (node.kind) {
case SyntaxKind.DoStatement:
return visitDoStatement(node as DoStatement);
@ -452,7 +452,7 @@ export function transformGenerators(context: TransformationContext): (x: SourceF
*
* @param node The node to visit.
*/
function visitJavaScriptInGeneratorFunctionBody(node: Node): VisitResult<Node> {
function visitJavaScriptInGeneratorFunctionBody(node: Node): VisitResult<Node | undefined> {
switch (node.kind) {
case SyntaxKind.FunctionDeclaration:
return visitFunctionDeclaration(node as FunctionDeclaration);
@ -521,7 +521,7 @@ export function transformGenerators(context: TransformationContext): (x: SourceF
*
* @param node The node to visit.
*/
function visitGenerator(node: Node): VisitResult<Node> {
function visitGenerator(node: Node): VisitResult<Node | undefined> {
switch (node.kind) {
case SyntaxKind.FunctionDeclaration:
return visitFunctionDeclaration(node as FunctionDeclaration);
@ -791,7 +791,7 @@ export function transformGenerators(context: TransformationContext): (x: SourceF
target = factory.updatePropertyAccessExpression(
left as PropertyAccessExpression,
cacheExpression(visitNode((left as PropertyAccessExpression).expression, visitor, isLeftHandSideExpression)),
cacheExpression(Debug.checkDefined(visitNode((left as PropertyAccessExpression).expression, visitor, isLeftHandSideExpression))),
(left as PropertyAccessExpression).name
);
break;
@ -809,13 +809,13 @@ export function transformGenerators(context: TransformationContext): (x: SourceF
// _a[_b] = %sent%;
target = factory.updateElementAccessExpression(left as ElementAccessExpression,
cacheExpression(visitNode((left as ElementAccessExpression).expression, visitor, isLeftHandSideExpression)),
cacheExpression(visitNode((left as ElementAccessExpression).argumentExpression, visitor, isExpression))
cacheExpression(Debug.checkDefined(visitNode((left as ElementAccessExpression).expression, visitor, isLeftHandSideExpression))),
cacheExpression(Debug.checkDefined(visitNode((left as ElementAccessExpression).argumentExpression, visitor, isExpression)))
);
break;
default:
target = visitNode(left, visitor, isExpression);
target = Debug.checkDefined(visitNode(left, visitor, isExpression));
break;
}
@ -828,7 +828,7 @@ export function transformGenerators(context: TransformationContext): (x: SourceF
factory.createBinaryExpression(
cacheExpression(target),
getNonAssignmentOperatorForCompoundAssignment(operator),
visitNode(right, visitor, isExpression)
Debug.checkDefined(visitNode(right, visitor, isExpression))
),
node
)
@ -837,7 +837,7 @@ export function transformGenerators(context: TransformationContext): (x: SourceF
);
}
else {
return factory.updateBinaryExpression(node, target, node.operatorToken, visitNode(right, visitor, isExpression));
return factory.updateBinaryExpression(node, target, node.operatorToken, Debug.checkDefined(visitNode(right, visitor, isExpression)));
}
}
@ -863,9 +863,9 @@ export function transformGenerators(context: TransformationContext): (x: SourceF
// _a + %sent% + c()
return factory.updateBinaryExpression(node,
cacheExpression(visitNode(node.left, visitor, isExpression)),
cacheExpression(Debug.checkDefined(visitNode(node.left, visitor, isExpression))),
node.operatorToken,
visitNode(node.right, visitor, isExpression));
Debug.checkDefined(visitNode(node.right, visitor, isExpression)));
}
return visitEachChild(node, visitor, context);
@ -902,7 +902,7 @@ export function transformGenerators(context: TransformationContext): (x: SourceF
pendingExpressions = [];
}
pendingExpressions.push(visitNode(node, visitor, isExpression));
pendingExpressions.push(Debug.checkDefined(visitNode(node, visitor, isExpression)));
}
}
}
@ -924,7 +924,7 @@ export function transformGenerators(context: TransformationContext): (x: SourceF
emitWorker(OpCode.Statement, [factory.createExpressionStatement(factory.inlineExpressions(pendingExpressions))]);
pendingExpressions = [];
}
pendingExpressions.push(visitNode(elem, visitor, isExpression));
pendingExpressions.push(Debug.checkDefined(visitNode(elem, visitor, isExpression)));
}
}
return factory.inlineExpressions(pendingExpressions);
@ -968,7 +968,7 @@ export function transformGenerators(context: TransformationContext): (x: SourceF
const resultLabel = defineLabel();
const resultLocal = declareLocal();
emitAssignment(resultLocal, visitNode(node.left, visitor, isExpression), /*location*/ node.left);
emitAssignment(resultLocal, Debug.checkDefined(visitNode(node.left, visitor, isExpression)), /*location*/ node.left);
if (node.operatorToken.kind === SyntaxKind.AmpersandAmpersandToken) {
// Logical `&&` shortcuts when the left-hand operand is falsey.
emitBreakWhenFalse(resultLabel, resultLocal, /*location*/ node.left);
@ -978,7 +978,7 @@ export function transformGenerators(context: TransformationContext): (x: SourceF
emitBreakWhenTrue(resultLabel, resultLocal, /*location*/ node.left);
}
emitAssignment(resultLocal, visitNode(node.right, visitor, isExpression), /*location*/ node.right);
emitAssignment(resultLocal, Debug.checkDefined(visitNode(node.right, visitor, isExpression)), /*location*/ node.right);
markLabel(resultLabel);
return resultLocal;
}
@ -1011,11 +1011,11 @@ export function transformGenerators(context: TransformationContext): (x: SourceF
const whenFalseLabel = defineLabel();
const resultLabel = defineLabel();
const resultLocal = declareLocal();
emitBreakWhenFalse(whenFalseLabel, visitNode(node.condition, visitor, isExpression), /*location*/ node.condition);
emitAssignment(resultLocal, visitNode(node.whenTrue, visitor, isExpression), /*location*/ node.whenTrue);
emitBreakWhenFalse(whenFalseLabel, Debug.checkDefined(visitNode(node.condition, visitor, isExpression)), /*location*/ node.condition);
emitAssignment(resultLocal, Debug.checkDefined(visitNode(node.whenTrue, visitor, isExpression)), /*location*/ node.whenTrue);
emitBreak(resultLabel);
markLabel(whenFalseLabel);
emitAssignment(resultLocal, visitNode(node.whenFalse, visitor, isExpression), /*location*/ node.whenFalse);
emitAssignment(resultLocal, Debug.checkDefined(visitNode(node.whenFalse, visitor, isExpression)), /*location*/ node.whenFalse);
markLabel(resultLabel);
return resultLocal;
}
@ -1128,7 +1128,7 @@ export function transformGenerators(context: TransformationContext): (x: SourceF
expressions = [];
}
expressions.push(visitNode(element, visitor, isExpression));
expressions.push(Debug.checkDefined(visitNode(element, visitor, isExpression)));
return expressions;
}
}
@ -1205,8 +1205,8 @@ export function transformGenerators(context: TransformationContext): (x: SourceF
// a = _a[%sent%]
return factory.updateElementAccessExpression(node,
cacheExpression(visitNode(node.expression, visitor, isLeftHandSideExpression)),
visitNode(node.argumentExpression, visitor, isExpression));
cacheExpression(Debug.checkDefined(visitNode(node.expression, visitor, isLeftHandSideExpression))),
Debug.checkDefined(visitNode(node.argumentExpression, visitor, isExpression)));
}
return visitEachChild(node, visitor, context);
@ -1228,7 +1228,7 @@ export function transformGenerators(context: TransformationContext): (x: SourceF
return setOriginalNode(
setTextRange(
factory.createFunctionApplyCall(
cacheExpression(visitNode(target, visitor, isLeftHandSideExpression)),
cacheExpression(Debug.checkDefined(visitNode(target, visitor, isLeftHandSideExpression))),
thisArg,
visitElements(node.arguments)
),
@ -1259,7 +1259,7 @@ export function transformGenerators(context: TransformationContext): (x: SourceF
setTextRange(
factory.createNewExpression(
factory.createFunctionApplyCall(
cacheExpression(visitNode(target, visitor, isExpression)),
cacheExpression(Debug.checkDefined(visitNode(target, visitor, isExpression))),
thisArg,
visitElements(
node.arguments!,
@ -1388,7 +1388,7 @@ export function transformGenerators(context: TransformationContext): (x: SourceF
return setSourceMapRange(
factory.createAssignment(
setSourceMapRange(factory.cloneNode(node.name) as Identifier, node.name),
visitNode(node.initializer, visitor, isExpression)
Debug.checkDefined(visitNode(node.initializer, visitor, isExpression))
),
node
);
@ -1413,7 +1413,7 @@ export function transformGenerators(context: TransformationContext): (x: SourceF
if (containsYield(node.thenStatement) || containsYield(node.elseStatement)) {
const endLabel = defineLabel();
const elseLabel = node.elseStatement ? defineLabel() : undefined;
emitBreakWhenFalse(node.elseStatement ? elseLabel! : endLabel, visitNode(node.expression, visitor, isExpression), /*location*/ node.expression);
emitBreakWhenFalse(node.elseStatement ? elseLabel! : endLabel, Debug.checkDefined(visitNode(node.expression, visitor, isExpression)), /*location*/ node.expression);
transformAndEmitEmbeddedStatement(node.thenStatement);
if (node.elseStatement) {
emitBreak(endLabel);
@ -1454,7 +1454,7 @@ export function transformGenerators(context: TransformationContext): (x: SourceF
markLabel(loopLabel);
transformAndEmitEmbeddedStatement(node.statement);
markLabel(conditionLabel);
emitBreakWhenTrue(loopLabel, visitNode(node.expression, visitor, isExpression));
emitBreakWhenTrue(loopLabel, Debug.checkDefined(visitNode(node.expression, visitor, isExpression)));
endLoopBlock();
}
else {
@ -1493,7 +1493,7 @@ export function transformGenerators(context: TransformationContext): (x: SourceF
const loopLabel = defineLabel();
const endLabel = beginLoopBlock(loopLabel);
markLabel(loopLabel);
emitBreakWhenFalse(endLabel, visitNode(node.expression, visitor, isExpression));
emitBreakWhenFalse(endLabel, Debug.checkDefined(visitNode(node.expression, visitor, isExpression)));
transformAndEmitEmbeddedStatement(node.statement);
emitBreak(loopLabel);
endLoopBlock();
@ -1547,7 +1547,7 @@ export function transformGenerators(context: TransformationContext): (x: SourceF
emitStatement(
setTextRange(
factory.createExpressionStatement(
visitNode(initializer, visitor, isExpression)
Debug.checkDefined(visitNode(initializer, visitor, isExpression))
),
initializer
)
@ -1557,7 +1557,7 @@ export function transformGenerators(context: TransformationContext): (x: SourceF
markLabel(conditionLabel);
if (node.condition) {
emitBreakWhenFalse(endLabel, visitNode(node.condition, visitor, isExpression));
emitBreakWhenFalse(endLabel, Debug.checkDefined(visitNode(node.condition, visitor, isExpression)));
}
transformAndEmitEmbeddedStatement(node.statement);
@ -1567,7 +1567,7 @@ export function transformGenerators(context: TransformationContext): (x: SourceF
emitStatement(
setTextRange(
factory.createExpressionStatement(
visitNode(node.incrementor, visitor, isExpression)
Debug.checkDefined(visitNode(node.incrementor, visitor, isExpression))
),
node.incrementor
)
@ -1645,7 +1645,7 @@ export function transformGenerators(context: TransformationContext): (x: SourceF
const keysIndex = factory.createLoopVariable(); // _i
const initializer = node.initializer;
hoistVariableDeclaration(keysIndex);
emitAssignment(obj, visitNode(node.expression, visitor, isExpression));
emitAssignment(obj, Debug.checkDefined(visitNode(node.expression, visitor, isExpression)));
emitAssignment(keysArray, factory.createArrayLiteralExpression());
emitStatement(
@ -1683,7 +1683,7 @@ export function transformGenerators(context: TransformationContext): (x: SourceF
variable = factory.cloneNode(initializer.declarations[0].name) as Identifier;
}
else {
variable = visitNode(initializer, visitor, isExpression);
variable = Debug.checkDefined(visitNode(initializer, visitor, isExpression));
Debug.assert(isLeftHandSideExpression(variable));
}
@ -1727,8 +1727,8 @@ export function transformGenerators(context: TransformationContext): (x: SourceF
node = factory.updateForInStatement(node,
initializer.declarations[0].name as Identifier,
visitNode(node.expression, visitor, isExpression),
visitNode(node.statement, visitor, isStatement, factory.liftToBlock)
Debug.checkDefined(visitNode(node.expression, visitor, isExpression)),
Debug.checkDefined(visitNode(node.statement, visitor, isStatement, factory.liftToBlock))
);
}
else {
@ -1811,7 +1811,7 @@ export function transformGenerators(context: TransformationContext): (x: SourceF
// .with (x)
// /*body*/
// .endwith
beginWithBlock(cacheExpression(visitNode(node.expression, visitor, isExpression)));
beginWithBlock(cacheExpression(Debug.checkDefined(visitNode(node.expression, visitor, isExpression))));
transformAndEmitEmbeddedStatement(node.statement);
endWithBlock();
}
@ -1858,7 +1858,7 @@ export function transformGenerators(context: TransformationContext): (x: SourceF
const numClauses = caseBlock.clauses.length;
const endLabel = beginSwitchBlock();
const expression = cacheExpression(visitNode(node.expression, visitor, isExpression));
const expression = cacheExpression(Debug.checkDefined(visitNode(node.expression, visitor, isExpression)));
// Create labels for each clause and find the index of the first default clause.
const clauseLabels: Label[] = [];
@ -1887,7 +1887,7 @@ export function transformGenerators(context: TransformationContext): (x: SourceF
pendingClauses.push(
factory.createCaseClause(
visitNode(clause.expression, visitor, isExpression),
Debug.checkDefined(visitNode(clause.expression, visitor, isExpression)),
[
createInlineBreak(clauseLabels[i], /*location*/ clause.expression)
]
@ -1981,7 +1981,7 @@ export function transformGenerators(context: TransformationContext): (x: SourceF
function transformAndEmitThrowStatement(node: ThrowStatement): void {
// TODO(rbuckton): `expression` should be required on `throw`.
emitThrow(
visitNode(node.expression ?? factory.createVoidZero(), visitor, isExpression),
Debug.checkDefined(visitNode(node.expression ?? factory.createVoidZero(), visitor, isExpression)),
/*location*/ node
);
}
@ -2614,7 +2614,7 @@ export function transformGenerators(context: TransformationContext): (x: SourceF
*
* @param node A statement.
*/
function emitStatement(node: Statement): void {
function emitStatement(node: Statement | undefined): void {
if (node) {
emitWorker(OpCode.Statement, [node]);
}

Просмотреть файл

@ -193,7 +193,7 @@ export function transformJsx(context: TransformationContext): (x: SourceFile | B
return visited;
}
function visitor(node: Node): VisitResult<Node> {
function visitor(node: Node): VisitResult<Node | undefined> {
if (node.transformFlags & TransformFlags.ContainsJsx) {
return visitorWorker(node);
}
@ -202,7 +202,7 @@ export function transformJsx(context: TransformationContext): (x: SourceFile | B
}
}
function visitorWorker(node: Node): VisitResult<Node> {
function visitorWorker(node: Node): VisitResult<Node | undefined> {
switch (node.kind) {
case SyntaxKind.JsxElement:
return visitJsxElement(node as JsxElement, /*isChild*/ false);
@ -428,7 +428,7 @@ export function transformJsx(context: TransformationContext): (x: SourceFile | B
}
function transformJsxSpreadAttributeToSpreadAssignment(node: JsxSpreadAttribute) {
return factory.createSpreadAssignment(visitNode(node.expression, visitor, isExpression));
return factory.createSpreadAssignment(Debug.checkDefined(visitNode(node.expression, visitor, isExpression)));
}
function transformJsxAttributesToObjectProps(attrs: readonly(JsxSpreadAttribute | JsxAttribute)[], children?: PropertyAssignment) {
@ -451,8 +451,8 @@ export function transformJsx(context: TransformationContext): (x: SourceFile | B
// of JsxSpreadAttribute nodes into expressions.
const expressions = flatten(
spanMap(attrs, isJsxSpreadAttribute, (attrs, isSpread) => isSpread
? map(attrs, transformJsxSpreadAttributeToExpression)
: factory.createObjectLiteralExpression(map(attrs, transformJsxAttributeToObjectLiteralElement))
? map(attrs as JsxSpreadAttribute[], transformJsxSpreadAttributeToExpression)
: factory.createObjectLiteralExpression(map(attrs as JsxAttribute[], transformJsxAttributeToObjectLiteralElement))
)
);
@ -470,7 +470,7 @@ export function transformJsx(context: TransformationContext): (x: SourceFile | B
}
function transformJsxSpreadAttributeToExpression(node: JsxSpreadAttribute) {
return visitNode(node.expression, visitor, isExpression);
return Debug.checkDefined(visitNode(node.expression, visitor, isExpression));
}
function transformJsxAttributeToObjectLiteralElement(node: JsxAttribute) {
@ -494,7 +494,7 @@ export function transformJsx(context: TransformationContext): (x: SourceFile | B
if (node.expression === undefined) {
return factory.createTrue();
}
return visitNode(node.expression, visitor, isExpression);
return Debug.checkDefined(visitNode(node.expression, visitor, isExpression));
}
if (isJsxElement(node)) {
return visitJsxElement(node, /*isChild*/ false);

Просмотреть файл

@ -13,6 +13,7 @@ import {
ClassLikeDeclaration,
classOrConstructorParameterIsDecorated,
ConstructorDeclaration,
Debug,
Decorator,
elideNodes,
EmitFlags,
@ -42,7 +43,7 @@ import {
isHeritageClause,
isIdentifier,
isModifier,
isParameterDeclaration,
isParameter,
isPrivateIdentifier,
isPropertyDeclaration,
isPropertyName,
@ -111,11 +112,11 @@ export function transformLegacyDecorators(context: TransformationContext): (x: S
return visited;
}
function modifierVisitor(node: Node): VisitResult<Node> {
function modifierVisitor(node: Node): VisitResult<Node | undefined> {
return isDecorator(node) ? undefined : node;
}
function visitor(node: Node): VisitResult<Node> {
function visitor(node: Node): VisitResult<Node | undefined> {
if (!(node.transformFlags & TransformFlags.ContainsDecorators)) {
return node;
}
@ -383,7 +384,7 @@ export function transformLegacyDecorators(context: TransformationContext): (x: S
return factory.updateConstructorDeclaration(
node,
visitNodes(node.modifiers, modifierVisitor, isModifier),
visitNodes(node.parameters, visitor, isParameterDeclaration),
visitNodes(node.parameters, visitor, isParameter),
visitNode(node.body, visitor, isBlock));
}
@ -402,10 +403,10 @@ export function transformLegacyDecorators(context: TransformationContext): (x: S
node,
visitNodes(node.modifiers, modifierVisitor, isModifier),
node.asteriskToken,
visitNode(node.name, visitor, isPropertyName),
Debug.checkDefined(visitNode(node.name, visitor, isPropertyName)),
/*questionToken*/ undefined,
/*typeParameters*/ undefined,
visitNodes(node.parameters, visitor, isParameterDeclaration),
visitNodes(node.parameters, visitor, isParameter),
/*type*/ undefined,
visitNode(node.body, visitor, isBlock)
), node);
@ -415,8 +416,8 @@ export function transformLegacyDecorators(context: TransformationContext): (x: S
return finishClassElement(factory.updateGetAccessorDeclaration(
node,
visitNodes(node.modifiers, modifierVisitor, isModifier),
visitNode(node.name, visitor, isPropertyName),
visitNodes(node.parameters, visitor, isParameterDeclaration),
Debug.checkDefined(visitNode(node.name, visitor, isPropertyName)),
visitNodes(node.parameters, visitor, isParameter),
/*type*/ undefined,
visitNode(node.body, visitor, isBlock)
), node);
@ -426,8 +427,8 @@ export function transformLegacyDecorators(context: TransformationContext): (x: S
return finishClassElement(factory.updateSetAccessorDeclaration(
node,
visitNodes(node.modifiers, modifierVisitor, isModifier),
visitNode(node.name, visitor, isPropertyName),
visitNodes(node.parameters, visitor, isParameterDeclaration),
Debug.checkDefined(visitNode(node.name, visitor, isPropertyName)),
visitNodes(node.parameters, visitor, isParameter),
visitNode(node.body, visitor, isBlock)
), node);
}
@ -440,7 +441,7 @@ export function transformLegacyDecorators(context: TransformationContext): (x: S
return finishClassElement(factory.updatePropertyDeclaration(
node,
visitNodes(node.modifiers, modifierVisitor, isModifier),
visitNode(node.name, visitor, isPropertyName),
Debug.checkDefined(visitNode(node.name, visitor, isPropertyName)),
/*questionOrExclamationToken*/ undefined,
/*type*/ undefined,
visitNode(node.initializer, visitor, isExpression)
@ -452,7 +453,7 @@ export function transformLegacyDecorators(context: TransformationContext): (x: S
node,
elideNodes(factory, node.modifiers),
node.dotDotDotToken,
visitNode(node.name, visitor, isBindingName),
Debug.checkDefined(visitNode(node.name, visitor, isBindingName)),
/*questionToken*/ undefined,
/*type*/ undefined,
visitNode(node.initializer, visitor, isExpression)
@ -649,7 +650,7 @@ export function transformLegacyDecorators(context: TransformationContext): (x: S
* @param decorator The decorator node.
*/
function transformDecorator(decorator: Decorator) {
return visitNode(decorator.expression, visitor, isExpression);
return Debug.checkDefined(visitNode(decorator.expression, visitor, isExpression));
}
/**
@ -658,7 +659,7 @@ export function transformLegacyDecorators(context: TransformationContext): (x: S
* @param decorators The decorators for the parameter at the provided offset.
* @param parameterOffset The offset of the parameter.
*/
function transformDecoratorsOfParameter(decorators: Decorator[], parameterOffset: number) {
function transformDecoratorsOfParameter(decorators: readonly Decorator[] | undefined, parameterOffset: number) {
let expressions: Expression[] | undefined;
if (decorators) {
expressions = [];
@ -787,3 +788,4 @@ export function transformLegacyDecorators(context: TransformationContext): (x: S
return undefined;
}
}

Просмотреть файл

@ -116,7 +116,7 @@ export function transformECMAScriptModule(context: TransformationContext): (x: S
}
}
function visitor(node: Node): VisitResult<Node> {
function visitor(node: Node): VisitResult<Node | undefined> {
switch (node.kind) {
case SyntaxKind.ImportEqualsDeclaration:
// Though an error in es2020 modules, in node-flavor es2020 modules, we can helpfully transform this to a synthetic `require` call
@ -189,7 +189,7 @@ export function transformECMAScriptModule(context: TransformationContext): (x: S
*
* @param node The node to visit.
*/
function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): VisitResult<Statement> {
function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): VisitResult<Statement | undefined> {
Debug.assert(isExternalModuleImportEqualsDeclaration(node), "import= for internal module references should be handled in an earlier transformer.");
let statements: Statement[] | undefined;
@ -231,7 +231,7 @@ export function transformECMAScriptModule(context: TransformationContext): (x: S
return statements;
}
function visitExportAssignment(node: ExportAssignment): VisitResult<ExportAssignment> {
function visitExportAssignment(node: ExportAssignment): VisitResult<ExportAssignment | undefined> {
// Elide `export=` as it is not legal with --module ES6
return node.isExportEquals ? undefined : node;
}

Просмотреть файл

@ -60,6 +60,7 @@ import {
isArrowFunction,
isAssignmentOperator,
isBindingPattern,
isClassElement,
isClassExpression,
isDeclarationNameOfEnumOrNamespace,
isDefaultImport,
@ -74,11 +75,13 @@ import {
isForInitializer,
isFunctionExpression,
isGeneratedIdentifier,
isHeritageClause,
isIdentifier,
isImportCall,
isImportClause,
isImportEqualsDeclaration,
isImportSpecifier,
isInitializedVariable,
isJsonSourceFile,
isLocalName,
isModifier,
@ -86,6 +89,7 @@ import {
isNamedExports,
isObjectLiteralExpression,
isOmittedExpression,
isParameter,
isPrefixUnaryExpression,
isShorthandPropertyAssignment,
isSimpleCopiableExpression,
@ -604,7 +608,7 @@ export function transformModule(context: TransformationContext): (x: SourceFile
*/
function addExportEqualsIfNeeded(statements: Statement[], emitAsReturn: boolean) {
if (currentModuleInfo.exportEquals) {
const expressionResult = visitNode(currentModuleInfo.exportEquals.expression, visitor);
const expressionResult = visitNode(currentModuleInfo.exportEquals.expression, visitor, isExpression);
if (expressionResult) {
if (emitAsReturn) {
const statement = factory.createReturnStatement(expressionResult);
@ -640,7 +644,7 @@ export function transformModule(context: TransformationContext): (x: SourceFile
*
* @param node The node to visit.
*/
function topLevelVisitor(node: Node): VisitResult<Node> {
function topLevelVisitor(node: Node): VisitResult<Node | undefined> {
switch (node.kind) {
case SyntaxKind.ImportDeclaration:
return visitImportDeclaration(node as ImportDeclaration);
@ -845,7 +849,7 @@ export function transformModule(context: TransformationContext): (x: SourceFile
function visitImportCallExpression(node: ImportCall): Expression {
const externalModuleName = getExternalModuleNameLiteral(factory, node, currentSourceFile, host, resolver, compilerOptions);
const firstArgument = visitNode(firstOrUndefined(node.arguments), visitor);
const firstArgument = visitNode(firstOrUndefined(node.arguments), visitor, isExpression);
// Only use the external module name if it differs from the first argument. This allows us to preserve the quote style of the argument on output.
const argument = externalModuleName && (!firstArgument || !isStringLiteral(firstArgument) || firstArgument.text !== externalModuleName.text) ? externalModuleName : firstArgument;
const containsLexicalThis = !!(node.transformFlags & TransformFlags.ContainsLexicalThis);
@ -1057,7 +1061,7 @@ export function transformModule(context: TransformationContext): (x: SourceFile
*
* @param node The node to visit.
*/
function visitImportDeclaration(node: ImportDeclaration): VisitResult<Statement> {
function visitImportDeclaration(node: ImportDeclaration): VisitResult<Statement | undefined> {
let statements: Statement[] | undefined;
const namespaceDeclaration = getNamespaceDeclarationNode(node);
if (moduleKind !== ModuleKind.AMD) {
@ -1177,7 +1181,7 @@ export function transformModule(context: TransformationContext): (x: SourceFile
*
* @param node The node to visit.
*/
function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): VisitResult<Statement> {
function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): VisitResult<Statement | undefined> {
Debug.assert(isExternalModuleImportEqualsDeclaration(node), "import= for internal module references should be handled in an earlier transformer.");
let statements: Statement[] | undefined;
@ -1253,7 +1257,7 @@ export function transformModule(context: TransformationContext): (x: SourceFile
*
* @param The node to visit.
*/
function visitExportDeclaration(node: ExportDeclaration): VisitResult<Statement> {
function visitExportDeclaration(node: ExportDeclaration): VisitResult<Statement | undefined> {
if (!node.moduleSpecifier) {
// Elide export declarations with no module specifier as they are handled
// elsewhere.
@ -1363,7 +1367,7 @@ export function transformModule(context: TransformationContext): (x: SourceFile
*
* @param node The node to visit.
*/
function visitExportAssignment(node: ExportAssignment): VisitResult<Statement> {
function visitExportAssignment(node: ExportAssignment): VisitResult<Statement | undefined> {
if (node.isExportEquals) {
return undefined;
}
@ -1373,10 +1377,10 @@ export function transformModule(context: TransformationContext): (x: SourceFile
if (original && hasAssociatedEndOfDeclarationMarker(original)) {
// Defer exports until we encounter an EndOfDeclarationMarker node
const id = getOriginalNodeId(node);
deferredExports[id] = appendExportStatement(deferredExports[id], factory.createIdentifier("default"), visitNode(node.expression, visitor), /*location*/ node, /*allowComments*/ true);
deferredExports[id] = appendExportStatement(deferredExports[id], factory.createIdentifier("default"), visitNode(node.expression, visitor, isExpression), /*location*/ node, /*allowComments*/ true);
}
else {
statements = appendExportStatement(statements, factory.createIdentifier("default"), visitNode(node.expression, visitor), /*location*/ node, /*allowComments*/ true);
statements = appendExportStatement(statements, factory.createIdentifier("default"), visitNode(node.expression, visitor, isExpression), /*location*/ node, /*allowComments*/ true);
}
return singleOrMany(statements);
@ -1387,7 +1391,7 @@ export function transformModule(context: TransformationContext): (x: SourceFile
*
* @param node The node to visit.
*/
function visitFunctionDeclaration(node: FunctionDeclaration): VisitResult<Statement> {
function visitFunctionDeclaration(node: FunctionDeclaration): VisitResult<Statement | undefined> {
let statements: Statement[] | undefined;
if (hasSyntacticModifier(node, ModifierFlags.Export)) {
statements = append(statements,
@ -1398,7 +1402,7 @@ export function transformModule(context: TransformationContext): (x: SourceFile
node.asteriskToken,
factory.getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true),
/*typeParameters*/ undefined,
visitNodes(node.parameters, visitor),
visitNodes(node.parameters, visitor, isParameter),
/*type*/ undefined,
visitEachChild(node.body, visitor, context)
),
@ -1429,7 +1433,7 @@ export function transformModule(context: TransformationContext): (x: SourceFile
*
* @param node The node to visit.
*/
function visitClassDeclaration(node: ClassDeclaration): VisitResult<Statement> {
function visitClassDeclaration(node: ClassDeclaration): VisitResult<Statement | undefined> {
let statements: Statement[] | undefined;
if (hasSyntacticModifier(node, ModifierFlags.Export)) {
statements = append(statements,
@ -1439,8 +1443,8 @@ export function transformModule(context: TransformationContext): (x: SourceFile
visitNodes(node.modifiers, modifierVisitor, isModifierLike),
factory.getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true),
/*typeParameters*/ undefined,
visitNodes(node.heritageClauses, visitor),
visitNodes(node.members, visitor)
visitNodes(node.heritageClauses, visitor, isHeritageClause),
visitNodes(node.members, visitor, isClassElement)
),
node
),
@ -1469,7 +1473,7 @@ export function transformModule(context: TransformationContext): (x: SourceFile
*
* @param node The node to visit.
*/
function visitVariableStatement(node: VariableStatement): VisitResult<Statement> {
function visitVariableStatement(node: VariableStatement): VisitResult<Statement | undefined> {
let statements: Statement[] | undefined;
let variables: VariableDeclaration[] | undefined;
let expressions: Expression[] | undefined;
@ -1503,7 +1507,7 @@ export function transformModule(context: TransformationContext): (x: SourceFile
variable.name,
variable.exclamationToken,
variable.type,
visitNode(variable.initializer, visitor)
visitNode(variable.initializer, visitor, isExpression)
);
variables = append(variables, updatedVariable);
@ -1568,8 +1572,8 @@ export function transformModule(context: TransformationContext): (x: SourceFile
function transformInitializedVariable(node: InitializedVariableDeclaration): Expression {
if (isBindingPattern(node.name)) {
return flattenDestructuringAssignment(
visitNode(node, visitor),
/*visitor*/ undefined,
visitNode(node, visitor, isInitializedVariable),
visitor,
context,
FlattenLevel.All,
/*needsValue*/ false,
@ -1585,7 +1589,7 @@ export function transformModule(context: TransformationContext): (x: SourceFile
),
/*location*/ node.name
),
node.initializer ? visitNode(node.initializer, visitor) : factory.createVoidZero()
node.initializer ? visitNode(node.initializer, visitor, isExpression) : factory.createVoidZero()
);
}
}
@ -1909,7 +1913,7 @@ export function transformModule(context: TransformationContext): (x: SourceFile
*
* @param node The node to visit.
*/
function modifierVisitor(node: Node): VisitResult<Node> {
function modifierVisitor(node: Node): VisitResult<Node | undefined> {
// Elide module-specific modifiers.
switch (node.kind) {
case SyntaxKind.ExportKeyword:

Просмотреть файл

@ -78,7 +78,7 @@ import {
isNamedExports,
isObjectLiteralExpression,
isOmittedExpression,
isParameterDeclaration,
isParameter,
isPrefixUnaryExpression,
isPropertyAssignment,
isShorthandPropertyAssignment,
@ -708,7 +708,7 @@ export function transformSystemModule(context: TransformationContext): (x: Sourc
*
* @param node The node to visit.
*/
function topLevelVisitor(node: Node): VisitResult<Node> {
function topLevelVisitor(node: Node): VisitResult<Node | undefined> {
switch (node.kind) {
case SyntaxKind.ImportDeclaration:
return visitImportDeclaration(node as ImportDeclaration);
@ -732,7 +732,7 @@ export function transformSystemModule(context: TransformationContext): (x: Sourc
*
* @param node The node to visit.
*/
function visitImportDeclaration(node: ImportDeclaration): VisitResult<Statement> {
function visitImportDeclaration(node: ImportDeclaration): VisitResult<Statement | undefined> {
let statements: Statement[] | undefined;
if (node.importClause) {
hoistVariableDeclaration(getLocalNameForExternalImport(factory, node, currentSourceFile)!); // TODO: GH#18217
@ -750,7 +750,7 @@ export function transformSystemModule(context: TransformationContext): (x: Sourc
return singleOrMany(statements);
}
function visitExportDeclaration(node: ExportDeclaration): VisitResult<Statement> {
function visitExportDeclaration(node: ExportDeclaration): VisitResult<Statement | undefined> {
Debug.assertIsDefined(node);
return undefined;
}
@ -760,7 +760,7 @@ export function transformSystemModule(context: TransformationContext): (x: Sourc
*
* @param node The node to visit.
*/
function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): VisitResult<Statement> {
function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): VisitResult<Statement | undefined> {
Debug.assert(isExternalModuleImportEqualsDeclaration(node), "import= for internal module references should be handled in an earlier transformer.");
let statements: Statement[] | undefined;
@ -783,7 +783,7 @@ export function transformSystemModule(context: TransformationContext): (x: Sourc
*
* @param node The node to visit.
*/
function visitExportAssignment(node: ExportAssignment): VisitResult<Statement> {
function visitExportAssignment(node: ExportAssignment): VisitResult<Statement | undefined> {
if (node.isExportEquals) {
// Elide `export=` as it is illegal in a SystemJS module.
return undefined;
@ -806,7 +806,7 @@ export function transformSystemModule(context: TransformationContext): (x: Sourc
*
* @param node The node to visit.
*/
function visitFunctionDeclaration(node: FunctionDeclaration): VisitResult<Statement> {
function visitFunctionDeclaration(node: FunctionDeclaration): VisitResult<Statement | undefined> {
if (hasSyntacticModifier(node, ModifierFlags.Export)) {
hoistedStatements = append(hoistedStatements,
factory.updateFunctionDeclaration(
@ -815,7 +815,7 @@ export function transformSystemModule(context: TransformationContext): (x: Sourc
node.asteriskToken,
factory.getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true),
/*typeParameters*/ undefined,
visitNodes(node.parameters, visitor, isParameterDeclaration),
visitNodes(node.parameters, visitor, isParameter),
/*type*/ undefined,
visitNode(node.body, visitor, isBlock)));
}
@ -840,7 +840,7 @@ export function transformSystemModule(context: TransformationContext): (x: Sourc
*
* @param node The node to visit.
*/
function visitClassDeclaration(node: ClassDeclaration): VisitResult<Statement> {
function visitClassDeclaration(node: ClassDeclaration): VisitResult<Statement | undefined> {
let statements: Statement[] | undefined;
// Hoist the name of the class declaration to the outer module body function.
@ -887,7 +887,7 @@ export function transformSystemModule(context: TransformationContext): (x: Sourc
*
* @param node The node to visit.
*/
function visitVariableStatement(node: VariableStatement): VisitResult<Statement> {
function visitVariableStatement(node: VariableStatement): VisitResult<Statement | undefined> {
if (!shouldHoistVariableDeclarationList(node.declarationList)) {
return visitNode(node, visitor, isStatement);
}
@ -1293,7 +1293,7 @@ export function transformSystemModule(context: TransformationContext): (x: Sourc
*
* @param node The node to visit.
*/
function topLevelNestedVisitor(node: Node): VisitResult<Node> {
function topLevelNestedVisitor(node: Node): VisitResult<Node | undefined> {
switch (node.kind) {
case SyntaxKind.VariableStatement:
return visitVariableStatement(node as VariableStatement);
@ -1448,7 +1448,7 @@ export function transformSystemModule(context: TransformationContext): (x: Sourc
return expressions ? factory.inlineExpressions(expressions) : factory.createOmittedExpression();
}
else {
return visitNode(node, discardedValueVisitor, isExpression);
return visitNode(node, discardedValueVisitor, isForInitializer);
}
}
@ -1487,7 +1487,7 @@ export function transformSystemModule(context: TransformationContext): (x: Sourc
return factory.updateLabeledStatement(
node,
node.label,
visitNode(node.statement, topLevelNestedVisitor, isStatement, factory.liftToBlock)
Debug.checkDefined(visitNode(node.statement, topLevelNestedVisitor, isStatement, factory.liftToBlock))
);
}
@ -1500,7 +1500,7 @@ export function transformSystemModule(context: TransformationContext): (x: Sourc
return factory.updateWithStatement(
node,
visitNode(node.expression, visitor, isExpression),
visitNode(node.statement, topLevelNestedVisitor, isStatement, factory.liftToBlock)
Debug.checkDefined(visitNode(node.statement, topLevelNestedVisitor, isStatement, factory.liftToBlock))
);
}
@ -1513,7 +1513,7 @@ export function transformSystemModule(context: TransformationContext): (x: Sourc
return factory.updateSwitchStatement(
node,
visitNode(node.expression, visitor, isExpression),
visitNode(node.caseBlock, topLevelNestedVisitor, isCaseBlock)
Debug.checkDefined(visitNode(node.caseBlock, topLevelNestedVisitor, isCaseBlock))
);
}
@ -1578,7 +1578,7 @@ export function transformSystemModule(context: TransformationContext): (x: Sourc
node = factory.updateCatchClause(
node,
node.variableDeclaration,
visitNode(node.block, topLevelNestedVisitor, isBlock)
Debug.checkDefined(visitNode(node.block, topLevelNestedVisitor, isBlock))
);
enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
@ -1676,7 +1676,7 @@ export function transformSystemModule(context: TransformationContext): (x: Sourc
// };
// });
const externalModuleName = getExternalModuleNameLiteral(factory, node, currentSourceFile, host, resolver, compilerOptions);
const firstArgument = visitNode(firstOrUndefined(node.arguments), visitor);
const firstArgument = visitNode(firstOrUndefined(node.arguments), visitor, isExpression);
// Only use the external module name if it differs from the first argument. This allows us to preserve the quote style of the argument on output.
const argument = externalModuleName && (!firstArgument || !isStringLiteral(firstArgument) || firstArgument.text !== externalModuleName.text) ? externalModuleName : firstArgument;
return factory.createCallExpression(
@ -1798,7 +1798,7 @@ export function transformSystemModule(context: TransformationContext): (x: Sourc
*
* @param node The node to visit.
*/
function modifierVisitor(node: Node): VisitResult<Node> {
function modifierVisitor(node: Node): VisitResult<Node | undefined> {
switch (node.kind) {
case SyntaxKind.ExportKeyword:
case SyntaxKind.DefaultKeyword:

Просмотреть файл

@ -41,6 +41,7 @@ export function processTaggedTemplateExpression(
// Visit the tag expression
const tag = visitNode(node.tag, visitor, isExpression);
Debug.assert(tag);
// Build up the template arguments and the raw and cooked strings for the template.
// We start out with 'undefined' for the first argument and revisit later
@ -64,7 +65,7 @@ export function processTaggedTemplateExpression(
for (const templateSpan of template.templateSpans) {
cookedStrings.push(createTemplateCooked(templateSpan.literal));
rawStrings.push(getRawLiteral(templateSpan.literal, currentSourceFile));
templateArguments.push(visitNode(templateSpan.expression, visitor, isExpression));
templateArguments.push(Debug.checkDefined(visitNode(templateSpan.expression, visitor, isExpression)));
}
}

Просмотреть файл

@ -110,7 +110,7 @@ import {
isNamedExportBindings,
isNamedImportBindings,
isNamespaceExport,
isObjectLiteralElement,
isObjectLiteralElementLike,
isParameterPropertyDeclaration,
isPrivateIdentifier,
isPropertyAccessExpression,
@ -119,6 +119,7 @@ import {
isSimpleInlineableExpression,
isSourceFile,
isStatement,
isTemplateLiteral,
JsxOpeningElement,
JsxSelfClosingElement,
lastOrUndefined,
@ -319,7 +320,7 @@ export function transformTypeScript(context: TransformationContext) {
*
* @param node The node to visit.
*/
function saveStateAndInvoke<T>(node: Node, f: (node: Node) => T): T {
function saveStateAndInvoke<T, U extends Node>(node: U, f: (node: U) => T): T {
// Save state
const savedCurrentScope = currentLexicalScope;
const savedCurrentScopeFirstDeclarationsOfName = currentScopeFirstDeclarationsOfName;
@ -381,7 +382,7 @@ export function transformTypeScript(context: TransformationContext) {
*
* @param node The node to visit.
*/
function visitor(node: Node): VisitResult<Node> {
function visitor(node: Node): VisitResult<Node | undefined> {
return saveStateAndInvoke(node, visitorWorker);
}
@ -390,7 +391,7 @@ export function transformTypeScript(context: TransformationContext) {
*
* @param node The node to visit.
*/
function visitorWorker(node: Node): VisitResult<Node> {
function visitorWorker(node: Node): VisitResult<Node | undefined> {
if (node.transformFlags & TransformFlags.ContainsTypeScript) {
return visitTypeScript(node);
}
@ -402,7 +403,7 @@ export function transformTypeScript(context: TransformationContext) {
*
* @param node The node to visit.
*/
function sourceElementVisitor(node: Node): VisitResult<Node> {
function sourceElementVisitor(node: Node): VisitResult<Node | undefined> {
return saveStateAndInvoke(node, sourceElementVisitorWorker);
}
@ -411,7 +412,7 @@ export function transformTypeScript(context: TransformationContext) {
*
* @param node The node to visit.
*/
function sourceElementVisitorWorker(node: Node): VisitResult<Node> {
function sourceElementVisitorWorker(node: Node): VisitResult<Node | undefined> {
switch (node.kind) {
case SyntaxKind.ImportDeclaration:
case SyntaxKind.ImportEqualsDeclaration:
@ -423,7 +424,7 @@ export function transformTypeScript(context: TransformationContext) {
}
}
function visitElidableStatement(node: ImportDeclaration | ImportEqualsDeclaration | ExportAssignment | ExportDeclaration): VisitResult<Node> {
function visitElidableStatement(node: ImportDeclaration | ImportEqualsDeclaration | ExportAssignment | ExportDeclaration): VisitResult<Node | undefined> {
const parsed = getParseTreeNode(node);
if (parsed !== node) {
// If the node has been transformed by a `before` transformer, perform no ellision on it
@ -456,7 +457,7 @@ export function transformTypeScript(context: TransformationContext) {
*
* @param node The node to visit.
*/
function namespaceElementVisitor(node: Node): VisitResult<Node> {
function namespaceElementVisitor(node: Node): VisitResult<Node | undefined> {
return saveStateAndInvoke(node, namespaceElementVisitorWorker);
}
@ -465,7 +466,7 @@ export function transformTypeScript(context: TransformationContext) {
*
* @param node The node to visit.
*/
function namespaceElementVisitorWorker(node: Node): VisitResult<Node> {
function namespaceElementVisitorWorker(node: Node): VisitResult<Node | undefined> {
if (node.kind === SyntaxKind.ExportDeclaration ||
node.kind === SyntaxKind.ImportDeclaration ||
node.kind === SyntaxKind.ImportClause ||
@ -486,7 +487,7 @@ export function transformTypeScript(context: TransformationContext) {
*
* @param parent The class containing the elements to visit.
*/
function getClassElementVisitor(parent: ClassLikeDeclaration): (node: Node) => VisitResult<Node> {
function getClassElementVisitor(parent: ClassLikeDeclaration): (node: Node) => VisitResult<Node | undefined> {
return node => saveStateAndInvoke(node, n => classElementVisitorWorker(n, parent));
}
@ -495,7 +496,7 @@ export function transformTypeScript(context: TransformationContext) {
*
* @param node The node to visit.
*/
function classElementVisitorWorker(node: Node, parent: ClassLikeDeclaration): VisitResult<Node> {
function classElementVisitorWorker(node: Node, parent: ClassLikeDeclaration): VisitResult<Node | undefined> {
switch (node.kind) {
case SyntaxKind.Constructor:
return visitConstructor(node as ConstructorDeclaration);
@ -533,11 +534,11 @@ export function transformTypeScript(context: TransformationContext) {
}
}
function getObjectLiteralElementVisitor(parent: ObjectLiteralExpression): (node: Node) => VisitResult<Node> {
function getObjectLiteralElementVisitor(parent: ObjectLiteralExpression): <T extends Node>(node: T) => VisitResult<Node | undefined> {
return node => saveStateAndInvoke(node, n => objectLiteralElementVisitorWorker(n, parent));
}
function objectLiteralElementVisitorWorker(node: Node, parent: ObjectLiteralExpression): VisitResult<Node> {
function objectLiteralElementVisitorWorker(node: Node, parent: ObjectLiteralExpression): VisitResult<Node | undefined> {
switch (node.kind) {
case SyntaxKind.PropertyAssignment:
case SyntaxKind.ShorthandPropertyAssignment:
@ -562,7 +563,7 @@ export function transformTypeScript(context: TransformationContext) {
}
}
function modifierVisitor(node: Node): VisitResult<Node> {
function modifierVisitor(node: Node): VisitResult<Node | undefined> {
if (isDecorator(node)) return undefined;
if (modifierToFlag(node.kind) & ModifierFlags.TypeScriptModifier) {
return undefined;
@ -579,7 +580,7 @@ export function transformTypeScript(context: TransformationContext) {
*
* @param node The node to visit.
*/
function visitTypeScript(node: Node): VisitResult<Node> {
function visitTypeScript(node: Node): VisitResult<Node | undefined> {
if (isStatement(node) && hasSyntacticModifier(node, ModifierFlags.Ambient)) {
// TypeScript ambient declarations are elided, but some comments may be preserved.
// See the implementation of `getLeadingComments` in comments.ts for more details.
@ -789,7 +790,7 @@ export function transformTypeScript(context: TransformationContext) {
function visitObjectLiteralExpression(node: ObjectLiteralExpression) {
return factory.updateObjectLiteralExpression(
node,
visitNodes(node.properties, getObjectLiteralElementVisitor(node), isObjectLiteralElement)
visitNodes(node.properties, getObjectLiteralElementVisitor(node), isObjectLiteralElementLike)
);
}
@ -1013,11 +1014,12 @@ export function transformTypeScript(context: TransformationContext) {
* @param parameterDecorators The decorators for the parameter at the provided offset.
* @param parameterOffset The offset of the parameter.
*/
function transformDecoratorsOfParameter(parameterDecorators: Decorator[], parameterOffset: number) {
function transformDecoratorsOfParameter(parameterDecorators: readonly Decorator[] | undefined, parameterOffset: number) {
if (parameterDecorators) {
const decorators: Decorator[] = [];
for (const parameterDecorator of parameterDecorators) {
const expression = visitNode(parameterDecorator.expression, visitor, isExpression);
Debug.assert(expression);
const helper = emitHelpers().createParamHelper(expression, parameterOffset);
setTextRange(helper, parameterDecorator.expression);
setEmitFlags(helper, EmitFlags.NoComments);
@ -1169,6 +1171,7 @@ export function transformTypeScript(context: TransformationContext) {
// - the property has a decorator.
if (isComputedPropertyName(name) && ((!hasStaticModifier(member) && currentClassHasParameterProperties) || hasDecorators(member))) {
const expression = visitNode(name.expression, visitor, isExpression);
Debug.assert(expression);
const innerExpression = skipPartiallyEmittedExpressions(expression);
if (!isSimpleInlineableExpression(innerExpression)) {
const generatedName = factory.getGeneratedNameForNode(name);
@ -1176,7 +1179,7 @@ export function transformTypeScript(context: TransformationContext) {
return factory.updateComputedPropertyName(name, factory.createAssignment(generatedName, expression));
}
}
return visitNode(name, visitor, isPropertyName);
return Debug.checkDefined(visitNode(name, visitor, isPropertyName));
}
/**
@ -1207,7 +1210,7 @@ export function transformTypeScript(context: TransformationContext) {
function visitExpressionWithTypeArguments(node: ExpressionWithTypeArguments): ExpressionWithTypeArguments {
return factory.updateExpressionWithTypeArguments(
node,
visitNode(node.expression, visitor, isLeftHandSideExpression),
Debug.checkDefined(visitNode(node.expression, visitor, isLeftHandSideExpression)),
/*typeArguments*/ undefined
);
}
@ -1236,7 +1239,7 @@ export function transformTypeScript(context: TransformationContext) {
return factory.updatePropertyDeclaration(
node,
concatenate<ModifierLike>(decorators, factory.createModifiersFromModifierFlags(ModifierFlags.Ambient)),
visitNode(node.name, visitor, isPropertyName),
Debug.checkDefined(visitNode(node.name, visitor, isPropertyName)),
/*questionOrExclamationToken*/ undefined,
/*type*/ undefined,
/*initializer*/ undefined
@ -1249,7 +1252,7 @@ export function transformTypeScript(context: TransformationContext) {
visitPropertyNameOfClassElement(node),
/*questionOrExclamationToken*/ undefined,
/*type*/ undefined,
visitNode(node.initializer, visitor)
visitNode(node.initializer, visitor, isExpression)
);
}
@ -1268,7 +1271,7 @@ export function transformTypeScript(context: TransformationContext) {
function transformConstructorBody(body: Block, constructor: ConstructorDeclaration) {
const parametersWithPropertyAssignments = constructor &&
filter(constructor.parameters, p => isParameterPropertyDeclaration(p, constructor));
filter(constructor.parameters, p => isParameterPropertyDeclaration(p, constructor)) as readonly ParameterPropertyDeclaration[] | undefined;
if (!some(parametersWithPropertyAssignments)) {
return visitFunctionBody(body, visitor, context);
}
@ -1510,7 +1513,7 @@ export function transformTypeScript(context: TransformationContext) {
node,
elideNodes(factory, node.modifiers), // preserve positions, if available
node.dotDotDotToken,
visitNode(node.name, visitor, isBindingName),
Debug.checkDefined(visitNode(node.name, visitor, isBindingName)),
/*questionToken*/ undefined,
/*type*/ undefined,
visitNode(node.initializer, visitor, isExpression)
@ -1564,7 +1567,7 @@ export function transformTypeScript(context: TransformationContext) {
return setTextRange(
factory.createAssignment(
getNamespaceMemberNameWithSourceMapsAndWithoutComments(name),
visitNode(node.initializer, visitor, isExpression)
Debug.checkDefined(visitNode(node.initializer, visitor, isExpression))
),
/*location*/ node
);
@ -1574,7 +1577,7 @@ export function transformTypeScript(context: TransformationContext) {
function visitVariableDeclaration(node: VariableDeclaration) {
const updated = factory.updateVariableDeclaration(
node,
visitNode(node.name, visitor, isBindingName),
Debug.checkDefined(visitNode(node.name, visitor, isBindingName)),
/*exclamationToken*/ undefined,
/*type*/ undefined,
visitNode(node.initializer, visitor, isExpression));
@ -1590,6 +1593,7 @@ export function transformTypeScript(context: TransformationContext) {
// Make sure we consider all nested cast expressions, e.g.:
// (<any><number><any>-A).x;
const expression = visitNode(node.expression, visitor, isExpression);
Debug.assert(expression);
// We have an expression of the form: (<Type>SubExpr). Emitting this as (SubExpr)
// is really not desirable. We would like to emit the subexpression as-is. Omitting
@ -1616,23 +1620,26 @@ export function transformTypeScript(context: TransformationContext) {
function visitAssertionExpression(node: AssertionExpression): Expression {
const expression = visitNode(node.expression, visitor, isExpression);
Debug.assert(expression);
return factory.createPartiallyEmittedExpression(expression, node);
}
function visitNonNullExpression(node: NonNullExpression): Expression {
const expression = visitNode(node.expression, visitor, isLeftHandSideExpression);
Debug.assert(expression);
return factory.createPartiallyEmittedExpression(expression, node);
}
function visitSatisfiesExpression(node: SatisfiesExpression): Expression {
const expression = visitNode(node.expression, visitor, isExpression);
Debug.assert(expression);
return factory.createPartiallyEmittedExpression(expression, node);
}
function visitCallExpression(node: CallExpression) {
return factory.updateCallExpression(
node,
visitNode(node.expression, visitor, isExpression),
Debug.checkDefined(visitNode(node.expression, visitor, isExpression)),
/*typeArguments*/ undefined,
visitNodes(node.arguments, visitor, isExpression));
}
@ -1640,7 +1647,7 @@ export function transformTypeScript(context: TransformationContext) {
function visitNewExpression(node: NewExpression) {
return factory.updateNewExpression(
node,
visitNode(node.expression, visitor, isExpression),
Debug.checkDefined(visitNode(node.expression, visitor, isExpression)),
/*typeArguments*/ undefined,
visitNodes(node.arguments, visitor, isExpression));
}
@ -1648,25 +1655,25 @@ export function transformTypeScript(context: TransformationContext) {
function visitTaggedTemplateExpression(node: TaggedTemplateExpression) {
return factory.updateTaggedTemplateExpression(
node,
visitNode(node.tag, visitor, isExpression),
Debug.checkDefined(visitNode(node.tag, visitor, isExpression)),
/*typeArguments*/ undefined,
visitNode(node.template, visitor, isExpression));
Debug.checkDefined(visitNode(node.template, visitor, isTemplateLiteral)));
}
function visitJsxSelfClosingElement(node: JsxSelfClosingElement) {
return factory.updateJsxSelfClosingElement(
node,
visitNode(node.tagName, visitor, isJsxTagNameExpression),
Debug.checkDefined(visitNode(node.tagName, visitor, isJsxTagNameExpression)),
/*typeArguments*/ undefined,
visitNode(node.attributes, visitor, isJsxAttributes));
Debug.checkDefined(visitNode(node.attributes, visitor, isJsxAttributes)));
}
function visitJsxJsxOpeningElement(node: JsxOpeningElement) {
return factory.updateJsxOpeningElement(
node,
visitNode(node.tagName, visitor, isJsxTagNameExpression),
Debug.checkDefined(visitNode(node.tagName, visitor, isJsxTagNameExpression)),
/*typeArguments*/ undefined,
visitNode(node.attributes, visitor, isJsxAttributes));
Debug.checkDefined(visitNode(node.attributes, visitor, isJsxAttributes)));
}
/**
@ -1847,7 +1854,7 @@ export function transformTypeScript(context: TransformationContext) {
else {
enableSubstitutionForNonQualifiedEnumMembers();
if (member.initializer) {
return visitNode(member.initializer, visitor, isExpression);
return Debug.checkDefined(visitNode(member.initializer, visitor, isExpression));
}
else {
return factory.createVoidZero();
@ -2095,7 +2102,7 @@ export function transformTypeScript(context: TransformationContext) {
let blockLocation: TextRange | undefined;
if (node.body) {
if (node.body.kind === SyntaxKind.ModuleBlock) {
saveStateAndInvoke(node.body, body => addRange(statements, visitNodes((body as ModuleBlock).statements, namespaceElementVisitor, isStatement)));
saveStateAndInvoke(node.body, body => addRange(statements, visitNodes(body.statements, namespaceElementVisitor, isStatement)));
statementsLocation = node.body.statements;
blockLocation = node.body;
}
@ -2167,7 +2174,7 @@ export function transformTypeScript(context: TransformationContext) {
*
* @param node The import declaration node.
*/
function visitImportDeclaration(node: ImportDeclaration): VisitResult<Statement> {
function visitImportDeclaration(node: ImportDeclaration): VisitResult<Statement | undefined> {
if (!node.importClause) {
// Do not elide a side-effect only import declaration.
// import "foo";
@ -2197,7 +2204,7 @@ export function transformTypeScript(context: TransformationContext) {
*
* @param node The import clause node.
*/
function visitImportClause(node: ImportClause): VisitResult<ImportClause> {
function visitImportClause(node: ImportClause): VisitResult<ImportClause> | undefined {
Debug.assert(!node.isTypeOnly);
// Elide the import clause if we elide both its name and its named bindings.
const name = shouldEmitAliasDeclaration(node) ? node.name : undefined;
@ -2210,7 +2217,7 @@ export function transformTypeScript(context: TransformationContext) {
*
* @param node The named import bindings node.
*/
function visitNamedImportBindings(node: NamedImportBindings): VisitResult<NamedImportBindings> {
function visitNamedImportBindings(node: NamedImportBindings): VisitResult<NamedImportBindings> | undefined {
if (node.kind === SyntaxKind.NamespaceImport) {
// Elide a namespace import if it is not referenced.
return shouldEmitAliasDeclaration(node) ? node : undefined;
@ -2230,7 +2237,7 @@ export function transformTypeScript(context: TransformationContext) {
*
* @param node The import specifier node.
*/
function visitImportSpecifier(node: ImportSpecifier): VisitResult<ImportSpecifier> {
function visitImportSpecifier(node: ImportSpecifier): VisitResult<ImportSpecifier> | undefined {
return !node.isTypeOnly && shouldEmitAliasDeclaration(node) ? node : undefined;
}
@ -2240,7 +2247,7 @@ export function transformTypeScript(context: TransformationContext) {
*
* @param node The export assignment node.
*/
function visitExportAssignment(node: ExportAssignment): VisitResult<Statement> {
function visitExportAssignment(node: ExportAssignment): VisitResult<Statement | undefined> {
// Elide the export assignment if it does not reference a value.
return resolver.isValueAliasDeclaration(node)
? visitEachChild(node, visitor, context)
@ -2252,7 +2259,7 @@ export function transformTypeScript(context: TransformationContext) {
*
* @param node The export declaration node.
*/
function visitExportDeclaration(node: ExportDeclaration): VisitResult<Statement> {
function visitExportDeclaration(node: ExportDeclaration): VisitResult<Statement | undefined> {
if (node.isTypeOnly) {
return undefined;
}
@ -2290,17 +2297,17 @@ export function transformTypeScript(context: TransformationContext) {
*
* @param node The named exports node.
*/
function visitNamedExports(node: NamedExports, allowEmpty: boolean): VisitResult<NamedExports> {
function visitNamedExports(node: NamedExports, allowEmpty: boolean): VisitResult<NamedExports> | undefined {
// Elide the named exports if all of its export specifiers were elided.
const elements = visitNodes(node.elements, visitExportSpecifier, isExportSpecifier);
return allowEmpty || some(elements) ? factory.updateNamedExports(node, elements) : undefined;
}
function visitNamespaceExports(node: NamespaceExport): VisitResult<NamespaceExport> {
return factory.updateNamespaceExport(node, visitNode(node.name, visitor, isIdentifier));
return factory.updateNamespaceExport(node, Debug.checkDefined(visitNode(node.name, visitor, isIdentifier)));
}
function visitNamedExportBindings(node: NamedExportBindings, allowEmpty: boolean): VisitResult<NamedExportBindings> {
function visitNamedExportBindings(node: NamedExportBindings, allowEmpty: boolean): VisitResult<NamedExportBindings> | undefined {
return isNamespaceExport(node) ? visitNamespaceExports(node) : visitNamedExports(node, allowEmpty);
}
@ -2309,7 +2316,7 @@ export function transformTypeScript(context: TransformationContext) {
*
* @param node The export specifier node.
*/
function visitExportSpecifier(node: ExportSpecifier): VisitResult<ExportSpecifier> {
function visitExportSpecifier(node: ExportSpecifier): VisitResult<ExportSpecifier> | undefined {
// Elide an export specifier if it does not reference a value.
return !node.isTypeOnly && resolver.isValueAliasDeclaration(node) ? node : undefined;
}
@ -2333,7 +2340,7 @@ export function transformTypeScript(context: TransformationContext) {
*
* @param node The import equals declaration node.
*/
function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): VisitResult<Statement> {
function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): VisitResult<Statement | undefined> {
// Always elide type-only imports
if (node.isTypeOnly) {
return undefined;

Просмотреть файл

@ -364,7 +364,7 @@ interface BuildInfoCacheEntry {
latestChangedDtsTime?: Date | false;
}
interface SolutionBuilderState<T extends BuilderProgram = BuilderProgram> extends WatchFactory<WatchType, ResolvedConfigFileName> {
interface SolutionBuilderState<T extends BuilderProgram> extends WatchFactory<WatchType, ResolvedConfigFileName> {
readonly host: SolutionBuilderHost<T>;
readonly hostWithWatch: SolutionBuilderWithWatchHost<T>;
readonly parseConfigFileHost: ParseConfigFileHost;
@ -524,11 +524,11 @@ function createSolutionBuilderState<T extends BuilderProgram>(watch: boolean, ho
return state;
}
function toPath(state: SolutionBuilderState, fileName: string) {
function toPath<T extends BuilderProgram>(state: SolutionBuilderState<T>, fileName: string) {
return ts.toPath(fileName, state.compilerHost.getCurrentDirectory(), state.compilerHost.getCanonicalFileName);
}
function toResolvedConfigFilePath(state: SolutionBuilderState, fileName: ResolvedConfigFileName): ResolvedConfigFilePath {
function toResolvedConfigFilePath<T extends BuilderProgram>(state: SolutionBuilderState<T>, fileName: ResolvedConfigFileName): ResolvedConfigFilePath {
const { resolvedConfigFilePaths } = state;
const path = resolvedConfigFilePaths.get(fileName);
if (path !== undefined) return path;
@ -542,12 +542,12 @@ function isParsedCommandLine(entry: ConfigFileCacheEntry): entry is ParsedComman
return !!(entry as ParsedCommandLine).options;
}
function getCachedParsedConfigFile(state: SolutionBuilderState, configFilePath: ResolvedConfigFilePath): ParsedCommandLine | undefined {
function getCachedParsedConfigFile<T extends BuilderProgram>(state: SolutionBuilderState<T>, configFilePath: ResolvedConfigFilePath): ParsedCommandLine | undefined {
const value = state.configFileCache.get(configFilePath);
return value && isParsedCommandLine(value) ? value : undefined;
}
function parseConfigFile(state: SolutionBuilderState, configFileName: ResolvedConfigFileName, configFilePath: ResolvedConfigFilePath): ParsedCommandLine | undefined {
function parseConfigFile<T extends BuilderProgram>(state: SolutionBuilderState<T>, configFileName: ResolvedConfigFileName, configFilePath: ResolvedConfigFilePath): ParsedCommandLine | undefined {
const { configFileCache } = state;
const value = configFileCache.get(configFilePath);
if (value) {
@ -573,11 +573,11 @@ function parseConfigFile(state: SolutionBuilderState, configFileName: ResolvedCo
return parsed;
}
function resolveProjectName(state: SolutionBuilderState, name: string): ResolvedConfigFileName {
function resolveProjectName<T extends BuilderProgram>(state: SolutionBuilderState<T>, name: string): ResolvedConfigFileName {
return resolveConfigFileProjectName(resolvePath(state.compilerHost.getCurrentDirectory(), name));
}
function createBuildOrder(state: SolutionBuilderState, roots: readonly ResolvedConfigFileName[]): AnyBuildOrder {
function createBuildOrder<T extends BuilderProgram>(state: SolutionBuilderState<T>, roots: readonly ResolvedConfigFileName[]): AnyBuildOrder {
const temporaryMarks = new Map<ResolvedConfigFilePath, true>();
const permanentMarks = new Map<ResolvedConfigFilePath, true>();
const circularityReportStack: string[] = [];
@ -624,11 +624,11 @@ function createBuildOrder(state: SolutionBuilderState, roots: readonly ResolvedC
}
}
function getBuildOrder(state: SolutionBuilderState) {
function getBuildOrder<T extends BuilderProgram>(state: SolutionBuilderState<T>) {
return state.buildOrder || createStateBuildOrder(state);
}
function createStateBuildOrder(state: SolutionBuilderState) {
function createStateBuildOrder<T extends BuilderProgram>(state: SolutionBuilderState<T>) {
const buildOrder = createBuildOrder(state, state.rootNames.map(f => resolveProjectName(state, f)));
// Clear all to ResolvedConfigFilePaths cache to start fresh
@ -689,7 +689,7 @@ function createStateBuildOrder(state: SolutionBuilderState) {
return state.buildOrder = buildOrder;
}
function getBuildOrderFor(state: SolutionBuilderState, project: string | undefined, onlyReferences: boolean | undefined): AnyBuildOrder | undefined {
function getBuildOrderFor<T extends BuilderProgram>(state: SolutionBuilderState<T>, project: string | undefined, onlyReferences: boolean | undefined): AnyBuildOrder | undefined {
const resolvedProject = project && resolveProjectName(state, project);
const buildOrderFromState = getBuildOrder(state);
if (isCircularBuildOrder(buildOrderFromState)) return buildOrderFromState;
@ -708,7 +708,7 @@ function getBuildOrderFor(state: SolutionBuilderState, project: string | undefin
return onlyReferences ? buildOrder.slice(0, buildOrder.length - 1) : buildOrder;
}
function enableCache(state: SolutionBuilderState) {
function enableCache<T extends BuilderProgram>(state: SolutionBuilderState<T>) {
if (state.cache) {
disableCache(state);
}
@ -741,7 +741,7 @@ function enableCache(state: SolutionBuilderState) {
};
}
function disableCache(state: SolutionBuilderState) {
function disableCache<T extends BuilderProgram>(state: SolutionBuilderState<T>) {
if (!state.cache) return;
const { cache, host, compilerHost, extendedConfigCache, moduleResolutionCache, typeReferenceDirectiveResolutionCache } = state;
@ -759,12 +759,12 @@ function disableCache(state: SolutionBuilderState) {
state.cache = undefined;
}
function clearProjectStatus(state: SolutionBuilderState, resolved: ResolvedConfigFilePath) {
function clearProjectStatus<T extends BuilderProgram>(state: SolutionBuilderState<T>, resolved: ResolvedConfigFilePath) {
state.projectStatus.delete(resolved);
state.diagnostics.delete(resolved);
}
function addProjToQueue({ projectPendingBuild }: SolutionBuilderState, proj: ResolvedConfigFilePath, reloadLevel: ConfigFileProgramReloadLevel) {
function addProjToQueue<T extends BuilderProgram>({ projectPendingBuild }: SolutionBuilderState<T>, proj: ResolvedConfigFilePath, reloadLevel: ConfigFileProgramReloadLevel) {
const value = projectPendingBuild.get(proj);
if (value === undefined) {
projectPendingBuild.set(proj, reloadLevel);
@ -774,7 +774,7 @@ function addProjToQueue({ projectPendingBuild }: SolutionBuilderState, proj: Res
}
}
function setupInitialBuild(state: SolutionBuilderState, cancellationToken: CancellationToken | undefined) {
function setupInitialBuild<T extends BuilderProgram>(state: SolutionBuilderState<T>, cancellationToken: CancellationToken | undefined) {
// Set initial build if not already built
if (!state.allProjectBuildPending) return;
state.allProjectBuildPending = false;
@ -854,8 +854,8 @@ export interface UpdateBundleProject<T extends BuilderProgram> extends Invalidat
export type InvalidatedProject<T extends BuilderProgram> = UpdateOutputFileStampsProject | BuildInvalidedProject<T> | UpdateBundleProject<T>;
function doneInvalidatedProject(
state: SolutionBuilderState,
function doneInvalidatedProject<T extends BuilderProgram>(
state: SolutionBuilderState<T>,
projectPath: ResolvedConfigFilePath
) {
state.projectPendingBuild.delete(projectPath);
@ -864,8 +864,8 @@ function doneInvalidatedProject(
ExitStatus.Success;
}
function createUpdateOutputFileStampsProject(
state: SolutionBuilderState,
function createUpdateOutputFileStampsProject<T extends BuilderProgram>(
state: SolutionBuilderState<T>,
project: ResolvedConfigFileName,
projectPath: ResolvedConfigFilePath,
config: ParsedCommandLine,
@ -1340,7 +1340,7 @@ function createBuildOrUpdateInvalidedProject<T extends BuilderProgram>(
}
}
function needsBuild({ options }: SolutionBuilderState, status: UpToDateStatus, config: ParsedCommandLine) {
function needsBuild<T extends BuilderProgram>({ options }: SolutionBuilderState<T>, status: UpToDateStatus, config: ParsedCommandLine) {
if (status.type !== UpToDateStatusType.OutOfDateWithPrepend || options.force) return true;
return config.fileNames.length === 0 ||
!!getConfigFileParsingDiagnostics(config).length ||
@ -1500,7 +1500,7 @@ function getNextInvalidatedProject<T extends BuilderProgram>(
return createInvalidatedProjectWithInfo(state, info, buildOrder);
}
function listEmittedFile({ write }: SolutionBuilderState, proj: ParsedCommandLine, file: string) {
function listEmittedFile<T extends BuilderProgram>({ write }: SolutionBuilderState<T>, proj: ParsedCommandLine, file: string) {
if (write && proj.options.listEmittedFiles) {
write(`TSFILE: ${file}`);
}
@ -1554,7 +1554,7 @@ function isFileWatcherWithModifiedTime(value: FileWatcherWithModifiedTime | Date
return !!(value as FileWatcherWithModifiedTime).watcher;
}
function getModifiedTime(state: SolutionBuilderState, fileName: string): Date {
function getModifiedTime<T extends BuilderProgram>(state: SolutionBuilderState<T>, fileName: string): Date {
const path = toPath(state, fileName);
const existing = state.filesWatched.get(path);
if (state.watch && !!existing) {
@ -1572,7 +1572,7 @@ function getModifiedTime(state: SolutionBuilderState, fileName: string): Date {
return result;
}
function watchFile(state: SolutionBuilderState, file: string, callback: FileWatcherCallback, pollingInterval: PollingInterval, options: WatchOptions | undefined, watchType: WatchType, project?: ResolvedConfigFileName): FileWatcher {
function watchFile<T extends BuilderProgram>(state: SolutionBuilderState<T>, file: string, callback: FileWatcherCallback, pollingInterval: PollingInterval, options: WatchOptions | undefined, watchType: WatchType, project?: ResolvedConfigFileName): FileWatcher {
const path = toPath(state, file);
const existing = state.filesWatched.get(path);
if (existing && isFileWatcherWithModifiedTime(existing)) {
@ -1610,7 +1610,7 @@ function watchFile(state: SolutionBuilderState, file: string, callback: FileWatc
};
}
function getOutputTimeStampMap(state: SolutionBuilderState, resolvedConfigFilePath: ResolvedConfigFilePath) {
function getOutputTimeStampMap<T extends BuilderProgram>(state: SolutionBuilderState<T>, resolvedConfigFilePath: ResolvedConfigFilePath) {
// Output timestamps are stored only in watch mode
if (!state.watch) return undefined;
let result = state.outputTimeStamps.get(resolvedConfigFilePath);
@ -1618,8 +1618,8 @@ function getOutputTimeStampMap(state: SolutionBuilderState, resolvedConfigFilePa
return result;
}
function setBuildInfo(
state: SolutionBuilderState,
function setBuildInfo<T extends BuilderProgram>(
state: SolutionBuilderState<T>,
buildInfo: BuildInfo,
resolvedConfigPath: ResolvedConfigFilePath,
options: CompilerOptions,
@ -1643,13 +1643,13 @@ function setBuildInfo(
}
}
function getBuildInfoCacheEntry(state: SolutionBuilderState, buildInfoPath: string, resolvedConfigPath: ResolvedConfigFilePath) {
function getBuildInfoCacheEntry<T extends BuilderProgram>(state: SolutionBuilderState<T>, buildInfoPath: string, resolvedConfigPath: ResolvedConfigFilePath) {
const path = toPath(state, buildInfoPath);
const existing = state.buildInfoCache.get(resolvedConfigPath);
return existing?.path === path ? existing : undefined;
}
function getBuildInfo(state: SolutionBuilderState, buildInfoPath: string, resolvedConfigPath: ResolvedConfigFilePath, modifiedTime: Date | undefined): BuildInfo | undefined {
function getBuildInfo<T extends BuilderProgram>(state: SolutionBuilderState<T>, buildInfoPath: string, resolvedConfigPath: ResolvedConfigFilePath, modifiedTime: Date | undefined): BuildInfo | undefined {
const path = toPath(state, buildInfoPath);
const existing = state.buildInfoCache.get(resolvedConfigPath);
if (existing !== undefined && existing.path === path) {
@ -1661,7 +1661,7 @@ function getBuildInfo(state: SolutionBuilderState, buildInfoPath: string, resolv
return buildInfo;
}
function checkConfigFileUpToDateStatus(state: SolutionBuilderState, configFile: string, oldestOutputFileTime: Date, oldestOutputFileName: string): Status.OutOfDateWithSelf | undefined {
function checkConfigFileUpToDateStatus<T extends BuilderProgram>(state: SolutionBuilderState<T>, configFile: string, oldestOutputFileTime: Date, oldestOutputFileName: string): Status.OutOfDateWithSelf | undefined {
// Check tsconfig time
const tsconfigTime = getModifiedTime(state, configFile);
if (oldestOutputFileTime < tsconfigTime) {
@ -1673,7 +1673,7 @@ function checkConfigFileUpToDateStatus(state: SolutionBuilderState, configFile:
}
}
function getUpToDateStatusWorker(state: SolutionBuilderState, project: ParsedCommandLine, resolvedPath: ResolvedConfigFilePath): UpToDateStatus {
function getUpToDateStatusWorker<T extends BuilderProgram>(state: SolutionBuilderState<T>, project: ParsedCommandLine, resolvedPath: ResolvedConfigFilePath): UpToDateStatus {
// Container if no files are specified in the project
if (!project.fileNames.length && !canJsonReportNoInputFiles(project.raw)) {
return {
@ -1953,12 +1953,12 @@ function getUpToDateStatusWorker(state: SolutionBuilderState, project: ParsedCom
};
}
function hasSameBuildInfo(state: SolutionBuilderState, buildInfoCacheEntry: BuildInfoCacheEntry, resolvedRefPath: ResolvedConfigFilePath) {
function hasSameBuildInfo<T extends BuilderProgram>(state: SolutionBuilderState<T>, buildInfoCacheEntry: BuildInfoCacheEntry, resolvedRefPath: ResolvedConfigFilePath) {
const refBuildInfo = state.buildInfoCache.get(resolvedRefPath)!;
return refBuildInfo.path === buildInfoCacheEntry.path;
}
function getUpToDateStatus(state: SolutionBuilderState, project: ParsedCommandLine | undefined, resolvedPath: ResolvedConfigFilePath): UpToDateStatus {
function getUpToDateStatus<T extends BuilderProgram>(state: SolutionBuilderState<T>, project: ParsedCommandLine | undefined, resolvedPath: ResolvedConfigFilePath): UpToDateStatus {
if (project === undefined) {
return { type: UpToDateStatusType.Unbuildable, reason: "File deleted mid-build" };
}
@ -1976,8 +1976,8 @@ function getUpToDateStatus(state: SolutionBuilderState, project: ParsedCommandLi
return actual;
}
function updateOutputTimestampsWorker(
state: SolutionBuilderState,
function updateOutputTimestampsWorker<T extends BuilderProgram>(
state: SolutionBuilderState<T>,
proj: ParsedCommandLine,
projectPath: ResolvedConfigFilePath,
verboseMessage: DiagnosticMessage,
@ -2026,7 +2026,7 @@ function updateOutputTimestampsWorker(
});
}
function getLatestChangedDtsTime(state: SolutionBuilderState, options: CompilerOptions, resolvedConfigPath: ResolvedConfigFilePath) {
function getLatestChangedDtsTime<T extends BuilderProgram>(state: SolutionBuilderState<T>, options: CompilerOptions, resolvedConfigPath: ResolvedConfigFilePath) {
if (!options.composite) return undefined;
const entry = Debug.checkDefined(state.buildInfoCache.get(resolvedConfigPath));
if (entry.latestChangedDtsTime !== undefined) return entry.latestChangedDtsTime || undefined;
@ -2037,7 +2037,7 @@ function getLatestChangedDtsTime(state: SolutionBuilderState, options: CompilerO
return latestChangedDtsTime;
}
function updateOutputTimestamps(state: SolutionBuilderState, proj: ParsedCommandLine, resolvedPath: ResolvedConfigFilePath) {
function updateOutputTimestamps<T extends BuilderProgram>(state: SolutionBuilderState<T>, proj: ParsedCommandLine, resolvedPath: ResolvedConfigFilePath) {
if (state.options.dry) {
return reportStatus(state, Diagnostics.A_non_dry_build_would_update_timestamps_for_output_of_project_0, proj.options.configFilePath!);
}
@ -2048,8 +2048,8 @@ function updateOutputTimestamps(state: SolutionBuilderState, proj: ParsedCommand
});
}
function queueReferencingProjects(
state: SolutionBuilderState,
function queueReferencingProjects<T extends BuilderProgram>(
state: SolutionBuilderState<T>,
project: ResolvedConfigFileName,
projectPath: ResolvedConfigFilePath,
projectIndex: number,
@ -2119,7 +2119,7 @@ function queueReferencingProjects(
}
}
function build(state: SolutionBuilderState, project?: string, cancellationToken?: CancellationToken, writeFile?: WriteFileCallback, getCustomTransformers?: (project: string) => CustomTransformers, onlyReferences?: boolean): ExitStatus {
function build<T extends BuilderProgram>(state: SolutionBuilderState<T>, project?: string, cancellationToken?: CancellationToken, writeFile?: WriteFileCallback, getCustomTransformers?: (project: string) => CustomTransformers, onlyReferences?: boolean): ExitStatus {
performance.mark("SolutionBuilder::beforeBuild");
const result = buildWorker(state, project, cancellationToken, writeFile, getCustomTransformers, onlyReferences);
performance.mark("SolutionBuilder::afterBuild");
@ -2127,7 +2127,7 @@ function build(state: SolutionBuilderState, project?: string, cancellationToken?
return result;
}
function buildWorker(state: SolutionBuilderState, project: string | undefined, cancellationToken: CancellationToken | undefined, writeFile: WriteFileCallback | undefined, getCustomTransformers: ((project: string) => CustomTransformers) | undefined, onlyReferences: boolean | undefined): ExitStatus {
function buildWorker<T extends BuilderProgram>(state: SolutionBuilderState<T>, project: string | undefined, cancellationToken: CancellationToken | undefined, writeFile: WriteFileCallback | undefined, getCustomTransformers: ((project: string) => CustomTransformers) | undefined, onlyReferences: boolean | undefined): ExitStatus {
const buildOrder = getBuildOrderFor(state, project, onlyReferences);
if (!buildOrder) return ExitStatus.InvalidProject_OutputsSkipped;
@ -2156,7 +2156,7 @@ function buildWorker(state: SolutionBuilderState, project: string | undefined, c
: ExitStatus.DiagnosticsPresent_OutputsSkipped;
}
function clean(state: SolutionBuilderState, project?: string, onlyReferences?: boolean): ExitStatus {
function clean<T extends BuilderProgram>(state: SolutionBuilderState<T>, project?: string, onlyReferences?: boolean): ExitStatus {
performance.mark("SolutionBuilder::beforeClean");
const result = cleanWorker(state, project, onlyReferences);
performance.mark("SolutionBuilder::afterClean");
@ -2164,7 +2164,7 @@ function clean(state: SolutionBuilderState, project?: string, onlyReferences?: b
return result;
}
function cleanWorker(state: SolutionBuilderState, project: string | undefined, onlyReferences: boolean | undefined) {
function cleanWorker<T extends BuilderProgram>(state: SolutionBuilderState<T>, project: string | undefined, onlyReferences: boolean | undefined) {
const buildOrder = getBuildOrderFor(state, project, onlyReferences);
if (!buildOrder) return ExitStatus.InvalidProject_OutputsSkipped;
@ -2208,7 +2208,7 @@ function cleanWorker(state: SolutionBuilderState, project: string | undefined, o
return ExitStatus.Success;
}
function invalidateProject(state: SolutionBuilderState, resolved: ResolvedConfigFilePath, reloadLevel: ConfigFileProgramReloadLevel) {
function invalidateProject<T extends BuilderProgram>(state: SolutionBuilderState<T>, resolved: ResolvedConfigFilePath, reloadLevel: ConfigFileProgramReloadLevel) {
// If host implements getParsedCommandLine, we cant get list of files from parseConfigFileHost
if (state.host.getParsedCommandLine && reloadLevel === ConfigFileProgramReloadLevel.Partial) {
reloadLevel = ConfigFileProgramReloadLevel.Full;
@ -2223,13 +2223,13 @@ function invalidateProject(state: SolutionBuilderState, resolved: ResolvedConfig
enableCache(state);
}
function invalidateProjectAndScheduleBuilds(state: SolutionBuilderState, resolvedPath: ResolvedConfigFilePath, reloadLevel: ConfigFileProgramReloadLevel) {
function invalidateProjectAndScheduleBuilds<T extends BuilderProgram>(state: SolutionBuilderState<T>, resolvedPath: ResolvedConfigFilePath, reloadLevel: ConfigFileProgramReloadLevel) {
state.reportFileChangeDetected = true;
invalidateProject(state, resolvedPath, reloadLevel);
scheduleBuildInvalidatedProject(state, 250, /*changeDetected*/ true);
}
function scheduleBuildInvalidatedProject(state: SolutionBuilderState, time: number, changeDetected: boolean) {
function scheduleBuildInvalidatedProject<T extends BuilderProgram>(state: SolutionBuilderState<T>, time: number, changeDetected: boolean) {
const { hostWithWatch } = state;
if (!hostWithWatch.setTimeout || !hostWithWatch.clearTimeout) {
return;
@ -2240,7 +2240,7 @@ function scheduleBuildInvalidatedProject(state: SolutionBuilderState, time: numb
state.timerToBuildInvalidatedProject = hostWithWatch.setTimeout(buildNextInvalidatedProject, time, state, changeDetected);
}
function buildNextInvalidatedProject(state: SolutionBuilderState, changeDetected: boolean) {
function buildNextInvalidatedProject<T extends BuilderProgram>(state: SolutionBuilderState<T>, changeDetected: boolean) {
performance.mark("SolutionBuilder::beforeBuild");
const buildOrder = buildNextInvalidatedProjectWorker(state, changeDetected);
performance.mark("SolutionBuilder::afterBuild");
@ -2248,7 +2248,7 @@ function buildNextInvalidatedProject(state: SolutionBuilderState, changeDetected
if (buildOrder) reportErrorSummary(state, buildOrder);
}
function buildNextInvalidatedProjectWorker(state: SolutionBuilderState, changeDetected: boolean) {
function buildNextInvalidatedProjectWorker<T extends BuilderProgram>(state: SolutionBuilderState<T>, changeDetected: boolean) {
state.timerToBuildInvalidatedProject = undefined;
if (state.reportFileChangeDetected) {
state.reportFileChangeDetected = false;
@ -2281,7 +2281,7 @@ function buildNextInvalidatedProjectWorker(state: SolutionBuilderState, changeDe
return buildOrder;
}
function watchConfigFile(state: SolutionBuilderState, resolved: ResolvedConfigFileName, resolvedPath: ResolvedConfigFilePath, parsed: ParsedCommandLine | undefined) {
function watchConfigFile<T extends BuilderProgram>(state: SolutionBuilderState<T>, resolved: ResolvedConfigFileName, resolvedPath: ResolvedConfigFilePath, parsed: ParsedCommandLine | undefined) {
if (!state.watch || state.allWatchedConfigFiles.has(resolvedPath)) return;
state.allWatchedConfigFiles.set(resolvedPath, watchFile(
state,
@ -2294,7 +2294,7 @@ function watchConfigFile(state: SolutionBuilderState, resolved: ResolvedConfigFi
));
}
function watchExtendedConfigFiles(state: SolutionBuilderState, resolvedPath: ResolvedConfigFilePath, parsed: ParsedCommandLine | undefined) {
function watchExtendedConfigFiles<T extends BuilderProgram>(state: SolutionBuilderState<T>, resolvedPath: ResolvedConfigFilePath, parsed: ParsedCommandLine | undefined) {
updateSharedExtendedConfigFileWatcher(
resolvedPath,
parsed?.options,
@ -2312,7 +2312,7 @@ function watchExtendedConfigFiles(state: SolutionBuilderState, resolvedPath: Res
);
}
function watchWildCardDirectories(state: SolutionBuilderState, resolved: ResolvedConfigFileName, resolvedPath: ResolvedConfigFilePath, parsed: ParsedCommandLine) {
function watchWildCardDirectories<T extends BuilderProgram>(state: SolutionBuilderState<T>, resolved: ResolvedConfigFileName, resolvedPath: ResolvedConfigFilePath, parsed: ParsedCommandLine) {
if (!state.watch) return;
updateWatchingWildcardDirectories(
getOrCreateValueMapFromConfigFileMap(state.allWatchedWildcardDirectories, resolvedPath),
@ -2343,7 +2343,7 @@ function watchWildCardDirectories(state: SolutionBuilderState, resolved: Resolve
);
}
function watchInputFiles(state: SolutionBuilderState, resolved: ResolvedConfigFileName, resolvedPath: ResolvedConfigFilePath, parsed: ParsedCommandLine) {
function watchInputFiles<T extends BuilderProgram>(state: SolutionBuilderState<T>, resolved: ResolvedConfigFileName, resolvedPath: ResolvedConfigFilePath, parsed: ParsedCommandLine) {
if (!state.watch) return;
mutateMap(
getOrCreateValueMapFromConfigFileMap(state.allWatchedInputFiles, resolvedPath),
@ -2363,7 +2363,7 @@ function watchInputFiles(state: SolutionBuilderState, resolved: ResolvedConfigFi
);
}
function watchPackageJsonFiles(state: SolutionBuilderState, resolved: ResolvedConfigFileName, resolvedPath: ResolvedConfigFilePath, parsed: ParsedCommandLine) {
function watchPackageJsonFiles<T extends BuilderProgram>(state: SolutionBuilderState<T>, resolved: ResolvedConfigFileName, resolvedPath: ResolvedConfigFilePath, parsed: ParsedCommandLine) {
if (!state.watch || !state.lastCachedPackageJsonLookups) return;
mutateMap(
getOrCreateValueMapFromConfigFileMap(state.allWatchedPackageJsonFiles, resolvedPath),
@ -2383,7 +2383,7 @@ function watchPackageJsonFiles(state: SolutionBuilderState, resolved: ResolvedCo
);
}
function startWatching(state: SolutionBuilderState, buildOrder: AnyBuildOrder) {
function startWatching<T extends BuilderProgram>(state: SolutionBuilderState<T>, buildOrder: AnyBuildOrder) {
if (!state.watchAllProjectsPending) return;
performance.mark("SolutionBuilder::beforeWatcherCreation");
state.watchAllProjectsPending = false;
@ -2408,7 +2408,7 @@ function startWatching(state: SolutionBuilderState, buildOrder: AnyBuildOrder) {
performance.measure("SolutionBuilder::Watcher creation", "SolutionBuilder::beforeWatcherCreation", "SolutionBuilder::afterWatcherCreation");
}
function stopWatching(state: SolutionBuilderState) {
function stopWatching<T extends BuilderProgram>(state: SolutionBuilderState<T>) {
clearMap(state.allWatchedConfigFiles, closeFileWatcher);
clearMap(state.allWatchedExtendedConfigFiles, closeFileWatcherOf);
clearMap(state.allWatchedWildcardDirectories, watchedWildcardDirectories => clearMap(watchedWildcardDirectories, closeFileWatcherOf));
@ -2444,23 +2444,23 @@ function createSolutionBuilderWorker<T extends BuilderProgram>(watch: boolean, h
};
}
function relName(state: SolutionBuilderState, path: string): string {
function relName<T extends BuilderProgram>(state: SolutionBuilderState<T>, path: string): string {
return convertToRelativePath(path, state.compilerHost.getCurrentDirectory(), state.compilerHost.getCanonicalFileName);
}
function reportStatus(state: SolutionBuilderState, message: DiagnosticMessage, ...args: string[]) {
function reportStatus<T extends BuilderProgram>(state: SolutionBuilderState<T>, message: DiagnosticMessage, ...args: string[]) {
state.host.reportSolutionBuilderStatus(createCompilerDiagnostic(message, ...args));
}
function reportWatchStatus(state: SolutionBuilderState, message: DiagnosticMessage, ...args: (string | number | undefined)[]) {
function reportWatchStatus<T extends BuilderProgram>(state: SolutionBuilderState<T>, message: DiagnosticMessage, ...args: (string | number | undefined)[]) {
state.hostWithWatch.onWatchStatusChange?.(createCompilerDiagnostic(message, ...args), state.host.getNewLine(), state.baseCompilerOptions);
}
function reportErrors({ host }: SolutionBuilderState, errors: readonly Diagnostic[]) {
function reportErrors<T extends BuilderProgram>({ host }: SolutionBuilderState<T>, errors: readonly Diagnostic[]) {
errors.forEach(err => host.reportDiagnostic(err));
}
function reportAndStoreErrors(state: SolutionBuilderState, proj: ResolvedConfigFilePath, errors: readonly Diagnostic[]) {
function reportAndStoreErrors<T extends BuilderProgram>(state: SolutionBuilderState<T>, proj: ResolvedConfigFilePath, errors: readonly Diagnostic[]) {
reportErrors(state, errors);
state.projectErrorsReported.set(proj, true);
if (errors.length) {
@ -2468,11 +2468,11 @@ function reportAndStoreErrors(state: SolutionBuilderState, proj: ResolvedConfigF
}
}
function reportParseConfigFileDiagnostic(state: SolutionBuilderState, proj: ResolvedConfigFilePath) {
function reportParseConfigFileDiagnostic<T extends BuilderProgram>(state: SolutionBuilderState<T>, proj: ResolvedConfigFilePath) {
reportAndStoreErrors(state, proj, [state.configFileCache.get(proj) as Diagnostic]);
}
function reportErrorSummary(state: SolutionBuilderState, buildOrder: AnyBuildOrder) {
function reportErrorSummary<T extends BuilderProgram>(state: SolutionBuilderState<T>, buildOrder: AnyBuildOrder) {
if (!state.needsSummary) return;
state.needsSummary = false;
const canReportSummary = state.watch || !!state.host.reportErrorSummary;
@ -2508,13 +2508,13 @@ function reportErrorSummary(state: SolutionBuilderState, buildOrder: AnyBuildOrd
/**
* Report the build ordering inferred from the current project graph if we're in verbose mode
*/
function reportBuildQueue(state: SolutionBuilderState, buildQueue: readonly ResolvedConfigFileName[]) {
function reportBuildQueue<T extends BuilderProgram>(state: SolutionBuilderState<T>, buildQueue: readonly ResolvedConfigFileName[]) {
if (state.options.verbose) {
reportStatus(state, Diagnostics.Projects_in_this_build_Colon_0, buildQueue.map(s => "\r\n * " + relName(state, s)).join(""));
}
}
function reportUpToDateStatus(state: SolutionBuilderState, configFileName: string, status: UpToDateStatus) {
function reportUpToDateStatus<T extends BuilderProgram>(state: SolutionBuilderState<T>, configFileName: string, status: UpToDateStatus) {
switch (status.type) {
case UpToDateStatusType.OutOfDateWithSelf:
return reportStatus(
@ -2642,7 +2642,7 @@ function reportUpToDateStatus(state: SolutionBuilderState, configFileName: strin
/**
* Report the up-to-date status of a project if we're in verbose mode
*/
function verboseReportProjectStatus(state: SolutionBuilderState, configFileName: string, status: UpToDateStatus) {
function verboseReportProjectStatus<T extends BuilderProgram>(state: SolutionBuilderState<T>, configFileName: string, status: UpToDateStatus) {
if (state.options.verbose) {
reportUpToDateStatus(state, configFileName, status);
}

Просмотреть файл

@ -8586,10 +8586,10 @@ export interface NodeFactory {
updateJSDocReadonlyTag(node: JSDocReadonlyTag, tagName: Identifier | undefined, comment: string | NodeArray<JSDocComment> | undefined): JSDocReadonlyTag;
createJSDocUnknownTag(tagName: Identifier, comment?: string | NodeArray<JSDocComment>): JSDocUnknownTag;
updateJSDocUnknownTag(node: JSDocUnknownTag, tagName: Identifier, comment: string | NodeArray<JSDocComment> | undefined): JSDocUnknownTag;
createJSDocDeprecatedTag(tagName: Identifier, comment?: string | NodeArray<JSDocComment>): JSDocDeprecatedTag;
updateJSDocDeprecatedTag(node: JSDocDeprecatedTag, tagName: Identifier, comment?: string | NodeArray<JSDocComment>): JSDocDeprecatedTag;
createJSDocOverrideTag(tagName: Identifier, comment?: string | NodeArray<JSDocComment>): JSDocOverrideTag;
updateJSDocOverrideTag(node: JSDocOverrideTag, tagName: Identifier, comment?: string | NodeArray<JSDocComment>): JSDocOverrideTag;
createJSDocDeprecatedTag(tagName: Identifier | undefined, comment?: string | NodeArray<JSDocComment>): JSDocDeprecatedTag;
updateJSDocDeprecatedTag(node: JSDocDeprecatedTag, tagName: Identifier | undefined, comment?: string | NodeArray<JSDocComment>): JSDocDeprecatedTag;
createJSDocOverrideTag(tagName: Identifier | undefined, comment?: string | NodeArray<JSDocComment>): JSDocOverrideTag;
updateJSDocOverrideTag(node: JSDocOverrideTag, tagName: Identifier | undefined, comment?: string | NodeArray<JSDocComment>): JSDocOverrideTag;
createJSDocThrowsTag(tagName: Identifier, typeExpression: JSDocTypeExpression | undefined, comment?: string | NodeArray<JSDocComment>): JSDocThrowsTag;
updateJSDocThrowsTag(node: JSDocThrowsTag, tagName: Identifier | undefined, typeExpression: JSDocTypeExpression | undefined, comment?: string | NodeArray<JSDocComment> | undefined): JSDocThrowsTag;
createJSDocSatisfiesTag(tagName: Identifier | undefined, typeExpression: JSDocTypeExpression, comment?: string | NodeArray<JSDocComment>): JSDocSatisfiesTag;
@ -8871,7 +8871,7 @@ export interface NodeFactory {
*
* @internal
*/
copyPrologue(source: readonly Statement[], target: Push<Statement>, ensureUseStrict?: boolean, visitor?: (node: Node) => VisitResult<Node>): number;
copyPrologue(source: readonly Statement[], target: Push<Statement>, ensureUseStrict?: boolean, visitor?: (node: Node) => VisitResult<Node | undefined>): number;
/**
* Copies only the standard (string-expression) prologue-directives into the target statement-array.
* @param source origin statements array
@ -8891,8 +8891,8 @@ export interface NodeFactory {
*
* @internal
*/
copyCustomPrologue(source: readonly Statement[], target: Push<Statement>, statementOffset: number, visitor?: (node: Node) => VisitResult<Node>, filter?: (node: Node) => boolean): number;
/** @internal */ copyCustomPrologue(source: readonly Statement[], target: Push<Statement>, statementOffset: number | undefined, visitor?: (node: Node) => VisitResult<Node>, filter?: (node: Node) => boolean): number | undefined;
copyCustomPrologue(source: readonly Statement[], target: Push<Statement>, statementOffset: number, visitor?: (node: Node) => VisitResult<Node | undefined>, filter?: (node: Statement) => boolean): number;
/** @internal */ copyCustomPrologue(source: readonly Statement[], target: Push<Statement>, statementOffset: number | undefined, visitor?: (node: Node) => VisitResult<Node | undefined>, filter?: (node: Statement) => boolean): number | undefined;
/** @internal */ ensureUseStrict(statements: NodeArray<Statement>): NodeArray<Statement>;
/** @internal */ liftToBlock(nodes: readonly Node[]): Statement;
/**
@ -9068,19 +9068,64 @@ export type Transformer<T extends Node> = (node: T) => T;
/**
* A function that accepts and possibly transforms a node.
*/
export type Visitor = (node: Node) => VisitResult<Node>;
export type Visitor<TIn extends Node = Node, TOut extends Node | undefined = TIn | undefined> = (node: TIn) => VisitResult<TOut>;
/**
* A function that walks a node using the given visitor, lifting node arrays into single nodes,
* returning an node which satisfies the test.
*
* - If the input node is undefined, then the output is undefined.
* - If the visitor returns undefined, then the output is undefined.
* - If the output node is not undefined, then it will satisfy the test function.
* - In order to obtain a return type that is more specific than `Node`, a test
* function _must_ be provided, and that function must be a type predicate.
*
* For the canonical implementation of this type, @see {visitNode}.
*/
export interface NodeVisitor {
<T extends Node>(nodes: T, visitor: Visitor | undefined, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => T): T;
<T extends Node>(nodes: T | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => T): T | undefined;
<TIn extends Node | undefined, TVisited extends Node | undefined, TOut extends Node>(
node: TIn,
visitor: Visitor<NonNullable<TIn>, TVisited>,
test: (node: Node) => node is TOut,
lift?: (node: readonly Node[]) => Node,
): TOut | (TIn & undefined) | (TVisited & undefined);
<TIn extends Node | undefined, TVisited extends Node | undefined>(
node: TIn,
visitor: Visitor<NonNullable<TIn>, TVisited>,
test?: (node: Node) => boolean,
lift?: (node: readonly Node[]) => Node,
): Node | (TIn & undefined) | (TVisited & undefined);
}
/**
* A function that walks a node array using the given visitor, returning an array whose contents satisfy the test.
*
* - If the input node array is undefined, the output is undefined.
* - If the visitor can return undefined, the node it visits in the array will be reused.
* - If the output node array is not undefined, then its contents will satisfy the test.
* - In order to obtain a return type that is more specific than `NodeArray<Node>`, a test
* function _must_ be provided, and that function must be a type predicate.
*
* For the canonical implementation of this type, @see {visitNodes}.
*/
export interface NodesVisitor {
<T extends Node>(nodes: NodeArray<T>, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray<T>;
<T extends Node>(nodes: NodeArray<T> | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray<T> | undefined;
<TIn extends Node, TInArray extends NodeArray<TIn> | undefined, TOut extends Node>(
nodes: TInArray,
visitor: Visitor<TIn, Node | undefined>,
test: (node: Node) => node is TOut,
start?: number,
count?: number,
): NodeArray<TOut> | (TInArray & undefined);
<TIn extends Node, TInArray extends NodeArray<TIn> | undefined>(
nodes: TInArray,
visitor: Visitor<TIn, Node | undefined>,
test?: (node: Node) => boolean,
start?: number,
count?: number,
): NodeArray<Node> | (TInArray & undefined);
}
export type VisitResult<T extends Node> = T | readonly T[] | undefined;
export type VisitResult<T extends Node | undefined> = T | readonly Node[];
export interface Printer {
/**

Просмотреть файл

@ -848,7 +848,7 @@ export function getSourceFileOfNode(node: Node): SourceFile;
/** @internal */
export function getSourceFileOfNode(node: Node | undefined): SourceFile | undefined;
/** @internal */
export function getSourceFileOfNode(node: Node): SourceFile {
export function getSourceFileOfNode(node: Node | undefined): SourceFile | undefined {
while (node && node.kind !== SyntaxKind.SourceFile) {
node = node.parent;
}
@ -1528,9 +1528,8 @@ export function isBlockScope(node: Node, parentNode: Node | undefined): boolean
}
/** @internal */
export function isDeclarationWithTypeParameters(node: Node): node is DeclarationWithTypeParameters;
/** @internal */
export function isDeclarationWithTypeParameters(node: DeclarationWithTypeParameters): node is DeclarationWithTypeParameters {
export function isDeclarationWithTypeParameters(node: Node): node is DeclarationWithTypeParameters {
Debug.type<DeclarationWithTypeParameters>(node);
switch (node.kind) {
case SyntaxKind.JSDocCallbackTag:
case SyntaxKind.JSDocTypedefTag:
@ -1543,9 +1542,8 @@ export function isDeclarationWithTypeParameters(node: DeclarationWithTypeParamet
}
/** @internal */
export function isDeclarationWithTypeParameterChildren(node: Node): node is DeclarationWithTypeParameterChildren;
/** @internal */
export function isDeclarationWithTypeParameterChildren(node: DeclarationWithTypeParameterChildren): node is DeclarationWithTypeParameterChildren {
export function isDeclarationWithTypeParameterChildren(node: Node): node is DeclarationWithTypeParameterChildren {
Debug.type<DeclarationWithTypeParameterChildren>(node);
switch (node.kind) {
case SyntaxKind.CallSignature:
case SyntaxKind.ConstructSignature:
@ -4533,8 +4531,20 @@ export function isPushOrUnshiftIdentifier(node: Identifier) {
return node.escapedText === "push" || node.escapedText === "unshift";
}
/** @internal */
export function isParameterDeclaration(node: VariableLikeDeclaration): boolean {
// TODO(jakebailey): this function should not be named this. While it does technically
// return true if the argument is a ParameterDeclaration, it also returns true for nodes
// that are children of ParameterDeclarations inside binding elements.
// Probably, this should be called `rootDeclarationIsParameter`.
/**
* This function returns true if the this node's root declaration is a parameter.
* For example, passing a `ParameterDeclaration` will return true, as will passing a
* binding element that is a child of a `ParameterDeclaration`.
*
* If you are looking to test that a `Node` is a `ParameterDeclaration`, use `isParameter`.
*
* @internal
*/
export function isParameterDeclaration(node: Declaration): boolean {
const root = getRootDeclaration(node);
return root.kind === SyntaxKind.Parameter;
}
@ -6833,8 +6843,9 @@ export function getInitializedVariables(node: VariableDeclarationList) {
return filter(node.declarations, isInitializedVariable);
}
function isInitializedVariable(node: VariableDeclaration): node is InitializedVariableDeclaration {
return node.initializer !== undefined;
/** @internal */
export function isInitializedVariable(node: Node): node is InitializedVariableDeclaration {
return isVariableDeclaration(node) && node.initializer !== undefined;
}
/** @internal */
@ -7147,6 +7158,7 @@ export function isTypeNodeKind(kind: SyntaxKind): kind is TypeNodeSyntaxKind {
|| kind === SyntaxKind.VoidKeyword
|| kind === SyntaxKind.UndefinedKeyword
|| kind === SyntaxKind.NeverKeyword
|| kind === SyntaxKind.IntrinsicKeyword
|| kind === SyntaxKind.ExpressionWithTypeArguments
|| kind === SyntaxKind.JSDocAllType
|| kind === SyntaxKind.JSDocUnknownType
@ -7276,11 +7288,11 @@ export function getLeftmostExpression(node: Expression, stopAtCallExpressions: b
/** @internal */
export interface ObjectAllocator {
getNodeConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => Node;
getTokenConstructor(): new <TKind extends SyntaxKind>(kind: TKind, pos?: number, end?: number) => Token<TKind>;
getIdentifierConstructor(): new (kind: SyntaxKind.Identifier, pos?: number, end?: number) => Identifier;
getPrivateIdentifierConstructor(): new (kind: SyntaxKind.PrivateIdentifier, pos?: number, end?: number) => PrivateIdentifier;
getSourceFileConstructor(): new (kind: SyntaxKind.SourceFile, pos?: number, end?: number) => SourceFile;
getNodeConstructor(): new (kind: SyntaxKind, pos: number, end: number) => Node;
getTokenConstructor(): new <TKind extends SyntaxKind>(kind: TKind, pos: number, end: number) => Token<TKind>;
getIdentifierConstructor(): new (kind: SyntaxKind.Identifier, pos: number, end: number) => Identifier;
getPrivateIdentifierConstructor(): new (kind: SyntaxKind.PrivateIdentifier, pos: number, end: number) => PrivateIdentifier;
getSourceFileConstructor(): new (kind: SyntaxKind.SourceFile, pos: number, end: number) => SourceFile;
getSymbolConstructor(): new (flags: SymbolFlags, name: __String) => Symbol;
getTypeConstructor(): new (checker: TypeChecker, flags: TypeFlags) => Type;
getSignatureConstructor(): new (checker: TypeChecker, flags: SignatureFlags) => Signature;
@ -8735,7 +8747,7 @@ export function isAnySupportedFileExtension(path: string): boolean {
/** @internal */
export function tryGetExtensionFromPath(path: string): Extension | undefined {
return find<Extension>(extensionsToRemove, e => fileExtensionIs(path, e));
return find(extensionsToRemove, e => fileExtensionIs(path, e));
}
/** @internal */

Просмотреть файл

@ -3,6 +3,7 @@ import {
AccessExpression,
AccessorDeclaration,
ArrayBindingElement,
ArrayBindingOrAssignmentElement,
ArrayBindingOrAssignmentPattern,
AssertionExpression,
AssertionKey,
@ -98,6 +99,7 @@ import {
isAmbientModule,
isAnyImportOrReExport,
isArrowFunction,
isAssignmentExpression,
isBinaryExpression,
isBindableStaticElementAccessExpression,
isBindingElement,
@ -220,6 +222,7 @@ import {
NonNullChain,
normalizePath,
NotEmittedStatement,
NullLiteral,
ObjectBindingOrAssignmentElement,
ObjectBindingOrAssignmentPattern,
ObjectLiteralElement,
@ -545,7 +548,10 @@ export function isEmptyBindingPattern(node: BindingName): node is BindingPattern
return false;
}
export function isEmptyBindingElement(node: BindingElement): boolean {
// TODO(jakebailey): It is very weird that we have BindingElement and ArrayBindingElement;
// we should have ObjectBindingElement and ArrayBindingElement, which are both BindingElement,
// just like BindingPattern is a ObjectBindingPattern or a ArrayBindingPattern.
export function isEmptyBindingElement(node: BindingElement | ArrayBindingElement): boolean {
if (isOmittedExpression(node)) {
return true;
}
@ -676,15 +682,19 @@ export function validateLocaleAndSetLanguage(
export function getOriginalNode(node: Node): Node;
export function getOriginalNode<T extends Node>(node: Node, nodeTest: (node: Node) => node is T): T;
export function getOriginalNode(node: Node | undefined): Node | undefined;
export function getOriginalNode<T extends Node>(node: Node | undefined, nodeTest: (node: Node | undefined) => node is T): T | undefined;
export function getOriginalNode(node: Node | undefined, nodeTest?: (node: Node | undefined) => boolean): Node | undefined {
export function getOriginalNode<T extends Node>(node: Node | undefined, nodeTest: (node: Node) => node is T): T | undefined;
export function getOriginalNode<T extends Node>(node: Node | undefined, nodeTest?: (node: Node) => node is T): T | undefined {
if (node) {
while (node.original !== undefined) {
node = node.original;
}
}
return !nodeTest || nodeTest(node) ? node : undefined;
if (!node || !nodeTest) {
return node as T | undefined;
}
return nodeTest(node) ? node : undefined;
}
/**
@ -695,7 +705,7 @@ export function getOriginalNode(node: Node | undefined, nodeTest?: (node: Node |
*/
export function findAncestor<T extends Node>(node: Node | undefined, callback: (element: Node) => element is T): T | undefined;
export function findAncestor(node: Node | undefined, callback: (element: Node) => boolean | "quit"): Node | undefined;
export function findAncestor(node: Node, callback: (element: Node) => boolean | "quit"): Node | undefined {
export function findAncestor(node: Node | undefined, callback: (element: Node) => boolean | "quit"): Node | undefined {
while (node) {
const result = callback(node);
if (result === "quit") {
@ -1784,6 +1794,14 @@ export function isDeclarationBindingElement(bindingElement: BindingOrAssignmentE
return false;
}
/** @internal */
export function isBindingOrAssignmentElement(node: Node): node is BindingOrAssignmentElement {
return isVariableDeclaration(node)
|| isParameter(node)
|| isObjectBindingOrAssignmentElement(node)
|| isArrayBindingOrAssignmentElement(node);
}
/**
* Determines whether a node is a BindingOrAssignmentPattern
*
@ -1836,6 +1854,22 @@ export function isArrayBindingOrAssignmentPattern(node: BindingOrAssignmentEleme
return false;
}
/** @internal */
export function isArrayBindingOrAssignmentElement(node: Node): node is ArrayBindingOrAssignmentElement {
switch (node.kind) {
case SyntaxKind.BindingElement:
case SyntaxKind.OmittedExpression: // Elision
case SyntaxKind.SpreadElement: // AssignmentRestElement
case SyntaxKind.ArrayLiteralExpression: // ArrayAssignmentPattern
case SyntaxKind.ObjectLiteralExpression: // ObjectAssignmentPattern
case SyntaxKind.Identifier: // DestructuringAssignmentTarget
case SyntaxKind.PropertyAccessExpression: // DestructuringAssignmentTarget
case SyntaxKind.ElementAccessExpression: // DestructuringAssignmentTarget
return true;
}
return isAssignmentExpression(node, /*excludeCompoundAssignment*/ true); // AssignmentElement
}
/** @internal */
export function isPropertyAccessOrQualifiedNameOrImportTypeNode(node: Node): node is PropertyAccessExpression | QualifiedName | ImportTypeNode {
const kind = node.kind;
@ -1952,6 +1986,23 @@ export function isUnaryExpressionWithWrite(expr: Node): expr is PrefixUnaryExpre
}
}
/**
* See isExpression; not for use in transforms.
* @internal
*/
export function isLiteralTypeLiteral(node: Node): node is NullLiteral | BooleanLiteral | LiteralExpression | PrefixUnaryExpression {
node = skipPartiallyEmittedExpressions(node);
switch (skipPartiallyEmittedExpressions(node).kind) {
case SyntaxKind.NullKeyword:
case SyntaxKind.TrueKeyword:
case SyntaxKind.FalseKeyword:
case SyntaxKind.PrefixUnaryExpression:
return true;
default:
return isLiteralExpression(node);
}
}
/**
* Determines whether a node is an expression based only on its kind.
* Use `isExpressionNode` if not in transforms.

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -234,7 +234,11 @@ export function getFilesInErrorForSummary(diagnostics: readonly Diagnostic[]): (
if (errorDiagnostic.file === undefined) return;
return `${errorDiagnostic.file.fileName}`;
});
return filesInError.map((fileName: string) => {
return filesInError.map((fileName) => {
if (fileName === undefined) {
return undefined;
}
const diagnosticForFileName = find(diagnostics, diagnostic =>
diagnostic.file !== undefined && diagnostic.file.fileName === fileName
);

Просмотреть файл

@ -378,6 +378,11 @@ interface ParsedConfig {
reloadLevel?: ConfigFileProgramReloadLevel.Partial | ConfigFileProgramReloadLevel.Full;
}
// All of one and partial of the other, or vice versa.
type WatchCompilerHostOfFilesAndCompilerOptionsOrConfigFile<T extends BuilderProgram> =
| WatchCompilerHostOfFilesAndCompilerOptions<T> & Partial<WatchCompilerHostOfConfigFile<T>>
| WatchCompilerHostOfConfigFile<T> & Partial<WatchCompilerHostOfFilesAndCompilerOptions<T>>;
/**
* Creates the watch from the host for root files and compiler options
*/
@ -386,7 +391,7 @@ export function createWatchProgram<T extends BuilderProgram>(host: WatchCompiler
* Creates the watch from the host for config file
*/
export function createWatchProgram<T extends BuilderProgram>(host: WatchCompilerHostOfConfigFile<T>): WatchOfConfigFile<T>;
export function createWatchProgram<T extends BuilderProgram>(host: WatchCompilerHostOfFilesAndCompilerOptions<T> & WatchCompilerHostOfConfigFile<T>): WatchOfFilesAndCompilerOptions<T> | WatchOfConfigFile<T> {
export function createWatchProgram<T extends BuilderProgram>(host: WatchCompilerHostOfFilesAndCompilerOptionsOrConfigFile<T>): WatchOfFilesAndCompilerOptions<T> | WatchOfConfigFile<T> {
interface FilePresentOnHost {
version: string;
sourceFile: SourceFile;
@ -442,6 +447,9 @@ export function createWatchProgram<T extends BuilderProgram>(host: WatchCompiler
newLine = updateNewLine();
}
Debug.assert(compilerOptions);
Debug.assert(rootFileNames);
const { watchFile, watchDirectory, writeLog } = createWatchFactory(host, compilerOptions);
const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames);
@ -451,7 +459,7 @@ export function createWatchProgram<T extends BuilderProgram>(host: WatchCompiler
configFileWatcher = watchFile(configFileName, scheduleProgramReload, PollingInterval.High, watchOptions, WatchType.ConfigFile);
}
const compilerHost = createCompilerHostFromProgramHost(host, () => compilerOptions, directoryStructureHost) as CompilerHost & ResolutionCacheHost;
const compilerHost = createCompilerHostFromProgramHost(host, () => compilerOptions!, directoryStructureHost) as CompilerHost & ResolutionCacheHost;
setGetSourceFileAsHashVersioned(compilerHost);
// Members for CompilerHost
const getNewSourceFile = compilerHost.getSourceFile;
@ -463,7 +471,7 @@ export function createWatchProgram<T extends BuilderProgram>(host: WatchCompiler
compilerHost.onReleaseParsedCommandLine = onReleaseParsedCommandLine;
// Members for ResolutionCacheHost
compilerHost.toPath = toPath;
compilerHost.getCompilationSettings = () => compilerOptions;
compilerHost.getCompilationSettings = () => compilerOptions!;
compilerHost.useSourceOfProjectReferenceRedirect = maybeBind(host, host.useSourceOfProjectReferenceRedirect);
compilerHost.watchDirectoryOfFailedLookupLocation = (dir, cb, flags) => watchDirectory(dir, cb, flags, watchOptions, WatchType.FailedLookupLocations);
compilerHost.watchAffectingFileLocation = (file, cb) => watchFile(file, cb, PollingInterval.High, watchOptions, WatchType.AffectingFileLocation);
@ -566,6 +574,10 @@ export function createWatchProgram<T extends BuilderProgram>(host: WatchCompiler
function synchronizeProgram() {
writeLog(`Synchronizing program`);
Debug.assert(compilerOptions);
Debug.assert(rootFileNames);
clearInvalidateResolutionsOfFailedLookupLocations();
const program = getCurrentBuilderProgram();
@ -849,6 +861,10 @@ export function createWatchProgram<T extends BuilderProgram>(host: WatchCompiler
function reloadFileNamesFromConfigFile() {
writeLog("Reloading new file names and options");
Debug.assert(compilerOptions);
Debug.assert(configFileName);
reloadLevel = ConfigFileProgramReloadLevel.None;
rootFileNames = getFileNamesFromConfigSpecs(compilerOptions.configFile!.configFileSpecs!, getNormalizedAbsolutePath(getDirectoryPath(configFileName), currentDirectory), compilerOptions, parseConfigFileHost, extraFileExtensions);
if (updateErrorForNoInputFiles(rootFileNames, getNormalizedAbsolutePath(configFileName, currentDirectory), compilerOptions.configFile!.configFileSpecs!, configFileParsingDiagnostics!, canConfigFileJsonReportNoInputFiles)) {
@ -860,6 +876,7 @@ export function createWatchProgram<T extends BuilderProgram>(host: WatchCompiler
}
function reloadConfigFile() {
Debug.assert(configFileName);
writeLog(`Reloading config file: ${configFileName}`);
reloadLevel = ConfigFileProgramReloadLevel.None;
@ -878,6 +895,7 @@ export function createWatchProgram<T extends BuilderProgram>(host: WatchCompiler
}
function parseConfigFile() {
Debug.assert(configFileName);
setConfigFileParsingResult(getParsedCommandLineOfConfigFile(
configFileName,
optionsToExtendForConfigFile,
@ -907,6 +925,7 @@ export function createWatchProgram<T extends BuilderProgram>(host: WatchCompiler
// With host implementing getParsedCommandLine we cant just update file names
if (config.parsedCommandLine && config.reloadLevel === ConfigFileProgramReloadLevel.Partial && !host.getParsedCommandLine) {
writeLog("Reloading new file names and options");
Debug.assert(compilerOptions);
const fileNames = getFileNamesFromConfigSpecs(
config.parsedCommandLine.options.configFile!.configFileSpecs!,
getNormalizedAbsolutePath(getDirectoryPath(configFileName), currentDirectory),
@ -1029,7 +1048,8 @@ export function createWatchProgram<T extends BuilderProgram>(host: WatchCompiler
return watchDirectory(
directory,
fileOrDirectory => {
Debug.assert(!!configFileName);
Debug.assert(configFileName);
Debug.assert(compilerOptions);
const fileOrDirectoryPath = toPath(fileOrDirectory);
@ -1068,6 +1088,7 @@ export function createWatchProgram<T extends BuilderProgram>(host: WatchCompiler
}
function updateExtendedConfigFilesWatches(forProjectPath: Path, options: CompilerOptions | undefined, watchOptions: WatchOptions | undefined, watchType: WatchTypeRegistry["ExtendedConfigFile"] | WatchTypeRegistry["ExtendedConfigOfReferencedProject"]) {
Debug.assert(configFileName);
updateSharedExtendedConfigFileWatcher(
forProjectPath,
options,

Просмотреть файл

@ -546,7 +546,7 @@ export class SolutionBuilderHost extends CompilerHost implements ts.SolutionBuil
private constructor(sys: System | vfs.FileSystem, options?: ts.CompilerOptions, setParentNodes?: boolean, createProgram?: ts.CreateProgram<ts.BuilderProgram>) {
super(sys, options, setParentNodes);
this.createProgram = createProgram || ts.createEmitAndSemanticDiagnosticsBuilderProgram;
this.createProgram = createProgram || ts.createEmitAndSemanticDiagnosticsBuilderProgram as unknown as ts.CreateProgram<ts.BuilderProgram>;
}
static create(sys: System | vfs.FileSystem, options?: ts.CompilerOptions, setParentNodes?: boolean, createProgram?: ts.CreateProgram<ts.BuilderProgram>) {

Просмотреть файл

@ -524,7 +524,7 @@ export class TestState {
public verifyErrorExistsBetweenMarkers(startMarkerName: string, endMarkerName: string, shouldExist: boolean) {
const startMarker = this.getMarkerByName(startMarkerName);
const endMarker = this.getMarkerByName(endMarkerName);
const predicate = (errorMinChar: number, errorLimChar: number, startPos: number, endPos: number) =>
const predicate = (errorMinChar: number, errorLimChar: number, startPos: number, endPos: number | undefined) =>
((errorMinChar === startPos) && (errorLimChar === endPos)) ? true : false;
const exists = this.anyErrorInRange(predicate, startMarker, endMarker);
@ -578,7 +578,7 @@ export class TestState {
public verifyErrorExistsAfterMarker(markerName: string, shouldExist: boolean, after: boolean) {
const marker: Marker = this.getMarkerByName(markerName);
let predicate: (errorMinChar: number, errorLimChar: number, startPos: number, endPos: number) => boolean;
let predicate: (errorMinChar: number, errorLimChar: number, startPos: number, endPos: number | undefined) => boolean;
if (after) {
predicate = (errorMinChar: number, errorLimChar: number, startPos: number) =>
@ -867,7 +867,8 @@ export class TestState {
const hints = this.languageService.provideInlayHints(this.activeFile.fileName, span, preference);
assert.equal(hints.length, expected.length, "Number of hints");
const sortHints = (a: ts.InlayHint, b: ts.InlayHint) => {
interface HasPosition { position: number; }
const sortHints = (a: HasPosition, b: HasPosition) => {
return a.position - b.position;
};
ts.zipWith(hints.sort(sortHints), [...expected].sort(sortHints), (actual, expected) => {

Просмотреть файл

@ -3,7 +3,6 @@ import * as fakes from "./_namespaces/fakes";
import * as vfs from "./_namespaces/vfs";
import * as collections from "./_namespaces/collections";
import * as vpath from "./_namespaces/vpath";
import * as Utils from "./_namespaces/Utils";
import {
Compiler,
harnessNewLine,
@ -1015,7 +1014,7 @@ export class ServerLanguageServiceAdapter implements LanguageServiceAdapter {
useSingleInferredProject: false,
useInferredProjectPerProjectRoot: false,
typingsInstaller: { ...ts.server.nullTypingsInstaller, globalTypingsCacheLocation: "/Library/Caches/typescript" },
byteLength: Utils.byteLength,
byteLength: Buffer.byteLength,
hrtime: process.hrtime,
logger: serverHost,
canUseEvents: true

Просмотреть файл

@ -5,11 +5,6 @@ export function encodeString(s: string): string {
return ts.sys.bufferFrom!(s).toString("utf8");
}
export function byteLength(s: string, encoding?: string): number {
// stub implementation if Buffer is not available (in-browser case)
return Buffer.byteLength(s, encoding as ts.BufferEncoding | undefined);
}
export function evalFile(fileContents: string, fileName: string, nodeContext?: any) {
const vm = require("vm");
if (nodeContext) {

Просмотреть файл

@ -733,7 +733,7 @@ function forEachResolvedProjectReferenceProjectWorker<T>(
function forEachPotentialProjectReference<T>(
project: ConfiguredProject,
cb: (potentialProjectReference: Path) => T | undefined
cb: (potentialProjectReference: NormalizedPath) => T | undefined
): T | undefined {
return project.potentialProjectReferences &&
forEachKey(project.potentialProjectReferences, cb);
@ -743,7 +743,7 @@ function forEachAnyProjectReferenceKind<T>(
project: ConfiguredProject,
cb: (resolvedProjectReference: ResolvedProjectReference) => T | undefined,
cbProjectRef: (projectReference: ProjectReference) => T | undefined,
cbPotentialProjectRef: (potentialProjectReference: Path) => T | undefined
cbPotentialProjectRef: (potentialProjectReference: NormalizedPath) => T | undefined
): T | undefined {
return project.getCurrentProgram() ?
project.forEachResolvedProjectReference(cb) :
@ -752,10 +752,10 @@ function forEachAnyProjectReferenceKind<T>(
forEach(project.getProjectReferences(), cbProjectRef);
}
function callbackRefProject<T>(
function callbackRefProject<T, P extends string>(
project: ConfiguredProject,
cb: (refProj: ConfiguredProject) => T | undefined,
refPath: Path | undefined
refPath: P | undefined
) {
const refProject = refPath && project.projectService.configuredProjects.get(refPath);
return refProject && cb(refProject);

Просмотреть файл

@ -2548,7 +2548,7 @@ export class ConfiguredProject extends Project {
*
* @internal
*/
potentialProjectReferences: Set<string> | undefined;
potentialProjectReferences: Set<NormalizedPath> | undefined;
/** @internal */
projectOptions?: ProjectOptions | true;

Просмотреть файл

@ -1,6 +1,7 @@
import {
arrayFrom,
arrayReverseIterator,
BufferEncoding,
CallHierarchyIncomingCall,
CallHierarchyItem,
CallHierarchyOutgoingCall,
@ -194,7 +195,7 @@ export const nullCancellationToken: ServerCancellationToken = {
resetRequest: () => void 0
};
function hrTimeToMilliseconds(time: number[]): number {
function hrTimeToMilliseconds(time: [number, number]): number {
const seconds = time[0];
const nanoseconds = time[1];
return ((1e9 * seconds) + nanoseconds) / 1000000.0;
@ -307,7 +308,7 @@ function allEditsBeforePos(edits: readonly TextChange[], pos: number): boolean {
export type CommandNames = protocol.CommandTypes;
export const CommandNames = (protocol as any).CommandTypes;
export function formatMessage<T extends protocol.Message>(msg: T, logger: Logger, byteLength: (s: string, encoding: string) => number, newLine: string): string {
export function formatMessage<T extends protocol.Message>(msg: T, logger: Logger, byteLength: (s: string, encoding: BufferEncoding) => number, newLine: string): string {
const verboseLogging = logger.hasLevel(LogLevel.verbose);
const json = JSON.stringify(msg);
@ -915,8 +916,8 @@ export interface SessionOptions {
useSingleInferredProject: boolean;
useInferredProjectPerProjectRoot: boolean;
typingsInstaller: ITypingsInstaller;
byteLength: (buf: string, encoding?: string) => number;
hrtime: (start?: number[]) => number[];
byteLength: (buf: string, encoding?: BufferEncoding) => number;
hrtime: (start?: [number, number]) => [number, number];
logger: Logger;
/**
* If falsy, all events are suppressed.
@ -950,8 +951,8 @@ export class Session<TMessage = string> implements EventSender {
protected host: ServerHost;
private readonly cancellationToken: ServerCancellationToken;
protected readonly typingsInstaller: ITypingsInstaller;
protected byteLength: (buf: string, encoding?: string) => number;
private hrtime: (start?: number[]) => number[];
protected byteLength: (buf: string, encoding?: BufferEncoding) => number;
private hrtime: (start?: [number, number]) => [number, number];
protected logger: Logger;
protected canUseEvents: boolean;
@ -3099,7 +3100,7 @@ export class Session<TMessage = string> implements EventSender {
return { response, responseRequired: true };
}
private handlers = new Map(Object.entries<(request: protocol.Request) => HandlerResponse>({
private handlers = new Map(Object.entries<(request: any) => HandlerResponse>({ // TODO(jakebailey): correctly type the handlers
[CommandNames.Status]: () => {
const response: protocol.StatusResponseBody = { version };
return this.requiredResponse(response);
@ -3544,7 +3545,7 @@ export class Session<TMessage = string> implements EventSender {
this.performanceData = undefined;
let start: number[] | undefined;
let start: [number, number] | undefined;
if (this.logger.hasLevel(LogLevel.requestTime)) {
start = this.hrtime();
if (this.logger.hasLevel(LogLevel.verbose)) {

Просмотреть файл

@ -17,6 +17,7 @@ import {
isJSDocIndexSignature,
isOptionalJSDocPropertyLikeTag,
isParameter,
isTypeNode,
JSDocFunctionType,
JSDocNonNullableType,
JSDocNullableType,
@ -35,7 +36,6 @@ import {
SyntaxKind,
textChanges,
tryCast,
TypeNode,
TypeReferenceNode,
VariableDeclaration,
visitEachChild,
@ -100,19 +100,19 @@ function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, de
for (const param of decl.parameters) {
if (!param.type) {
const paramType = getJSDocType(param);
if (paramType) changes.tryInsertTypeAnnotation(sourceFile, param, transformJSDocType(paramType));
if (paramType) changes.tryInsertTypeAnnotation(sourceFile, param, visitNode(paramType, transformJSDocType, isTypeNode));
}
}
if (needParens) changes.insertNodeAfter(sourceFile, last(decl.parameters), factory.createToken(SyntaxKind.CloseParenToken));
if (!decl.type) {
const returnType = getJSDocReturnType(decl);
if (returnType) changes.tryInsertTypeAnnotation(sourceFile, decl, transformJSDocType(returnType));
if (returnType) changes.tryInsertTypeAnnotation(sourceFile, decl, visitNode(returnType, transformJSDocType, isTypeNode));
}
}
else {
const jsdocType = Debug.checkDefined(getJSDocType(decl), "A JSDocType for this declaration should exist"); // If not defined, shouldn't have been an error to fix
Debug.assert(!decl.type, "The JSDocType decl should have a type"); // If defined, shouldn't have been an error to fix.
changes.tryInsertTypeAnnotation(sourceFile, decl, transformJSDocType(jsdocType));
changes.tryInsertTypeAnnotation(sourceFile, decl, visitNode(jsdocType, transformJSDocType, isTypeNode));
}
}
@ -123,7 +123,7 @@ function isDeclarationWithType(node: Node): node is DeclarationWithType {
node.kind === SyntaxKind.PropertyDeclaration;
}
function transformJSDocType(node: TypeNode): TypeNode {
function transformJSDocType(node: Node): Node {
switch (node.kind) {
case SyntaxKind.JSDocAllType:
case SyntaxKind.JSDocUnknownType:
@ -155,21 +155,21 @@ function transformJSDocTypeLiteral(node: JSDocTypeLiteral) {
/*modifiers*/ undefined,
isIdentifier(tag.name) ? tag.name : tag.name.right,
isOptionalJSDocPropertyLikeTag(tag) ? factory.createToken(SyntaxKind.QuestionToken) : undefined,
tag.typeExpression && visitNode(tag.typeExpression.type, transformJSDocType) || factory.createKeywordTypeNode(SyntaxKind.AnyKeyword))));
tag.typeExpression && visitNode(tag.typeExpression.type, transformJSDocType, isTypeNode) || factory.createKeywordTypeNode(SyntaxKind.AnyKeyword))));
setEmitFlags(typeNode, EmitFlags.SingleLine);
return typeNode;
}
function transformJSDocOptionalType(node: JSDocOptionalType) {
return factory.createUnionTypeNode([visitNode(node.type, transformJSDocType), factory.createTypeReferenceNode("undefined", emptyArray)]);
return factory.createUnionTypeNode([visitNode(node.type, transformJSDocType, isTypeNode), factory.createTypeReferenceNode("undefined", emptyArray)]);
}
function transformJSDocNullableType(node: JSDocNullableType) {
return factory.createUnionTypeNode([visitNode(node.type, transformJSDocType), factory.createTypeReferenceNode("null", emptyArray)]);
return factory.createUnionTypeNode([visitNode(node.type, transformJSDocType, isTypeNode), factory.createTypeReferenceNode("null", emptyArray)]);
}
function transformJSDocVariadicType(node: JSDocVariadicType) {
return factory.createArrayTypeNode(visitNode(node.type, transformJSDocType));
return factory.createArrayTypeNode(visitNode(node.type, transformJSDocType, isTypeNode));
}
function transformJSDocFunctionType(node: JSDocFunctionType) {
@ -183,7 +183,7 @@ function transformJSDocParameter(node: ParameterDeclaration) {
const isRest = node.type!.kind === SyntaxKind.JSDocVariadicType && index === node.parent.parameters.length - 1; // TODO: GH#18217
const name = node.name || (isRest ? "rest" : "arg" + index);
const dotdotdot = isRest ? factory.createToken(SyntaxKind.DotDotDotToken) : node.dotDotDotToken;
return factory.createParameterDeclaration(node.modifiers, dotdotdot, name, node.questionToken, visitNode(node.type, transformJSDocType), node.initializer);
return factory.createParameterDeclaration(node.modifiers, dotdotdot, name, node.questionToken, visitNode(node.type, transformJSDocType, isTypeNode), node.initializer);
}
function transformJSDocTypeReference(node: TypeReferenceNode) {
@ -212,7 +212,7 @@ function transformJSDocTypeReference(node: TypeReferenceNode) {
args = factory.createNodeArray([factory.createTypeReferenceNode("any", emptyArray)]);
}
else {
args = visitNodes(node.typeArguments, transformJSDocType);
args = visitNodes(node.typeArguments, transformJSDocType, isTypeNode);
}
}
return factory.createTypeReferenceNode(name, args);

Просмотреть файл

@ -51,6 +51,7 @@ import {
isPropertyAssignment,
isSetAccessorDeclaration,
isStringLiteral,
isTypeNode,
isYieldExpression,
LanguageServiceHost,
length,
@ -100,6 +101,7 @@ import {
UserPreferences,
visitEachChild,
visitNode,
visitNodes,
} from "../_namespaces/ts";
import { ImportAdder } from "../_namespaces/ts.codefix";
@ -852,12 +854,11 @@ export function findJsonProperty(obj: ObjectLiteralExpression, name: string): Pr
*/
export function tryGetAutoImportableReferenceFromTypeNode(importTypeNode: TypeNode | undefined, scriptTarget: ScriptTarget) {
let symbols: Symbol[] | undefined;
const typeNode = visitNode(importTypeNode, visit);
const typeNode = visitNode(importTypeNode, visit, isTypeNode);
if (symbols && typeNode) {
return { typeNode, symbols };
}
function visit(node: TypeNode): TypeNode;
function visit(node: Node): Node {
if (isLiteralImportTypeNode(node) && node.qualifier) {
// Symbol for the left-most thing after the dot
@ -868,7 +869,7 @@ export function tryGetAutoImportableReferenceFromTypeNode(importTypeNode: TypeNo
: node.qualifier;
symbols = append(symbols, firstIdentifier.symbol);
const typeArguments = node.typeArguments?.map(visit);
const typeArguments = visitNodes(node.typeArguments, visit, isTypeNode);
return factory.createTypeReferenceNode(qualifier, typeArguments);
}
return visitEachChild(node, visit, nullTransformationContext);

Просмотреть файл

@ -1002,9 +1002,13 @@ function getUmdSymbol(token: Node, checker: TypeChecker): Symbol | undefined {
// The error wasn't for the symbolAtLocation, it was for the JSX tag itself, which needs access to e.g. `React`.
const { parent } = token;
return (isJsxOpeningLikeElement(parent) && parent.tagName === token) || isJsxOpeningFragment(parent)
? tryCast(checker.resolveName(checker.getJsxNamespace(parent), isJsxOpeningLikeElement(parent) ? token : parent, SymbolFlags.Value, /*excludeGlobals*/ false), isUMDExportSymbol)
: undefined;
if ((isJsxOpeningLikeElement(parent) && parent.tagName === token) || isJsxOpeningFragment(parent)) {
const parentSymbol = checker.resolveName(checker.getJsxNamespace(parent), isJsxOpeningLikeElement(parent) ? token : parent, SymbolFlags.Value, /*excludeGlobals*/ false);
if (isUMDExportSymbol(parentSymbol)) {
return parentSymbol;
}
}
return undefined;
}
/**

Просмотреть файл

@ -1595,7 +1595,7 @@ function transformFunctionBody(body: Node, exposedVariableDeclarations: readonly
const statements = factory.createNodeArray(isBlock(body) ? body.statements.slice(0) : [isStatement(body) ? body : factory.createReturnStatement(skipParentheses(body as Expression))]);
// rewrite body if either there are writes that should be propagated back via return statements or there are substitutions
if (hasWritesOrVariableDeclarations || substitutions.size) {
const rewrittenStatements = visitNodes(statements, visitor).slice();
const rewrittenStatements = visitNodes(statements, visitor, isStatement).slice();
if (hasWritesOrVariableDeclarations && !hasReturn && isStatement(body)) {
// add return at the end to propagate writes back in case if control flow falls out of the function body
// it is ok to know that range has at least one return since it we only allow unconditional returns
@ -1620,7 +1620,7 @@ function transformFunctionBody(body: Node, exposedVariableDeclarations: readonly
if (!returnValueProperty) {
returnValueProperty = "__return";
}
assignments.unshift(factory.createPropertyAssignment(returnValueProperty, visitNode(node.expression, visitor)));
assignments.unshift(factory.createPropertyAssignment(returnValueProperty, visitNode(node.expression, visitor, isExpression)));
}
if (assignments.length === 1) {
return factory.createReturnStatement(assignments[0].name as Expression);

Просмотреть файл

@ -1342,11 +1342,18 @@ export function assignPositionsToNode(node: Node): Node {
return newNode;
}
function assignPositionsToNodeArray(nodes: NodeArray<any>, visitor: Visitor, test?: (node: Node) => boolean, start?: number, count?: number) {
function assignPositionsToNodeArray(
nodes: NodeArray<Node> | undefined,
visitor: Visitor,
test?: (node: Node) => boolean,
start?: number,
count?: number,
): NodeArray<Node> | undefined {
const visited = visitNodes(nodes, visitor, test, start, count);
if (!visited) {
return visited;
}
Debug.assert(nodes);
// clone nodearray if necessary
const nodeArray = visited === nodes ? factory.createNodeArray(visited.slice(0)) : visited;
setTextRangePosEnd(nodeArray, getPos(nodes), getEnd(nodes));

Просмотреть файл

@ -3069,10 +3069,10 @@ export function getSynthesizedDeepCloneWithReplacements<T extends Node>(
}
function getSynthesizedDeepCloneWorker<T extends Node>(node: T, replaceNode?: (node: Node) => Node | undefined): T {
const nodeClone: (n: T) => T = replaceNode
const nodeClone: <T extends Node>(n: T) => T = replaceNode
? n => getSynthesizedDeepCloneWithReplacements(n, /*includeTrivia*/ true, replaceNode)
: getSynthesizedDeepClone;
const nodesClone: (ns: NodeArray<T>) => NodeArray<T> = replaceNode
const nodesClone: <T extends Node>(ns: NodeArray<T> | undefined) => NodeArray<T> | undefined = replaceNode
? ns => ns && getSynthesizedDeepClonesWithReplacements(ns, /*includeTrivia*/ true, replaceNode)
: ns => ns && getSynthesizedDeepClones(ns);
const visited =
@ -3964,7 +3964,7 @@ export function isNonGlobalDeclaration(declaration: Declaration) {
return false;
}
// If the file is a module written in TypeScript, it still might be in a `declare global` augmentation
return isInJSFile(declaration) || !findAncestor(declaration, isGlobalScopeAugmentation);
return isInJSFile(declaration) || !findAncestor(declaration, d => isModuleDeclaration(d) && isGlobalScopeAugmentation(d));
}
/** @internal */

Просмотреть файл

@ -22,7 +22,7 @@ describe("unittests:: compilerCore", () => {
assert.isFalse(ts.equalOwnProperties({}, { a: 0 }, trythyTest), "missing left falsey property");
assert.isFalse(ts.equalOwnProperties({ a: 1 }, {}, trythyTest), "missing right truthy property");
assert.isFalse(ts.equalOwnProperties({ a: 0 }, {}, trythyTest), "missing right falsey property");
assert.isTrue(ts.equalOwnProperties({ a: 1 }, { a: "foo" }, trythyTest), "valid equality");
assert.isTrue(ts.equalOwnProperties({ a: 1 }, { a: "foo" as any }, trythyTest), "valid equality");
});
it("all equal", () => {
assert.isFalse(ts.equalOwnProperties({}, { a: 1 }, () => true), "missing left property");

Просмотреть файл

@ -91,7 +91,7 @@ describe("unittests:: customTransforms", () => {
context => node => ts.visitNode(node, function visitor(node: ts.Node): ts.Node {
if (ts.isStringLiteral(node) && node.text === "change") return ts.factory.createStringLiteral("changed");
return ts.visitEachChild(node, visitor, context);
})
}, ts.isSourceFile)
]}, {
target: ts.ScriptTarget.ES5,
module: ts.ModuleKind.ES2015,
@ -126,7 +126,7 @@ describe("unittests:: customTransforms", () => {
return node;
}
return ts.visitEachChild(node, visitor, context);
})
}, ts.isSourceFile)
]
},
{ sourceMap: true }
@ -155,7 +155,7 @@ describe("unittests:: customTransforms", () => {
return newNode;
}
return ts.visitEachChild(node, visitor, context);
});
}, ts.isSourceFile);
return {
transformSourceFile,
transformBundle: node => ts.factory.createBundle(ts.map(node.sourceFiles, transformSourceFile), node.prepends),

Просмотреть файл

@ -330,7 +330,7 @@ namespace M {
function findConstructor(sourceFile: ts.SourceFile): ts.ConstructorDeclaration {
const classDecl = sourceFile.statements[0] as ts.ClassDeclaration;
return ts.find<ts.ClassElement, ts.ConstructorDeclaration>(classDecl.members, (m): m is ts.ConstructorDeclaration => ts.isConstructorDeclaration(m) && !!m.body)!;
return ts.find(classDecl.members, (m): m is ts.ConstructorDeclaration => ts.isConstructorDeclaration(m) && !!m.body)!;
}
function createTestSuperCall() {
const superCall = ts.factory.createCallExpression(

Просмотреть файл

@ -30,10 +30,10 @@ describe("unittests:: TransformAPI", () => {
}
return ts.visitEachChild(node, visitor, context);
}
return (file: ts.SourceFile) => ts.visitNode(file, visitor);
return (file: ts.SourceFile) => ts.visitNode(file, visitor, ts.isSourceFile);
}
function replaceIdentifiersNamedOldNameWithNewName(context: ts.TransformationContext) {
function replaceIdentifiersNamedOldNameWithNewName<T extends ts.SourceFile | ts.Bundle>(context: ts.TransformationContext) {
const previousOnSubstituteNode = context.onSubstituteNode;
context.enableSubstitution(ts.SyntaxKind.Identifier);
context.onSubstituteNode = (hint, node) => {
@ -43,17 +43,17 @@ describe("unittests:: TransformAPI", () => {
}
return node;
};
return (file: ts.SourceFile) => file;
return (file: T) => file;
}
function replaceIdentifiersNamedOldNameWithNewName2(context: ts.TransformationContext) {
const visitor: ts.Visitor = (node) => {
const visitor = (node: ts.Node): ts.Node => {
if (ts.isIdentifier(node) && node.text === "oldName") {
return ts.factory.createIdentifier("newName");
}
return ts.visitEachChild(node, visitor, context);
};
return (node: ts.SourceFile) => ts.visitNode(node, visitor);
return (node: ts.SourceFile) => ts.visitNode(node, visitor, ts.isSourceFile);
}
function createTaggedTemplateLiteral(): ts.Transformer<ts.SourceFile> {
@ -109,7 +109,7 @@ describe("unittests:: TransformAPI", () => {
return transformSourceFile(`let a: () => void`, [
context => file => ts.visitNode(file, function visitor(node: ts.Node): ts.VisitResult<ts.Node> {
return ts.visitEachChild(node, visitor, context);
})
}, ts.isSourceFile)
]);
});
@ -120,7 +120,7 @@ describe("unittests:: TransformAPI", () => {
return ts.factory.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword);
}
return ts.visitEachChild(node, visitor, context);
})
}, ts.isSourceFile)
]);
});
@ -557,7 +557,7 @@ module MyModule {
return host.readFile("source.js")!.toString();
function transformSourceFile(context: ts.TransformationContext) {
const visitor: ts.Visitor = (node) => {
const visitor = (node: ts.Node): ts.Node => {
if (ts.isMethodDeclaration(node)) {
return ts.factory.updateMethodDeclaration(
node,
@ -573,7 +573,7 @@ module MyModule {
}
return ts.visitEachChild(node, visitor, context);
};
return (node: ts.SourceFile) => ts.visitNode(node, visitor);
return (node: ts.SourceFile) => ts.visitNode(node, visitor, ts.isSourceFile);
}
});

Просмотреть файл

@ -2,6 +2,7 @@ import * as ts from "../../_namespaces/ts";
import {
createServerHost,
File,
Folder,
libFile,
SymLink,
TestServerHost,
@ -366,7 +367,7 @@ describe("unittests:: tsserver:: CachingFileSystemInformation:: tsserverProjectS
describe("Verify npm install in directory with tsconfig file works when", () => {
function verifyNpmInstall(timeoutDuringPartialInstallation: boolean) {
const root = "/user/username/rootfolder/otherfolder";
const getRootedFileOrFolder = (fileOrFolder: File) => {
const getRootedFileOrFolder = <T extends File | Folder>(fileOrFolder: T) => {
fileOrFolder.path = root + fileOrFolder.path;
return fileOrFolder;
};
@ -411,7 +412,7 @@ describe("unittests:: tsserver:: CachingFileSystemInformation:: tsserverProjectS
let npmInstallComplete = false;
// Simulate npm install
const filesAndFoldersToAdd: File[] = [
const filesAndFoldersToAdd: (File | Folder)[] = [
{ path: "/a/b/node_modules" },
{ path: "/a/b/node_modules/.staging/@types" },
{ path: "/a/b/node_modules/.staging/lodash-b0733faa" },

Просмотреть файл

@ -1,6 +1,5 @@
import * as ts from "../../_namespaces/ts";
import * as Harness from "../../_namespaces/Harness";
import * as Utils from "../../_namespaces/Utils";
import {
changeToHostTrackingWrittenFiles,
createServerHost,
@ -473,7 +472,7 @@ export function createSession(host: ts.server.ServerHost, opts: Partial<TestSess
useSingleInferredProject: false,
useInferredProjectPerProjectRoot: false,
typingsInstaller: undefined!, // TODO: GH#18217
byteLength: Utils.byteLength,
byteLength: Buffer.byteLength,
hrtime: process.hrtime,
logger: opts.logger || createHasErrorMessageLogger(),
canUseEvents: false

Просмотреть файл

@ -2,7 +2,6 @@ import { expect } from "chai";
import * as ts from "../../_namespaces/ts";
import * as Harness from "../../_namespaces/Harness";
import * as Utils from "../../_namespaces/Utils";
import {
createHasErrorMessageLogger,
nullLogger,
@ -53,7 +52,7 @@ describe("unittests:: tsserver:: Session:: General functionality", () => {
useSingleInferredProject: false,
useInferredProjectPerProjectRoot: false,
typingsInstaller: undefined!, // TODO: GH#18217
byteLength: Utils.byteLength,
byteLength: Buffer.byteLength,
hrtime: process.hrtime,
logger: nullLogger(),
canUseEvents: true
@ -352,7 +351,7 @@ describe("unittests:: tsserver:: Session:: General functionality", () => {
it("is an overrideable handle which sends protocol messages over the wire", () => {
const msg: ts.server.protocol.Request = { seq: 0, type: "request", command: "" };
const strmsg = JSON.stringify(msg);
const len = 1 + Utils.byteLength(strmsg, "utf8");
const len = 1 + Buffer.byteLength(strmsg, "utf8");
const resultMsg = `Content-Length: ${len}\r\n\r\n${strmsg}\n`;
session.send = ts.server.Session.prototype.send;
@ -475,7 +474,7 @@ describe("unittests:: tsserver:: Session:: exceptions", () => {
useSingleInferredProject: false,
useInferredProjectPerProjectRoot: false,
typingsInstaller: undefined!, // TODO: GH#18217
byteLength: Utils.byteLength,
byteLength: Buffer.byteLength,
hrtime: process.hrtime,
logger: nullLogger(),
canUseEvents: true
@ -522,7 +521,7 @@ describe("unittests:: tsserver:: Session:: how Session is extendable via subclas
useSingleInferredProject: false,
useInferredProjectPerProjectRoot: false,
typingsInstaller: undefined!, // TODO: GH#18217
byteLength: Utils.byteLength,
byteLength: Buffer.byteLength,
hrtime: process.hrtime,
logger: createHasErrorMessageLogger(),
canUseEvents: true
@ -590,7 +589,7 @@ describe("unittests:: tsserver:: Session:: an example of using the Session API t
useSingleInferredProject: false,
useInferredProjectPerProjectRoot: false,
typingsInstaller: undefined!, // TODO: GH#18217
byteLength: Utils.byteLength,
byteLength: Buffer.byteLength,
hrtime: process.hrtime,
logger: createHasErrorMessageLogger(),
canUseEvents: true

Просмотреть файл

@ -16,12 +16,13 @@
"noEmitOnError": true,
"emitDeclarationOnly": true,
"strictNullChecks": true,
"noImplicitAny": true,
"noImplicitThis": true,
"strictPropertyInitialization": true,
"strict": true,
"strictBindCallApply": false,
"useUnknownInCatchVariables": false,
"noUnusedLocals": true,
"noUnusedParameters": true,
"allowUnusedLabels": false,
"skipLibCheck": true,

Просмотреть файл

@ -136,8 +136,8 @@ const enum ProjectWatcherType {
type ProjectWatchers = Map<string, FileWatcher> & { isInvoked?: boolean; };
function getDetailWatchInfo(projectName: string, watchers: ProjectWatchers) {
return `Project: ${projectName} watcher already invoked: ${watchers.isInvoked}`;
function getDetailWatchInfo(projectName: string, watchers: ProjectWatchers | undefined) {
return `Project: ${projectName} watcher already invoked: ${watchers?.isInvoked}`;
}
export abstract class TypingsInstaller {

Просмотреть файл

@ -3729,7 +3729,7 @@ declare namespace ts {
private enableRequestedPluginsForProjectAsync;
configurePlugin(args: protocol.ConfigurePluginRequestArguments): void;
}
function formatMessage<T extends protocol.Message>(msg: T, logger: Logger, byteLength: (s: string, encoding: string) => number, newLine: string): string;
function formatMessage<T extends protocol.Message>(msg: T, logger: Logger, byteLength: (s: string, encoding: BufferEncoding) => number, newLine: string): string;
interface ServerCancellationToken extends HostCancellationToken {
setRequest(requestId: number): void;
resetRequest(requestId: number): void;
@ -3751,8 +3751,14 @@ declare namespace ts {
useSingleInferredProject: boolean;
useInferredProjectPerProjectRoot: boolean;
typingsInstaller: ITypingsInstaller;
byteLength: (buf: string, encoding?: string) => number;
hrtime: (start?: number[]) => number[];
byteLength: (buf: string, encoding?: BufferEncoding) => number;
hrtime: (start?: [
number,
number
]) => [
number,
number
];
logger: Logger;
/**
* If falsy, all events are suppressed.
@ -3781,7 +3787,7 @@ declare namespace ts {
protected host: ServerHost;
private readonly cancellationToken;
protected readonly typingsInstaller: ITypingsInstaller;
protected byteLength: (buf: string, encoding?: string) => number;
protected byteLength: (buf: string, encoding?: BufferEncoding) => number;
private hrtime;
protected logger: Logger;
protected canUseEvents: boolean;
@ -7822,10 +7828,10 @@ declare namespace ts {
updateJSDocReadonlyTag(node: JSDocReadonlyTag, tagName: Identifier | undefined, comment: string | NodeArray<JSDocComment> | undefined): JSDocReadonlyTag;
createJSDocUnknownTag(tagName: Identifier, comment?: string | NodeArray<JSDocComment>): JSDocUnknownTag;
updateJSDocUnknownTag(node: JSDocUnknownTag, tagName: Identifier, comment: string | NodeArray<JSDocComment> | undefined): JSDocUnknownTag;
createJSDocDeprecatedTag(tagName: Identifier, comment?: string | NodeArray<JSDocComment>): JSDocDeprecatedTag;
updateJSDocDeprecatedTag(node: JSDocDeprecatedTag, tagName: Identifier, comment?: string | NodeArray<JSDocComment>): JSDocDeprecatedTag;
createJSDocOverrideTag(tagName: Identifier, comment?: string | NodeArray<JSDocComment>): JSDocOverrideTag;
updateJSDocOverrideTag(node: JSDocOverrideTag, tagName: Identifier, comment?: string | NodeArray<JSDocComment>): JSDocOverrideTag;
createJSDocDeprecatedTag(tagName: Identifier | undefined, comment?: string | NodeArray<JSDocComment>): JSDocDeprecatedTag;
updateJSDocDeprecatedTag(node: JSDocDeprecatedTag, tagName: Identifier | undefined, comment?: string | NodeArray<JSDocComment>): JSDocDeprecatedTag;
createJSDocOverrideTag(tagName: Identifier | undefined, comment?: string | NodeArray<JSDocComment>): JSDocOverrideTag;
updateJSDocOverrideTag(node: JSDocOverrideTag, tagName: Identifier | undefined, comment?: string | NodeArray<JSDocComment>): JSDocOverrideTag;
createJSDocThrowsTag(tagName: Identifier, typeExpression: JSDocTypeExpression | undefined, comment?: string | NodeArray<JSDocComment>): JSDocThrowsTag;
updateJSDocThrowsTag(node: JSDocThrowsTag, tagName: Identifier | undefined, typeExpression: JSDocTypeExpression | undefined, comment?: string | NodeArray<JSDocComment> | undefined): JSDocThrowsTag;
createJSDocSatisfiesTag(tagName: Identifier | undefined, typeExpression: JSDocTypeExpression, comment?: string | NodeArray<JSDocComment>): JSDocSatisfiesTag;
@ -8192,16 +8198,39 @@ declare namespace ts {
/**
* A function that accepts and possibly transforms a node.
*/
type Visitor = (node: Node) => VisitResult<Node>;
type Visitor<TIn extends Node = Node, TOut extends Node | undefined = TIn | undefined> = (node: TIn) => VisitResult<TOut>;
/**
* A function that walks a node using the given visitor, lifting node arrays into single nodes,
* returning an node which satisfies the test.
*
* - If the input node is undefined, then the output is undefined.
* - If the visitor returns undefined, then the output is undefined.
* - If the output node is not undefined, then it will satisfy the test function.
* - In order to obtain a return type that is more specific than `Node`, a test
* function _must_ be provided, and that function must be a type predicate.
*
* For the canonical implementation of this type, @see {visitNode}.
*/
interface NodeVisitor {
<T extends Node>(nodes: T, visitor: Visitor | undefined, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => T): T;
<T extends Node>(nodes: T | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => T): T | undefined;
<TIn extends Node | undefined, TVisited extends Node | undefined, TOut extends Node>(node: TIn, visitor: Visitor<NonNullable<TIn>, TVisited>, test: (node: Node) => node is TOut, lift?: (node: readonly Node[]) => Node): TOut | (TIn & undefined) | (TVisited & undefined);
<TIn extends Node | undefined, TVisited extends Node | undefined>(node: TIn, visitor: Visitor<NonNullable<TIn>, TVisited>, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => Node): Node | (TIn & undefined) | (TVisited & undefined);
}
/**
* A function that walks a node array using the given visitor, returning an array whose contents satisfy the test.
*
* - If the input node array is undefined, the output is undefined.
* - If the visitor can return undefined, the node it visits in the array will be reused.
* - If the output node array is not undefined, then its contents will satisfy the test.
* - In order to obtain a return type that is more specific than `NodeArray<Node>`, a test
* function _must_ be provided, and that function must be a type predicate.
*
* For the canonical implementation of this type, @see {visitNodes}.
*/
interface NodesVisitor {
<T extends Node>(nodes: NodeArray<T>, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray<T>;
<T extends Node>(nodes: NodeArray<T> | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray<T> | undefined;
<TIn extends Node, TInArray extends NodeArray<TIn> | undefined, TOut extends Node>(nodes: TInArray, visitor: Visitor<TIn, Node | undefined>, test: (node: Node) => node is TOut, start?: number, count?: number): NodeArray<TOut> | (TInArray & undefined);
<TIn extends Node, TInArray extends NodeArray<TIn> | undefined>(nodes: TInArray, visitor: Visitor<TIn, Node | undefined>, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray<Node> | (TInArray & undefined);
}
type VisitResult<T extends Node> = T | readonly T[] | undefined;
type VisitResult<T extends Node | undefined> = T | readonly Node[];
interface Printer {
/**
* Print a node and its subtree as-is, without any emit transformations.
@ -8415,6 +8444,7 @@ declare namespace ts {
}
type FileWatcherCallback = (fileName: string, eventKind: FileWatcherEventKind, modifiedTime?: Date) => void;
type DirectoryWatcherCallback = (fileName: string) => void;
type BufferEncoding = "ascii" | "utf8" | "utf-8" | "utf16le" | "ucs2" | "ucs-2" | "base64" | "latin1" | "binary" | "hex";
interface System {
args: string[];
newLine: string;
@ -8473,8 +8503,8 @@ declare namespace ts {
function forEachLeadingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T): U | undefined;
function forEachTrailingCommentRange<U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean) => U): U | undefined;
function forEachTrailingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T): U | undefined;
function reduceEachLeadingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial: U): U | undefined;
function reduceEachTrailingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial: U): U | undefined;
function reduceEachLeadingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T, initial: U): U | undefined;
function reduceEachTrailingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T, initial: U): U | undefined;
function getLeadingCommentRanges(text: string, pos: number): CommentRange[] | undefined;
function getTrailingCommentRanges(text: string, pos: number): CommentRange[] | undefined;
/** Optionally, get the shebang */
@ -8553,7 +8583,7 @@ declare namespace ts {
function getTypeParameterOwner(d: Declaration): Declaration | undefined;
function isParameterPropertyDeclaration(node: Node, parent: Node): node is ParameterPropertyDeclaration;
function isEmptyBindingPattern(node: BindingName): node is BindingPattern;
function isEmptyBindingElement(node: BindingElement): boolean;
function isEmptyBindingElement(node: BindingElement | ArrayBindingElement): boolean;
function walkUpBindingElementsAndPatterns(binding: BindingElement): VariableDeclaration | ParameterDeclaration;
function getCombinedModifierFlags(node: Declaration): ModifierFlags;
function getCombinedNodeFlags(node: Node): NodeFlags;
@ -8570,7 +8600,7 @@ declare namespace ts {
function getOriginalNode(node: Node): Node;
function getOriginalNode<T extends Node>(node: Node, nodeTest: (node: Node) => node is T): T;
function getOriginalNode(node: Node | undefined): Node | undefined;
function getOriginalNode<T extends Node>(node: Node | undefined, nodeTest: (node: Node | undefined) => node is T): T | undefined;
function getOriginalNode<T extends Node>(node: Node | undefined, nodeTest: (node: Node) => node is T): T | undefined;
/**
* Iterates through the parent chain of a node and performs the callback on each parent until the callback
* returns a truthy value, then returns that value.
@ -9288,41 +9318,65 @@ declare namespace ts {
/**
* Visits a Node using the supplied visitor, possibly returning a new Node in its place.
*
* - If the input node is undefined, then the output is undefined.
* - If the visitor returns undefined, then the output is undefined.
* - If the output node is not undefined, then it will satisfy the test function.
* - In order to obtain a return type that is more specific than `Node`, a test
* function _must_ be provided, and that function must be a type predicate.
*
* @param node The Node to visit.
* @param visitor The callback used to visit the Node.
* @param test A callback to execute to verify the Node is valid.
* @param lift An optional callback to execute to lift a NodeArray into a valid Node.
*/
function visitNode<T extends Node>(node: T, visitor: Visitor | undefined, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => T): T;
function visitNode<TIn extends Node | undefined, TVisited extends Node | undefined, TOut extends Node>(node: TIn, visitor: Visitor<NonNullable<TIn>, TVisited>, test: (node: Node) => node is TOut, lift?: (node: readonly Node[]) => Node): TOut | (TIn & undefined) | (TVisited & undefined);
/**
* Visits a Node using the supplied visitor, possibly returning a new Node in its place.
*
* - If the input node is undefined, then the output is undefined.
* - If the visitor returns undefined, then the output is undefined.
* - If the output node is not undefined, then it will satisfy the test function.
* - In order to obtain a return type that is more specific than `Node`, a test
* function _must_ be provided, and that function must be a type predicate.
*
* @param node The Node to visit.
* @param visitor The callback used to visit the Node.
* @param test A callback to execute to verify the Node is valid.
* @param lift An optional callback to execute to lift a NodeArray into a valid Node.
*/
function visitNode<T extends Node>(node: T | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => T): T | undefined;
function visitNode<TIn extends Node | undefined, TVisited extends Node | undefined>(node: TIn, visitor: Visitor<NonNullable<TIn>, TVisited>, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => Node): Node | (TIn & undefined) | (TVisited & undefined);
/**
* Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place.
*
* - If the input node array is undefined, the output is undefined.
* - If the visitor can return undefined, the node it visits in the array will be reused.
* - If the output node array is not undefined, then its contents will satisfy the test.
* - In order to obtain a return type that is more specific than `NodeArray<Node>`, a test
* function _must_ be provided, and that function must be a type predicate.
*
* @param nodes The NodeArray to visit.
* @param visitor The callback used to visit a Node.
* @param test A node test to execute for each node.
* @param start An optional value indicating the starting offset at which to start visiting.
* @param count An optional value indicating the maximum number of nodes to visit.
*/
function visitNodes<T extends Node>(nodes: NodeArray<T>, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray<T>;
function visitNodes<TIn extends Node, TInArray extends NodeArray<TIn> | undefined, TOut extends Node>(nodes: TInArray, visitor: Visitor<TIn, Node | undefined>, test: (node: Node) => node is TOut, start?: number, count?: number): NodeArray<TOut> | (TInArray & undefined);
/**
* Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place.
*
* - If the input node array is undefined, the output is undefined.
* - If the visitor can return undefined, the node it visits in the array will be reused.
* - If the output node array is not undefined, then its contents will satisfy the test.
* - In order to obtain a return type that is more specific than `NodeArray<Node>`, a test
* function _must_ be provided, and that function must be a type predicate.
*
* @param nodes The NodeArray to visit.
* @param visitor The callback used to visit a Node.
* @param test A node test to execute for each node.
* @param start An optional value indicating the starting offset at which to start visiting.
* @param count An optional value indicating the maximum number of nodes to visit.
*/
function visitNodes<T extends Node>(nodes: NodeArray<T> | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray<T> | undefined;
function visitNodes<TIn extends Node, TInArray extends NodeArray<TIn> | undefined>(nodes: TInArray, visitor: Visitor<TIn, Node | undefined>, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray<Node> | (TInArray & undefined);
/**
* Starts a new lexical environment and visits a statement list, ending the lexical environment
* and merging hoisted declarations upon completion.

84
tests/baselines/reference/api/typescript.d.ts поставляемый
Просмотреть файл

@ -3887,10 +3887,10 @@ declare namespace ts {
updateJSDocReadonlyTag(node: JSDocReadonlyTag, tagName: Identifier | undefined, comment: string | NodeArray<JSDocComment> | undefined): JSDocReadonlyTag;
createJSDocUnknownTag(tagName: Identifier, comment?: string | NodeArray<JSDocComment>): JSDocUnknownTag;
updateJSDocUnknownTag(node: JSDocUnknownTag, tagName: Identifier, comment: string | NodeArray<JSDocComment> | undefined): JSDocUnknownTag;
createJSDocDeprecatedTag(tagName: Identifier, comment?: string | NodeArray<JSDocComment>): JSDocDeprecatedTag;
updateJSDocDeprecatedTag(node: JSDocDeprecatedTag, tagName: Identifier, comment?: string | NodeArray<JSDocComment>): JSDocDeprecatedTag;
createJSDocOverrideTag(tagName: Identifier, comment?: string | NodeArray<JSDocComment>): JSDocOverrideTag;
updateJSDocOverrideTag(node: JSDocOverrideTag, tagName: Identifier, comment?: string | NodeArray<JSDocComment>): JSDocOverrideTag;
createJSDocDeprecatedTag(tagName: Identifier | undefined, comment?: string | NodeArray<JSDocComment>): JSDocDeprecatedTag;
updateJSDocDeprecatedTag(node: JSDocDeprecatedTag, tagName: Identifier | undefined, comment?: string | NodeArray<JSDocComment>): JSDocDeprecatedTag;
createJSDocOverrideTag(tagName: Identifier | undefined, comment?: string | NodeArray<JSDocComment>): JSDocOverrideTag;
updateJSDocOverrideTag(node: JSDocOverrideTag, tagName: Identifier | undefined, comment?: string | NodeArray<JSDocComment>): JSDocOverrideTag;
createJSDocThrowsTag(tagName: Identifier, typeExpression: JSDocTypeExpression | undefined, comment?: string | NodeArray<JSDocComment>): JSDocThrowsTag;
updateJSDocThrowsTag(node: JSDocThrowsTag, tagName: Identifier | undefined, typeExpression: JSDocTypeExpression | undefined, comment?: string | NodeArray<JSDocComment> | undefined): JSDocThrowsTag;
createJSDocSatisfiesTag(tagName: Identifier | undefined, typeExpression: JSDocTypeExpression, comment?: string | NodeArray<JSDocComment>): JSDocSatisfiesTag;
@ -4257,16 +4257,39 @@ declare namespace ts {
/**
* A function that accepts and possibly transforms a node.
*/
type Visitor = (node: Node) => VisitResult<Node>;
type Visitor<TIn extends Node = Node, TOut extends Node | undefined = TIn | undefined> = (node: TIn) => VisitResult<TOut>;
/**
* A function that walks a node using the given visitor, lifting node arrays into single nodes,
* returning an node which satisfies the test.
*
* - If the input node is undefined, then the output is undefined.
* - If the visitor returns undefined, then the output is undefined.
* - If the output node is not undefined, then it will satisfy the test function.
* - In order to obtain a return type that is more specific than `Node`, a test
* function _must_ be provided, and that function must be a type predicate.
*
* For the canonical implementation of this type, @see {visitNode}.
*/
interface NodeVisitor {
<T extends Node>(nodes: T, visitor: Visitor | undefined, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => T): T;
<T extends Node>(nodes: T | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => T): T | undefined;
<TIn extends Node | undefined, TVisited extends Node | undefined, TOut extends Node>(node: TIn, visitor: Visitor<NonNullable<TIn>, TVisited>, test: (node: Node) => node is TOut, lift?: (node: readonly Node[]) => Node): TOut | (TIn & undefined) | (TVisited & undefined);
<TIn extends Node | undefined, TVisited extends Node | undefined>(node: TIn, visitor: Visitor<NonNullable<TIn>, TVisited>, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => Node): Node | (TIn & undefined) | (TVisited & undefined);
}
/**
* A function that walks a node array using the given visitor, returning an array whose contents satisfy the test.
*
* - If the input node array is undefined, the output is undefined.
* - If the visitor can return undefined, the node it visits in the array will be reused.
* - If the output node array is not undefined, then its contents will satisfy the test.
* - In order to obtain a return type that is more specific than `NodeArray<Node>`, a test
* function _must_ be provided, and that function must be a type predicate.
*
* For the canonical implementation of this type, @see {visitNodes}.
*/
interface NodesVisitor {
<T extends Node>(nodes: NodeArray<T>, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray<T>;
<T extends Node>(nodes: NodeArray<T> | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray<T> | undefined;
<TIn extends Node, TInArray extends NodeArray<TIn> | undefined, TOut extends Node>(nodes: TInArray, visitor: Visitor<TIn, Node | undefined>, test: (node: Node) => node is TOut, start?: number, count?: number): NodeArray<TOut> | (TInArray & undefined);
<TIn extends Node, TInArray extends NodeArray<TIn> | undefined>(nodes: TInArray, visitor: Visitor<TIn, Node | undefined>, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray<Node> | (TInArray & undefined);
}
type VisitResult<T extends Node> = T | readonly T[] | undefined;
type VisitResult<T extends Node | undefined> = T | readonly Node[];
interface Printer {
/**
* Print a node and its subtree as-is, without any emit transformations.
@ -4480,6 +4503,7 @@ declare namespace ts {
}
type FileWatcherCallback = (fileName: string, eventKind: FileWatcherEventKind, modifiedTime?: Date) => void;
type DirectoryWatcherCallback = (fileName: string) => void;
type BufferEncoding = "ascii" | "utf8" | "utf-8" | "utf16le" | "ucs2" | "ucs-2" | "base64" | "latin1" | "binary" | "hex";
interface System {
args: string[];
newLine: string;
@ -4538,8 +4562,8 @@ declare namespace ts {
function forEachLeadingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T): U | undefined;
function forEachTrailingCommentRange<U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean) => U): U | undefined;
function forEachTrailingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T): U | undefined;
function reduceEachLeadingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial: U): U | undefined;
function reduceEachTrailingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial: U): U | undefined;
function reduceEachLeadingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T, initial: U): U | undefined;
function reduceEachTrailingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T, initial: U): U | undefined;
function getLeadingCommentRanges(text: string, pos: number): CommentRange[] | undefined;
function getTrailingCommentRanges(text: string, pos: number): CommentRange[] | undefined;
/** Optionally, get the shebang */
@ -4618,7 +4642,7 @@ declare namespace ts {
function getTypeParameterOwner(d: Declaration): Declaration | undefined;
function isParameterPropertyDeclaration(node: Node, parent: Node): node is ParameterPropertyDeclaration;
function isEmptyBindingPattern(node: BindingName): node is BindingPattern;
function isEmptyBindingElement(node: BindingElement): boolean;
function isEmptyBindingElement(node: BindingElement | ArrayBindingElement): boolean;
function walkUpBindingElementsAndPatterns(binding: BindingElement): VariableDeclaration | ParameterDeclaration;
function getCombinedModifierFlags(node: Declaration): ModifierFlags;
function getCombinedNodeFlags(node: Node): NodeFlags;
@ -4635,7 +4659,7 @@ declare namespace ts {
function getOriginalNode(node: Node): Node;
function getOriginalNode<T extends Node>(node: Node, nodeTest: (node: Node) => node is T): T;
function getOriginalNode(node: Node | undefined): Node | undefined;
function getOriginalNode<T extends Node>(node: Node | undefined, nodeTest: (node: Node | undefined) => node is T): T | undefined;
function getOriginalNode<T extends Node>(node: Node | undefined, nodeTest: (node: Node) => node is T): T | undefined;
/**
* Iterates through the parent chain of a node and performs the callback on each parent until the callback
* returns a truthy value, then returns that value.
@ -5353,41 +5377,65 @@ declare namespace ts {
/**
* Visits a Node using the supplied visitor, possibly returning a new Node in its place.
*
* - If the input node is undefined, then the output is undefined.
* - If the visitor returns undefined, then the output is undefined.
* - If the output node is not undefined, then it will satisfy the test function.
* - In order to obtain a return type that is more specific than `Node`, a test
* function _must_ be provided, and that function must be a type predicate.
*
* @param node The Node to visit.
* @param visitor The callback used to visit the Node.
* @param test A callback to execute to verify the Node is valid.
* @param lift An optional callback to execute to lift a NodeArray into a valid Node.
*/
function visitNode<T extends Node>(node: T, visitor: Visitor | undefined, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => T): T;
function visitNode<TIn extends Node | undefined, TVisited extends Node | undefined, TOut extends Node>(node: TIn, visitor: Visitor<NonNullable<TIn>, TVisited>, test: (node: Node) => node is TOut, lift?: (node: readonly Node[]) => Node): TOut | (TIn & undefined) | (TVisited & undefined);
/**
* Visits a Node using the supplied visitor, possibly returning a new Node in its place.
*
* - If the input node is undefined, then the output is undefined.
* - If the visitor returns undefined, then the output is undefined.
* - If the output node is not undefined, then it will satisfy the test function.
* - In order to obtain a return type that is more specific than `Node`, a test
* function _must_ be provided, and that function must be a type predicate.
*
* @param node The Node to visit.
* @param visitor The callback used to visit the Node.
* @param test A callback to execute to verify the Node is valid.
* @param lift An optional callback to execute to lift a NodeArray into a valid Node.
*/
function visitNode<T extends Node>(node: T | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => T): T | undefined;
function visitNode<TIn extends Node | undefined, TVisited extends Node | undefined>(node: TIn, visitor: Visitor<NonNullable<TIn>, TVisited>, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => Node): Node | (TIn & undefined) | (TVisited & undefined);
/**
* Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place.
*
* - If the input node array is undefined, the output is undefined.
* - If the visitor can return undefined, the node it visits in the array will be reused.
* - If the output node array is not undefined, then its contents will satisfy the test.
* - In order to obtain a return type that is more specific than `NodeArray<Node>`, a test
* function _must_ be provided, and that function must be a type predicate.
*
* @param nodes The NodeArray to visit.
* @param visitor The callback used to visit a Node.
* @param test A node test to execute for each node.
* @param start An optional value indicating the starting offset at which to start visiting.
* @param count An optional value indicating the maximum number of nodes to visit.
*/
function visitNodes<T extends Node>(nodes: NodeArray<T>, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray<T>;
function visitNodes<TIn extends Node, TInArray extends NodeArray<TIn> | undefined, TOut extends Node>(nodes: TInArray, visitor: Visitor<TIn, Node | undefined>, test: (node: Node) => node is TOut, start?: number, count?: number): NodeArray<TOut> | (TInArray & undefined);
/**
* Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place.
*
* - If the input node array is undefined, the output is undefined.
* - If the visitor can return undefined, the node it visits in the array will be reused.
* - If the output node array is not undefined, then its contents will satisfy the test.
* - In order to obtain a return type that is more specific than `NodeArray<Node>`, a test
* function _must_ be provided, and that function must be a type predicate.
*
* @param nodes The NodeArray to visit.
* @param visitor The callback used to visit a Node.
* @param test A node test to execute for each node.
* @param start An optional value indicating the starting offset at which to start visiting.
* @param count An optional value indicating the maximum number of nodes to visit.
*/
function visitNodes<T extends Node>(nodes: NodeArray<T> | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray<T> | undefined;
function visitNodes<TIn extends Node, TInArray extends NodeArray<TIn> | undefined>(nodes: TInArray, visitor: Visitor<TIn, Node | undefined>, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray<Node> | (TInArray & undefined);
/**
* Starts a new lexical environment and visits a statement list, ending the lexical environment
* and merging hoisted declarations upon completion.