Skip to content

Commit

Permalink
Refactor node factory API, use node factory in parser
Browse files Browse the repository at this point in the history
  • Loading branch information
rbuckton committed Nov 22, 2019
1 parent 75301c8 commit 922ab41
Show file tree
Hide file tree
Showing 115 changed files with 21,058 additions and 13,152 deletions.
2 changes: 1 addition & 1 deletion .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"command": "gulp",
"args": ["tests"],
"group": "build",
"problemMatcher": ["$gulp-tsc"]
"problemMatcher": ["$tsc"]
}
]
}
1,925 changes: 1,925 additions & 0 deletions src/compat/factory.ts

Large diffs are not rendered by default.

12 changes: 12 additions & 0 deletions src/compat/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"extends": "../tsconfig-base",
"compilerOptions": {
"outFile": "../../built/local/compat.js"
},
"references": [
{ "path": "../compiler" }
],
"files": [
"factory.ts"
]
}
971 changes: 2 additions & 969 deletions src/compiler/binder.ts

Large diffs are not rendered by default.

487 changes: 252 additions & 235 deletions src/compiler/checker.ts

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions src/compiler/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ namespace ts {
/** Array that is only intended to be pushed to, never read. */
export interface Push<T> {
push(...values: T[]): void;
/* @internal*/ readonly length: number;
}

/* @internal */
Expand All @@ -70,6 +71,9 @@ namespace ts {
EqualTo = 0,
GreaterThan = 1
}

/* @internal */
export type MatchingKeys<TRecord, TMatch, K extends keyof TRecord = keyof TRecord> = K extends (TRecord[K] extends TMatch ? K : never) ? K : never;
}

/* @internal */
Expand Down
150 changes: 149 additions & 1 deletion src/compiler/debug.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,72 @@
/* @internal */
namespace ts {
export enum LogLevel {
Off,
Error,
Warning,
Info,
Verbose
}

export interface LoggingHost {
log(level: LogLevel, s: string): void;
}

export interface DeprecationOptions {
message?: string;
error?: boolean;
since?: Version | string;
warnAfter?: Version | string;
errorAfter?: Version | string;
typeScriptVersion?: Version | string;
}

export namespace Debug {
let typeScriptVersion: Version | undefined;

/* eslint-disable prefer-const */
export let currentAssertionLevel = AssertionLevel.None;
export let currentLogLevel = LogLevel.Warning;
export let isDebugging = false;
export let loggingHost: LoggingHost | undefined;
/* eslint-enable prefer-const */

export function getTypeScriptVersion() {
return typeScriptVersion ?? (typeScriptVersion = new Version(version));
}

export function shouldLog(level: LogLevel): boolean {
return currentLogLevel <= level;
}

function logMessage(level: LogLevel, s: string): void {
if (loggingHost && shouldLog(level)) {
loggingHost.log(level, s);
}
}

export function log(s: string): void {
logMessage(LogLevel.Info, s);
}

export namespace log {
export function error(s: string): void {
logMessage(LogLevel.Error, s);
}

export function warn(s: string): void {
logMessage(LogLevel.Warning, s);
}

export function log(s: string): void {
logMessage(LogLevel.Info, s);
}

export function trace(s: string): void {
logMessage(LogLevel.Verbose, s);
}
}

export function shouldAssert(level: AssertionLevel): boolean {
return currentAssertionLevel >= level;
}
Expand Down Expand Up @@ -295,7 +356,7 @@ namespace ts {
if (nodeIsSynthesized(this)) return "";
const parseNode = getParseTreeNode(this);
const sourceFile = parseNode && getSourceFileOfNode(parseNode);
return sourceFile ? getSourceTextOfNodeFromSourceFile(sourceFile, parseNode, includeTrivia) : "";
return sourceFile ? getSourceTextOfNodeFromSourceFile(sourceFile, parseNode!, includeTrivia) : "";
}
}
});
Expand All @@ -320,5 +381,92 @@ namespace ts {
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 (!hasWrittenDeprecation) {
log.warn(formatDeprecationMessage(name, /*error*/ false, errorAfter, since, message));
hasWrittenDeprecation = true;
}
};
}

function createDeprecation(name: string, options: DeprecationOptions & { error: true }): () => never;
function createDeprecation(name: string, options?: DeprecationOptions): () => void;
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;
}

function wrapAccessor(deprecation: () => void, desc: PropertyDescriptor) {
if (desc.configurable) {
const newDesc: PropertyDescriptor = { ...desc, enumerable: false };
if (desc.get) newDesc.get = wrapFunction(deprecation, desc.get);
if (desc.set) newDesc.set = wrapFunction(deprecation, desc.set);
return newDesc;
}
}

function wrapValue(deprecation: () => void, desc: PropertyDescriptor) {
if (typeof desc.value === "function" && (desc.configurable || desc.writable)) {
const newDesc: PropertyDescriptor = { ...desc };
if (desc.configurable) {
desc.enumerable = false;
}
newDesc.value = wrapFunction(deprecation, newDesc.value);
return newDesc;
}
}

export function deprecateExport<T, K extends Extract<MatchingKeys<T, (...args: any[]) => any>, string>>(ns: T, key: K, options?: DeprecationOptions) {
const desc = Object.getOwnPropertyDescriptor(ns, key);
if (!desc) return;
const deprecation = createDeprecation(key, options);
const newDesc = desc.get || desc.set ? wrapAccessor(deprecation, desc) : wrapValue(deprecation, desc);
if (newDesc) {
Object.defineProperty(ns, key, newDesc);
}
}

export function deprecateExports<T, K extends Extract<MatchingKeys<T, (...args: any[]) => any>, string>>(object: T, keys: readonly K[], options?: DeprecationOptions) {
for (const key of keys) {
deprecateExport(object, key, options);
}
}

export function deprecateFunction<F extends (...args: any[]) => any>(func: F, options?: DeprecationOptions): F {
const deprecation = createDeprecation(getFunctionName(func), options);
return wrapFunction(deprecation, func);
}
}
}
18 changes: 9 additions & 9 deletions src/compiler/emitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ namespace ts {
if (options.outFile || options.out) {
const prepends = host.getPrependNodes();
if (sourceFiles.length || prepends.length) {
const bundle = createBundle(sourceFiles, prepends);
const bundle = factory.createBundle(sourceFiles, prepends);
const result = action(getOutputPathsFor(bundle, host, forceDtsEmit), bundle);
if (result) {
return result;
Expand Down Expand Up @@ -354,7 +354,7 @@ namespace ts {
return;
}
// Transform the source files
const transform = transformNodes(resolver, host, compilerOptions, [sourceFileOrBundle], scriptTransformers, /*allowDtsFiles*/ false);
const transform = transformNodes(resolver, host, factory, compilerOptions, [sourceFileOrBundle], scriptTransformers, /*allowDtsFiles*/ false);

const printerOptions: PrinterOptions = {
removeComments: compilerOptions.removeComments,
Expand Down Expand Up @@ -400,13 +400,13 @@ namespace ts {
}
const sourceFiles = isSourceFile(sourceFileOrBundle) ? [sourceFileOrBundle] : sourceFileOrBundle.sourceFiles;
// Setup and perform the transformation to retrieve declarations from the input files
const inputListOrBundle = (compilerOptions.outFile || compilerOptions.out) ? [createBundle(sourceFiles, !isSourceFile(sourceFileOrBundle) ? sourceFileOrBundle.prepends : undefined)] : sourceFiles;
const inputListOrBundle = (compilerOptions.outFile || compilerOptions.out) ? [factory.createBundle(sourceFiles, !isSourceFile(sourceFileOrBundle) ? sourceFileOrBundle.prepends : undefined)] : sourceFiles;
if (emitOnlyDtsFiles && !getEmitDeclarations(compilerOptions)) {
// Checker wont collect the linked aliases since thats only done when declaration is enabled.
// Do that here when emitting only dts files
sourceFiles.forEach(collectLinkedAliases);
}
const declarationTransform = transformNodes(resolver, host, compilerOptions, inputListOrBundle, declarationTransformers, /*allowDtsFiles*/ false);
const declarationTransform = transformNodes(resolver, host, factory, compilerOptions, inputListOrBundle, declarationTransformers, /*allowDtsFiles*/ false);
if (length(declarationTransform.diagnostics)) {
for (const diagnostic of declarationTransform.diagnostics!) {
emitterDiagnostics.add(diagnostic);
Expand Down Expand Up @@ -682,15 +682,15 @@ namespace ts {
!host.useCaseSensitiveFileNames()
);
sourceFile.text = "";
sourceFile.statements = createNodeArray();
sourceFile.statements = factory.createNodeArray();
return sourceFile;
});
const jsBundle = Debug.assertDefined(bundle.js);
forEach(jsBundle.sources && jsBundle.sources.prologues, prologueInfo => {
const sourceFile = sourceFiles[prologueInfo.file];
sourceFile.text = prologueInfo.text;
sourceFile.end = prologueInfo.text.length;
sourceFile.statements = createNodeArray(prologueInfo.directives.map(directive => {
sourceFile.statements = factory.createNodeArray(prologueInfo.directives.map(directive => {
const statement = createNode(SyntaxKind.ExpressionStatement, directive.pos, directive.end) as PrologueDirective;
statement.expression = createNode(SyntaxKind.StringLiteral, directive.expression.pos, directive.expression.end) as StringLiteral;
statement.expression.text = directive.expression.text;
Expand Down Expand Up @@ -3423,15 +3423,15 @@ namespace ts {
}

function emitJSDocTypeLiteral(lit: JSDocTypeLiteral) {
emitList(lit, createNodeArray(lit.jsDocPropertyTags), ListFormat.JSDocComment);
emitList(lit, factory.createNodeArray(lit.jsDocPropertyTags), ListFormat.JSDocComment);
}

function emitJSDocSignature(sig: JSDocSignature) {
if (sig.typeParameters) {
emitList(sig, createNodeArray(sig.typeParameters), ListFormat.JSDocComment);
emitList(sig, factory.createNodeArray(sig.typeParameters), ListFormat.JSDocComment);
}
if (sig.parameters) {
emitList(sig, createNodeArray(sig.parameters), ListFormat.JSDocComment);
emitList(sig, factory.createNodeArray(sig.parameters), ListFormat.JSDocComment);
}
if (sig.type) {
writeLine();
Expand Down
Loading

0 comments on commit 922ab41

Please sign in to comment.