Move deprecate from Debug to deprecatedCompat (#51522)

This commit is contained in:
Jake Bailey
2022-11-15 16:00:33 -08:00
committed by GitHub
parent f4ddc1a09b
commit 4d53a1f8f1
8 changed files with 447 additions and 433 deletions

View File

@@ -1,7 +1,7 @@
import * as ts from "./_namespaces/ts";
import {
AnyFunction, AssertionLevel, BigIntLiteralType, CheckMode, compareValues, EmitFlags, every, FlowFlags, FlowLabel, FlowNode,
FlowNodeBase, FlowSwitchClause, formatStringFromArgs, getEffectiveModifierFlagsNoCache, getEmitFlags, getOwnKeys,
FlowNodeBase, FlowSwitchClause, getEffectiveModifierFlagsNoCache, getEmitFlags, getOwnKeys,
getParseTreeNode, getSourceFileOfNode, getSourceTextOfNodeFromSourceFile, hasProperty, idText, IntrinsicType,
isArrayTypeNode, isBigIntLiteral, isCallSignatureDeclaration, isConditionalTypeNode, isConstructorDeclaration,
isConstructorTypeNode, isConstructSignatureDeclaration, isDefaultClause, isFunctionTypeNode, isGeneratedIdentifier,
@@ -14,7 +14,7 @@ import {
ObjectFlags, ObjectType, RelationComparisonResult, Signature, SignatureCheckMode,
SignatureFlags, SnippetKind, SortedReadonlyArray, stableSort, Symbol, SymbolFlags, symbolName, SyntaxKind,
TransformFlags, Type, TypeFacts, TypeFlags, TypeMapKind, TypeMapper, unescapeLeadingUnderscores, VarianceFlags,
version, Version, zipWith,
zipWith,
} from "./_namespaces/ts";
/** @internal */
@@ -31,33 +31,16 @@ export interface LoggingHost {
log(level: LogLevel, s: string): void;
}
/** @internal */
export interface DeprecationOptions {
message?: string;
error?: boolean;
since?: Version | string;
warnAfter?: Version | string;
errorAfter?: Version | string;
typeScriptVersion?: Version | string;
name?: string;
}
/** @internal */
export namespace Debug {
let typeScriptVersion: Version | undefined;
/* eslint-disable prefer-const */
let currentAssertionLevel = AssertionLevel.None;
export let currentLogLevel = LogLevel.Warning;
export let isDebugging = false;
export let loggingHost: LoggingHost | undefined;
export let enableDeprecationWarnings = true;
/* eslint-enable prefer-const */
type AssertionKeys = MatchingKeys<typeof Debug, AnyFunction>;
export function getTypeScriptVersion() {
return typeScriptVersion ?? (typeScriptVersion = new Version(version));
}
export function shouldLog(level: LogLevel): boolean {
return currentLogLevel <= level;
@@ -697,58 +680,6 @@ export namespace Debug {
isDebugInfoEnabled = true;
}
function formatDeprecationMessage(name: string, error: boolean | undefined, errorAfter: Version | undefined, since: Version | undefined, message: string | undefined) {
let deprecationMessage = error ? "DeprecationError: " : "DeprecationWarning: ";
deprecationMessage += `'${name}' `;
deprecationMessage += since ? `has been deprecated since v${since}` : "is deprecated";
deprecationMessage += error ? " and can no longer be used." : errorAfter ? ` and will no longer be usable after v${errorAfter}.` : ".";
deprecationMessage += message ? ` ${formatStringFromArgs(message, [name], 0)}` : "";
return deprecationMessage;
}
function createErrorDeprecation(name: string, errorAfter: Version | undefined, since: Version | undefined, message: string | undefined) {
const deprecationMessage = formatDeprecationMessage(name, /*error*/ true, errorAfter, since, message);
return () => {
throw new TypeError(deprecationMessage);
};
}
function createWarningDeprecation(name: string, errorAfter: Version | undefined, since: Version | undefined, message: string | undefined) {
let hasWrittenDeprecation = false;
return () => {
if (enableDeprecationWarnings && !hasWrittenDeprecation) {
log.warn(formatDeprecationMessage(name, /*error*/ false, errorAfter, since, message));
hasWrittenDeprecation = true;
}
};
}
export function createDeprecation(name: string, options: DeprecationOptions & { error: true }): () => never;
export function createDeprecation(name: string, options?: DeprecationOptions): () => void;
export function createDeprecation(name: string, options: DeprecationOptions = {}) {
const version = typeof options.typeScriptVersion === "string" ? new Version(options.typeScriptVersion) : options.typeScriptVersion ?? getTypeScriptVersion();
const errorAfter = typeof options.errorAfter === "string" ? new Version(options.errorAfter) : options.errorAfter;
const warnAfter = typeof options.warnAfter === "string" ? new Version(options.warnAfter) : options.warnAfter;
const since = typeof options.since === "string" ? new Version(options.since) : options.since ?? warnAfter;
const error = options.error || errorAfter && version.compareTo(errorAfter) <= 0;
const warn = !warnAfter || version.compareTo(warnAfter) >= 0;
return error ? createErrorDeprecation(name, errorAfter, since, options.message) :
warn ? createWarningDeprecation(name, errorAfter, since, options.message) :
noop;
}
function wrapFunction<F extends (...args: any[]) => any>(deprecation: () => void, func: F): F {
return function (this: unknown) {
deprecation();
return func.apply(this, arguments);
} as F;
}
export function deprecate<F extends (...args: any[]) => any>(func: F, options?: DeprecationOptions): F {
const deprecation = createDeprecation(options?.name ?? getFunctionName(func), options);
return wrapFunction(deprecation, func);
}
export function formatVariance(varianceFlags: VarianceFlags) {
const variance = varianceFlags & VarianceFlags.VarianceMask;
let result =

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,5 @@
import { Debug, Node, SyntaxKind, TypeAssertion } from "../_namespaces/ts";
import { Node, SyntaxKind, TypeAssertion } from "../_namespaces/ts";
import { deprecate } from "../deprecate";
// DEPRECATION: Renamed node tests
// DEPRECATION PLAN:
@@ -6,10 +7,10 @@ import { Debug, Node, SyntaxKind, TypeAssertion } from "../_namespaces/ts";
// - warn: 4.1
// - error: TBD
/** @deprecated Use `isTypeAssertionExpression` instead. */
export const isTypeAssertion = Debug.deprecate(function isTypeAssertion(node: Node): node is TypeAssertion {
export const isTypeAssertion = deprecate(function isTypeAssertion(node: Node): node is TypeAssertion {
return node.kind === SyntaxKind.TypeAssertionExpression;
}, {
since: "4.0",
warnAfter: "4.1",
message: "Use `isTypeAssertionExpression` instead."
});
});

View File

@@ -1,4 +1,5 @@
import { Debug, isMemberName, MemberName, Node } from "../_namespaces/ts";
import { isMemberName, MemberName, Node } from "../_namespaces/ts";
import { deprecate } from "../deprecate";
// DEPRECATION: Renamed node tests
// DEPRECATION PLAN:
@@ -8,10 +9,10 @@ import { Debug, isMemberName, MemberName, Node } from "../_namespaces/ts";
/**
* @deprecated Use `isMemberName` instead.
*/
export const isIdentifierOrPrivateIdentifier = Debug.deprecate(function isIdentifierOrPrivateIdentifier(node: Node): node is MemberName {
export const isIdentifierOrPrivateIdentifier = deprecate(function isIdentifierOrPrivateIdentifier(node: Node): node is MemberName {
return isMemberName(node);
}, {
since: "4.2",
warnAfter: "4.3",
message: "Use `isMemberName` instead."
});
});

View File

@@ -0,0 +1,65 @@
import { Debug, DeprecationOptions, formatStringFromArgs, noop, version, Version } from "./_namespaces/ts";
export let enableDeprecationWarnings = true;
export function setEnableDeprecationWarnings(value: boolean) {
enableDeprecationWarnings = value;
}
let typeScriptVersion: Version | undefined;
function getTypeScriptVersion() {
return typeScriptVersion ?? (typeScriptVersion = new Version(version));
}
function formatDeprecationMessage(name: string, error: boolean | undefined, errorAfter: Version | undefined, since: Version | undefined, message: string | undefined) {
let deprecationMessage = error ? "DeprecationError: " : "DeprecationWarning: ";
deprecationMessage += `'${name}' `;
deprecationMessage += since ? `has been deprecated since v${since}` : "is deprecated";
deprecationMessage += error ? " and can no longer be used." : errorAfter ? ` and will no longer be usable after v${errorAfter}.` : ".";
deprecationMessage += message ? ` ${formatStringFromArgs(message, [name], 0)}` : "";
return deprecationMessage;
}
function createErrorDeprecation(name: string, errorAfter: Version | undefined, since: Version | undefined, message: string | undefined) {
const deprecationMessage = formatDeprecationMessage(name, /*error*/ true, errorAfter, since, message);
return () => {
throw new TypeError(deprecationMessage);
};
}
function createWarningDeprecation(name: string, errorAfter: Version | undefined, since: Version | undefined, message: string | undefined) {
let hasWrittenDeprecation = false;
return () => {
if (enableDeprecationWarnings && !hasWrittenDeprecation) {
Debug.log.warn(formatDeprecationMessage(name, /*error*/ false, errorAfter, since, message));
hasWrittenDeprecation = true;
}
};
}
export function createDeprecation(name: string, options: DeprecationOptions & { error: true }): () => never;
export function createDeprecation(name: string, options?: DeprecationOptions): () => void;
export function createDeprecation(name: string, options: DeprecationOptions = {}) {
const version = typeof options.typeScriptVersion === "string" ? new Version(options.typeScriptVersion) : options.typeScriptVersion ?? getTypeScriptVersion();
const errorAfter = typeof options.errorAfter === "string" ? new Version(options.errorAfter) : options.errorAfter;
const warnAfter = typeof options.warnAfter === "string" ? new Version(options.warnAfter) : options.warnAfter;
const since = typeof options.since === "string" ? new Version(options.since) : options.since ?? warnAfter;
const error = options.error || errorAfter && version.compareTo(errorAfter) <= 0;
const warn = !warnAfter || version.compareTo(warnAfter) >= 0;
return error ? createErrorDeprecation(name, errorAfter, since, options.message) :
warn ? createWarningDeprecation(name, errorAfter, since, options.message) :
noop;
}
function wrapFunction<F extends (...args: any[]) => any>(deprecation: () => void, func: F): F {
return function (this: unknown) {
deprecation();
return func.apply(this, arguments);
} as F;
}
export function deprecate<F extends (...args: any[]) => any>(func: F, options?: DeprecationOptions): F {
const deprecation = createDeprecation(options?.name ?? Debug.getFunctionName(func), options);
return wrapFunction(deprecation, func);
}

View File

@@ -1,8 +1,21 @@
import { Debug, DeprecationOptions, hasProperty, UnionToIntersection } from "./_namespaces/ts";
import { hasProperty, UnionToIntersection, Version } from "./_namespaces/ts";
import { deprecate } from "./deprecate";
/** @internal */
export interface DeprecationOptions {
message?: string;
error?: boolean;
since?: Version | string;
warnAfter?: Version | string;
errorAfter?: Version | string;
typeScriptVersion?: Version | string;
name?: string;
}
// The following are deprecations for the public API. Deprecated exports are removed from the compiler itself
// and compatible implementations are added here, along with an appropriate deprecation warning using
// the `@deprecated` JSDoc tag as well as the `Debug.deprecate` API.
// the `@deprecated` JSDoc tag as well as the `deprecate` API.
//
// Deprecations fall into one of three categories:
//
@@ -69,7 +82,7 @@ export function createOverload<T extends OverloadDefinitions>(name: string, over
for (const key of Object.keys(deprecations)) {
const index = +key as (keyof T & number);
if (!isNaN(index) && hasProperty(overloads, `${index}`)) {
overloads[index] = Debug.deprecate(overloads[index], { ...deprecations[index], name });
overloads[index] = deprecate(overloads[index], { ...deprecations[index], name });
}
}
}

View File

@@ -1,4 +1,5 @@
import * as ts from "../_namespaces/ts";
import { deprecate } from "../../deprecatedCompat/deprecate";
describe("unittests:: debugDeprecation", () => {
let loggingHost: ts.LoggingHost | undefined;
@@ -11,7 +12,7 @@ describe("unittests:: debugDeprecation", () => {
});
describe("deprecateFunction", () => {
it("silent deprecation", () => {
const deprecation = ts.Debug.deprecate(ts.noop, {
const deprecation = deprecate(ts.noop, {
warnAfter: "3.9",
typeScriptVersion: "3.8"
});
@@ -25,7 +26,7 @@ describe("unittests:: debugDeprecation", () => {
assert.isFalse(logWritten);
});
it("warning deprecation with warnAfter", () => {
const deprecation = ts.Debug.deprecate(ts.noop, {
const deprecation = deprecate(ts.noop, {
warnAfter: "3.9",
typeScriptVersion: "3.9"
});
@@ -39,7 +40,7 @@ describe("unittests:: debugDeprecation", () => {
assert.isTrue(logWritten);
});
it("warning deprecation without warnAfter", () => {
const deprecation = ts.Debug.deprecate(ts.noop, {
const deprecation = deprecate(ts.noop, {
typeScriptVersion: "3.9"
});
let logWritten = false;
@@ -52,7 +53,7 @@ describe("unittests:: debugDeprecation", () => {
assert.isTrue(logWritten);
});
it("warning deprecation writes once", () => {
const deprecation = ts.Debug.deprecate(ts.noop, {
const deprecation = deprecate(ts.noop, {
typeScriptVersion: "3.9"
});
let logWrites = 0;
@@ -66,7 +67,7 @@ describe("unittests:: debugDeprecation", () => {
assert.equal(logWrites, 1);
});
it("error deprecation with errorAfter", () => {
const deprecation = ts.Debug.deprecate(ts.noop, {
const deprecation = deprecate(ts.noop, {
warnAfter: "3.8",
errorAfter: "3.9",
typeScriptVersion: "3.9"
@@ -81,7 +82,7 @@ describe("unittests:: debugDeprecation", () => {
assert.isFalse(logWritten);
});
it("error deprecation with error", () => {
const deprecation = ts.Debug.deprecate(ts.noop, {
const deprecation = deprecate(ts.noop, {
error: true,
});
let logWritten = false;
@@ -94,4 +95,4 @@ describe("unittests:: debugDeprecation", () => {
assert.isFalse(logWritten);
});
});
});
});

View File

@@ -1,4 +1,5 @@
import * as ts from "../_namespaces/ts";
import { setEnableDeprecationWarnings } from "../../deprecatedCompat/deprecate";
describe("unittests:: FactoryAPI", () => {
function assertSyntaxKind(node: ts.Node, expected: ts.SyntaxKind) {
@@ -85,11 +86,11 @@ describe("unittests:: FactoryAPI", () => {
describe("deprecations", () => {
beforeEach(() => {
ts.Debug.enableDeprecationWarnings = false;
setEnableDeprecationWarnings(false);
});
afterEach(() => {
ts.Debug.enableDeprecationWarnings = true;
setEnableDeprecationWarnings(true);
});
// https://github.com/microsoft/TypeScript/issues/50259