mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-26 00:36:29 -05:00
Move deprecate from Debug to deprecatedCompat (#51522)
This commit is contained in:
@@ -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
@@ -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."
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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."
|
||||
});
|
||||
});
|
||||
|
||||
65
src/deprecatedCompat/deprecate.ts
Normal file
65
src/deprecatedCompat/deprecate.ts
Normal 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);
|
||||
}
|
||||
@@ -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 });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user