Skip to content

Commit 922ab41

Browse files
committed
Refactor node factory API, use node factory in parser
1 parent 75301c8 commit 922ab41

File tree

115 files changed

+21058
-13152
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

115 files changed

+21058
-13152
lines changed

Diff for: .vscode/tasks.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
"command": "gulp",
2929
"args": ["tests"],
3030
"group": "build",
31-
"problemMatcher": ["$gulp-tsc"]
31+
"problemMatcher": ["$tsc"]
3232
}
3333
]
3434
}

Diff for: src/compat/factory.ts

+1,925
Large diffs are not rendered by default.

Diff for: src/compat/tsconfig.json

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"extends": "../tsconfig-base",
3+
"compilerOptions": {
4+
"outFile": "../../built/local/compat.js"
5+
},
6+
"references": [
7+
{ "path": "../compiler" }
8+
],
9+
"files": [
10+
"factory.ts"
11+
]
12+
}

Diff for: src/compiler/binder.ts

+2-969
Large diffs are not rendered by default.

Diff for: src/compiler/checker.ts

+252-235
Large diffs are not rendered by default.

Diff for: src/compiler/core.ts

+4
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ namespace ts {
5656
/** Array that is only intended to be pushed to, never read. */
5757
export interface Push<T> {
5858
push(...values: T[]): void;
59+
/* @internal*/ readonly length: number;
5960
}
6061

6162
/* @internal */
@@ -70,6 +71,9 @@ namespace ts {
7071
EqualTo = 0,
7172
GreaterThan = 1
7273
}
74+
75+
/* @internal */
76+
export type MatchingKeys<TRecord, TMatch, K extends keyof TRecord = keyof TRecord> = K extends (TRecord[K] extends TMatch ? K : never) ? K : never;
7377
}
7478

7579
/* @internal */

Diff for: src/compiler/debug.ts

+149-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,72 @@
11
/* @internal */
22
namespace ts {
3+
export enum LogLevel {
4+
Off,
5+
Error,
6+
Warning,
7+
Info,
8+
Verbose
9+
}
10+
11+
export interface LoggingHost {
12+
log(level: LogLevel, s: string): void;
13+
}
14+
15+
export interface DeprecationOptions {
16+
message?: string;
17+
error?: boolean;
18+
since?: Version | string;
19+
warnAfter?: Version | string;
20+
errorAfter?: Version | string;
21+
typeScriptVersion?: Version | string;
22+
}
23+
324
export namespace Debug {
25+
let typeScriptVersion: Version | undefined;
26+
427
/* eslint-disable prefer-const */
528
export let currentAssertionLevel = AssertionLevel.None;
29+
export let currentLogLevel = LogLevel.Warning;
630
export let isDebugging = false;
31+
export let loggingHost: LoggingHost | undefined;
732
/* eslint-enable prefer-const */
833

34+
export function getTypeScriptVersion() {
35+
return typeScriptVersion ?? (typeScriptVersion = new Version(version));
36+
}
37+
38+
export function shouldLog(level: LogLevel): boolean {
39+
return currentLogLevel <= level;
40+
}
41+
42+
function logMessage(level: LogLevel, s: string): void {
43+
if (loggingHost && shouldLog(level)) {
44+
loggingHost.log(level, s);
45+
}
46+
}
47+
48+
export function log(s: string): void {
49+
logMessage(LogLevel.Info, s);
50+
}
51+
52+
export namespace log {
53+
export function error(s: string): void {
54+
logMessage(LogLevel.Error, s);
55+
}
56+
57+
export function warn(s: string): void {
58+
logMessage(LogLevel.Warning, s);
59+
}
60+
61+
export function log(s: string): void {
62+
logMessage(LogLevel.Info, s);
63+
}
64+
65+
export function trace(s: string): void {
66+
logMessage(LogLevel.Verbose, s);
67+
}
68+
}
69+
970
export function shouldAssert(level: AssertionLevel): boolean {
1071
return currentAssertionLevel >= level;
1172
}
@@ -295,7 +356,7 @@ namespace ts {
295356
if (nodeIsSynthesized(this)) return "";
296357
const parseNode = getParseTreeNode(this);
297358
const sourceFile = parseNode && getSourceFileOfNode(parseNode);
298-
return sourceFile ? getSourceTextOfNodeFromSourceFile(sourceFile, parseNode, includeTrivia) : "";
359+
return sourceFile ? getSourceTextOfNodeFromSourceFile(sourceFile, parseNode!, includeTrivia) : "";
299360
}
300361
}
301362
});
@@ -320,5 +381,92 @@ namespace ts {
320381
isDebugInfoEnabled = true;
321382
}
322383

384+
function formatDeprecationMessage(name: string, error: boolean | undefined, errorAfter: Version | undefined, since: Version | undefined, message: string | undefined) {
385+
let deprecationMessage = error ? "DeprecationError: " : "DeprecationWarning: ";
386+
deprecationMessage += `'${name}' `;
387+
deprecationMessage += since ? `has been deprecated since v${since}` : "is deprecated";
388+
deprecationMessage += error ? " and can no longer be used." : errorAfter ? ` and will no longer be usable after v${errorAfter}.` : ".";
389+
deprecationMessage += message ? ` ${formatStringFromArgs(message, [name], 0)}` : "";
390+
return deprecationMessage;
391+
}
392+
393+
function createErrorDeprecation(name: string, errorAfter: Version | undefined, since: Version | undefined, message: string | undefined) {
394+
const deprecationMessage = formatDeprecationMessage(name, /*error*/ true, errorAfter, since, message);
395+
return () => {
396+
throw new TypeError(deprecationMessage);
397+
};
398+
}
399+
400+
function createWarningDeprecation(name: string, errorAfter: Version | undefined, since: Version | undefined, message: string | undefined) {
401+
let hasWrittenDeprecation = false;
402+
return () => {
403+
if (!hasWrittenDeprecation) {
404+
log.warn(formatDeprecationMessage(name, /*error*/ false, errorAfter, since, message));
405+
hasWrittenDeprecation = true;
406+
}
407+
};
408+
}
409+
410+
function createDeprecation(name: string, options: DeprecationOptions & { error: true }): () => never;
411+
function createDeprecation(name: string, options?: DeprecationOptions): () => void;
412+
function createDeprecation(name: string, options: DeprecationOptions = {}) {
413+
const version = typeof options.typeScriptVersion === "string" ? new Version(options.typeScriptVersion) : options.typeScriptVersion ?? getTypeScriptVersion();
414+
const errorAfter = typeof options.errorAfter === "string" ? new Version(options.errorAfter) : options.errorAfter;
415+
const warnAfter = typeof options.warnAfter === "string" ? new Version(options.warnAfter) : options.warnAfter;
416+
const since = typeof options.since === "string" ? new Version(options.since) : options.since ?? warnAfter;
417+
const error = options.error || errorAfter && version.compareTo(errorAfter) <= 0;
418+
const warn = !warnAfter || version.compareTo(warnAfter) >= 0;
419+
return error ? createErrorDeprecation(name, errorAfter, since, options.message) :
420+
warn ? createWarningDeprecation(name, errorAfter, since, options.message) :
421+
noop;
422+
}
423+
424+
function wrapFunction<F extends (...args: any[]) => any>(deprecation: () => void, func: F): F {
425+
return function (this: unknown) {
426+
deprecation();
427+
return func.apply(this, arguments);
428+
} as F;
429+
}
430+
431+
function wrapAccessor(deprecation: () => void, desc: PropertyDescriptor) {
432+
if (desc.configurable) {
433+
const newDesc: PropertyDescriptor = { ...desc, enumerable: false };
434+
if (desc.get) newDesc.get = wrapFunction(deprecation, desc.get);
435+
if (desc.set) newDesc.set = wrapFunction(deprecation, desc.set);
436+
return newDesc;
437+
}
438+
}
439+
440+
function wrapValue(deprecation: () => void, desc: PropertyDescriptor) {
441+
if (typeof desc.value === "function" && (desc.configurable || desc.writable)) {
442+
const newDesc: PropertyDescriptor = { ...desc };
443+
if (desc.configurable) {
444+
desc.enumerable = false;
445+
}
446+
newDesc.value = wrapFunction(deprecation, newDesc.value);
447+
return newDesc;
448+
}
449+
}
450+
451+
export function deprecateExport<T, K extends Extract<MatchingKeys<T, (...args: any[]) => any>, string>>(ns: T, key: K, options?: DeprecationOptions) {
452+
const desc = Object.getOwnPropertyDescriptor(ns, key);
453+
if (!desc) return;
454+
const deprecation = createDeprecation(key, options);
455+
const newDesc = desc.get || desc.set ? wrapAccessor(deprecation, desc) : wrapValue(deprecation, desc);
456+
if (newDesc) {
457+
Object.defineProperty(ns, key, newDesc);
458+
}
459+
}
460+
461+
export function deprecateExports<T, K extends Extract<MatchingKeys<T, (...args: any[]) => any>, string>>(object: T, keys: readonly K[], options?: DeprecationOptions) {
462+
for (const key of keys) {
463+
deprecateExport(object, key, options);
464+
}
465+
}
466+
467+
export function deprecateFunction<F extends (...args: any[]) => any>(func: F, options?: DeprecationOptions): F {
468+
const deprecation = createDeprecation(getFunctionName(func), options);
469+
return wrapFunction(deprecation, func);
470+
}
323471
}
324472
}

Diff for: src/compiler/emitter.ts

+9-9
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ namespace ts {
2828
if (options.outFile || options.out) {
2929
const prepends = host.getPrependNodes();
3030
if (sourceFiles.length || prepends.length) {
31-
const bundle = createBundle(sourceFiles, prepends);
31+
const bundle = factory.createBundle(sourceFiles, prepends);
3232
const result = action(getOutputPathsFor(bundle, host, forceDtsEmit), bundle);
3333
if (result) {
3434
return result;
@@ -354,7 +354,7 @@ namespace ts {
354354
return;
355355
}
356356
// Transform the source files
357-
const transform = transformNodes(resolver, host, compilerOptions, [sourceFileOrBundle], scriptTransformers, /*allowDtsFiles*/ false);
357+
const transform = transformNodes(resolver, host, factory, compilerOptions, [sourceFileOrBundle], scriptTransformers, /*allowDtsFiles*/ false);
358358

359359
const printerOptions: PrinterOptions = {
360360
removeComments: compilerOptions.removeComments,
@@ -400,13 +400,13 @@ namespace ts {
400400
}
401401
const sourceFiles = isSourceFile(sourceFileOrBundle) ? [sourceFileOrBundle] : sourceFileOrBundle.sourceFiles;
402402
// Setup and perform the transformation to retrieve declarations from the input files
403-
const inputListOrBundle = (compilerOptions.outFile || compilerOptions.out) ? [createBundle(sourceFiles, !isSourceFile(sourceFileOrBundle) ? sourceFileOrBundle.prepends : undefined)] : sourceFiles;
403+
const inputListOrBundle = (compilerOptions.outFile || compilerOptions.out) ? [factory.createBundle(sourceFiles, !isSourceFile(sourceFileOrBundle) ? sourceFileOrBundle.prepends : undefined)] : sourceFiles;
404404
if (emitOnlyDtsFiles && !getEmitDeclarations(compilerOptions)) {
405405
// Checker wont collect the linked aliases since thats only done when declaration is enabled.
406406
// Do that here when emitting only dts files
407407
sourceFiles.forEach(collectLinkedAliases);
408408
}
409-
const declarationTransform = transformNodes(resolver, host, compilerOptions, inputListOrBundle, declarationTransformers, /*allowDtsFiles*/ false);
409+
const declarationTransform = transformNodes(resolver, host, factory, compilerOptions, inputListOrBundle, declarationTransformers, /*allowDtsFiles*/ false);
410410
if (length(declarationTransform.diagnostics)) {
411411
for (const diagnostic of declarationTransform.diagnostics!) {
412412
emitterDiagnostics.add(diagnostic);
@@ -682,15 +682,15 @@ namespace ts {
682682
!host.useCaseSensitiveFileNames()
683683
);
684684
sourceFile.text = "";
685-
sourceFile.statements = createNodeArray();
685+
sourceFile.statements = factory.createNodeArray();
686686
return sourceFile;
687687
});
688688
const jsBundle = Debug.assertDefined(bundle.js);
689689
forEach(jsBundle.sources && jsBundle.sources.prologues, prologueInfo => {
690690
const sourceFile = sourceFiles[prologueInfo.file];
691691
sourceFile.text = prologueInfo.text;
692692
sourceFile.end = prologueInfo.text.length;
693-
sourceFile.statements = createNodeArray(prologueInfo.directives.map(directive => {
693+
sourceFile.statements = factory.createNodeArray(prologueInfo.directives.map(directive => {
694694
const statement = createNode(SyntaxKind.ExpressionStatement, directive.pos, directive.end) as PrologueDirective;
695695
statement.expression = createNode(SyntaxKind.StringLiteral, directive.expression.pos, directive.expression.end) as StringLiteral;
696696
statement.expression.text = directive.expression.text;
@@ -3423,15 +3423,15 @@ namespace ts {
34233423
}
34243424

34253425
function emitJSDocTypeLiteral(lit: JSDocTypeLiteral) {
3426-
emitList(lit, createNodeArray(lit.jsDocPropertyTags), ListFormat.JSDocComment);
3426+
emitList(lit, factory.createNodeArray(lit.jsDocPropertyTags), ListFormat.JSDocComment);
34273427
}
34283428

34293429
function emitJSDocSignature(sig: JSDocSignature) {
34303430
if (sig.typeParameters) {
3431-
emitList(sig, createNodeArray(sig.typeParameters), ListFormat.JSDocComment);
3431+
emitList(sig, factory.createNodeArray(sig.typeParameters), ListFormat.JSDocComment);
34323432
}
34333433
if (sig.parameters) {
3434-
emitList(sig, createNodeArray(sig.parameters), ListFormat.JSDocComment);
3434+
emitList(sig, factory.createNodeArray(sig.parameters), ListFormat.JSDocComment);
34353435
}
34363436
if (sig.type) {
34373437
writeLine();

0 commit comments

Comments
 (0)