mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Remove "generate types" code (#31075)
This commit is contained in:
@@ -4919,14 +4919,6 @@
|
||||
"category": "Message",
|
||||
"code": 95066
|
||||
},
|
||||
"Generate types for '{0}'": {
|
||||
"category": "Message",
|
||||
"code": 95067
|
||||
},
|
||||
"Generate types for all packages without types": {
|
||||
"category": "Message",
|
||||
"code": 95068
|
||||
},
|
||||
"Add 'unknown' conversion for non-overlapping types": {
|
||||
"category": "Message",
|
||||
"code": 95069
|
||||
|
||||
@@ -1,162 +0,0 @@
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
export interface InspectValueOptions {
|
||||
readonly fileNameToRequire: string;
|
||||
}
|
||||
|
||||
export const enum ValueKind { Const, Array, FunctionOrClass, Object }
|
||||
export interface ValueInfoBase {
|
||||
readonly name: string;
|
||||
}
|
||||
export type ValueInfo = ValueInfoSimple | ValueInfoArray | ValueInfoFunctionOrClass | ValueInfoObject;
|
||||
export interface ValueInfoSimple extends ValueInfoBase {
|
||||
readonly kind: ValueKind.Const;
|
||||
readonly typeName: string;
|
||||
readonly comment?: string | undefined;
|
||||
}
|
||||
export interface ValueInfoFunctionOrClass extends ValueInfoBase {
|
||||
readonly kind: ValueKind.FunctionOrClass;
|
||||
readonly source: string | number; // For a native function, this is the length.
|
||||
readonly prototypeMembers: ReadonlyArray<ValueInfo>;
|
||||
readonly namespaceMembers: ReadonlyArray<ValueInfo>;
|
||||
}
|
||||
export interface ValueInfoArray extends ValueInfoBase {
|
||||
readonly kind: ValueKind.Array;
|
||||
readonly inner: ValueInfo;
|
||||
}
|
||||
export interface ValueInfoObject extends ValueInfoBase {
|
||||
readonly kind: ValueKind.Object;
|
||||
readonly hasNontrivialPrototype: boolean;
|
||||
readonly members: ReadonlyArray<ValueInfo>;
|
||||
}
|
||||
|
||||
export function inspectModule(fileNameToRequire: string): ValueInfo {
|
||||
return inspectValue(removeFileExtension(getBaseFileName(fileNameToRequire)), tryRequire(fileNameToRequire));
|
||||
}
|
||||
|
||||
export function inspectValue(name: string, value: unknown): ValueInfo {
|
||||
return getValueInfo(name, value, getRecurser());
|
||||
}
|
||||
|
||||
type Recurser = <T>(obj: unknown, name: string, cbOk: () => T, cbFail: (isCircularReference: boolean, keyStack: ReadonlyArray<string>) => T) => T;
|
||||
function getRecurser(): Recurser {
|
||||
const seen: unknown[] = [];
|
||||
const nameStack: string[] = [];
|
||||
return (obj, name, cbOk, cbFail) => {
|
||||
if (seen.indexOf(obj) !== -1 || nameStack.length > 4) {
|
||||
return cbFail(seen.indexOf(obj) !== -1, nameStack);
|
||||
}
|
||||
|
||||
seen.push(obj);
|
||||
nameStack.push(name);
|
||||
const res = cbOk();
|
||||
nameStack.pop();
|
||||
seen.pop();
|
||||
return res;
|
||||
};
|
||||
}
|
||||
|
||||
function getValueInfo(name: string, value: unknown, recurser: Recurser): ValueInfo {
|
||||
return recurser(value, name,
|
||||
(): ValueInfo => {
|
||||
if (typeof value === "function") return getFunctionOrClassInfo(value as AnyFunction, name, recurser);
|
||||
if (typeof value === "object") {
|
||||
const builtin = getBuiltinType(name, value as object, recurser);
|
||||
if (builtin !== undefined) return builtin;
|
||||
const entries = getEntriesOfObject(value as object);
|
||||
const hasNontrivialPrototype = Object.getPrototypeOf(value) !== Object.prototype;
|
||||
const members = flatMap(entries, ({ key, value }) => getValueInfo(key, value, recurser));
|
||||
return { kind: ValueKind.Object, name, hasNontrivialPrototype, members };
|
||||
}
|
||||
return { kind: ValueKind.Const, name, typeName: isNullOrUndefined(value) ? "any" : typeof value };
|
||||
},
|
||||
(isCircularReference, keyStack) => anyValue(name, ` ${isCircularReference ? "Circular reference" : "Too-deep object hierarchy"} from ${keyStack.join(".")}`));
|
||||
}
|
||||
|
||||
function getFunctionOrClassInfo(fn: AnyFunction, name: string, recurser: Recurser): ValueInfoFunctionOrClass {
|
||||
const prototypeMembers = getPrototypeMembers(fn, recurser);
|
||||
const namespaceMembers = flatMap(getEntriesOfObject(fn), ({ key, value }) => getValueInfo(key, value, recurser));
|
||||
const toString = cast(Function.prototype.toString.call(fn), isString);
|
||||
const source = stringContains(toString, "{ [native code] }") ? getFunctionLength(fn) : toString;
|
||||
return { kind: ValueKind.FunctionOrClass, name, source, namespaceMembers, prototypeMembers };
|
||||
}
|
||||
|
||||
const builtins: () => ReadonlyMap<AnyConstructor> = memoize(() => {
|
||||
const map = createMap<AnyConstructor>();
|
||||
for (const { key, value } of getEntriesOfObject(global)) {
|
||||
if (typeof value === "function" && typeof value.prototype === "object" && value !== Object) {
|
||||
map.set(key, value as AnyConstructor);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
});
|
||||
function getBuiltinType(name: string, value: object, recurser: Recurser): ValueInfo | undefined {
|
||||
return isArray(value)
|
||||
? { name, kind: ValueKind.Array, inner: value.length && getValueInfo("element", first(value), recurser) || anyValue(name) }
|
||||
: forEachEntry(builtins(), (builtin, builtinName): ValueInfo | undefined =>
|
||||
value instanceof builtin ? { kind: ValueKind.Const, name, typeName: builtinName } : undefined);
|
||||
}
|
||||
|
||||
function getPrototypeMembers(fn: AnyFunction, recurser: Recurser): ReadonlyArray<ValueInfo> {
|
||||
const prototype = fn.prototype as unknown;
|
||||
// tslint:disable-next-line no-unnecessary-type-assertion (TODO: update LKG and it will really be unnecessary)
|
||||
return typeof prototype !== "object" || prototype === null ? emptyArray : mapDefined(getEntriesOfObject(prototype as object), ({ key, value }) =>
|
||||
key === "constructor" ? undefined : getValueInfo(key, value, recurser));
|
||||
}
|
||||
|
||||
const ignoredProperties: ReadonlyArray<string> = ["arguments", "caller", "constructor", "eval", "super_"];
|
||||
const reservedFunctionProperties: ReadonlyArray<string> = Object.getOwnPropertyNames(noop);
|
||||
interface ObjectEntry { readonly key: string; readonly value: unknown; }
|
||||
function getEntriesOfObject(obj: object): ReadonlyArray<ObjectEntry> {
|
||||
const seen = createMap<true>();
|
||||
const entries: ObjectEntry[] = [];
|
||||
let chain = obj;
|
||||
while (!isNullOrUndefined(chain) && chain !== Object.prototype && chain !== Function.prototype) {
|
||||
for (const key of Object.getOwnPropertyNames(chain)) {
|
||||
if (!isJsPrivate(key) &&
|
||||
ignoredProperties.indexOf(key) === -1 &&
|
||||
(typeof obj !== "function" || reservedFunctionProperties.indexOf(key) === -1) &&
|
||||
// Don't add property from a higher prototype if it already exists in a lower one
|
||||
addToSeen(seen, key)) {
|
||||
const value = safeGetPropertyOfObject(chain, key);
|
||||
// Don't repeat "toString" that matches signature from Object.prototype
|
||||
if (!(key === "toString" && typeof value === "function" && value.length === 0)) {
|
||||
entries.push({ key, value });
|
||||
}
|
||||
}
|
||||
}
|
||||
chain = Object.getPrototypeOf(chain);
|
||||
}
|
||||
return entries.sort((e1, e2) => compareStringsCaseSensitive(e1.key, e2.key));
|
||||
}
|
||||
|
||||
function getFunctionLength(fn: AnyFunction): number {
|
||||
return tryCast(safeGetPropertyOfObject(fn, "length"), isNumber) || 0;
|
||||
}
|
||||
|
||||
function safeGetPropertyOfObject(obj: object, key: string): unknown {
|
||||
const desc = Object.getOwnPropertyDescriptor(obj, key);
|
||||
return desc && desc.value;
|
||||
}
|
||||
|
||||
function isNullOrUndefined(value: unknown): value is null | undefined {
|
||||
return value == null; // tslint:disable-line
|
||||
}
|
||||
|
||||
function anyValue(name: string, comment?: string): ValueInfo {
|
||||
return { kind: ValueKind.Const, name, typeName: "any", comment };
|
||||
}
|
||||
|
||||
export function isJsPrivate(name: string): boolean {
|
||||
return startsWith(name, "_");
|
||||
}
|
||||
|
||||
function tryRequire(fileNameToRequire: string): unknown {
|
||||
try {
|
||||
return require(fileNameToRequire);
|
||||
}
|
||||
catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -53,6 +53,5 @@
|
||||
"moduleSpecifiers.ts",
|
||||
"watch.ts",
|
||||
"tsbuild.ts",
|
||||
"inspectValue.ts",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -3068,19 +3068,6 @@ Actual: ${stringify(fullActual)}`);
|
||||
return this.languageService.getApplicableRefactors(fileName, positionOrRange, preferences) || ts.emptyArray;
|
||||
}
|
||||
|
||||
public generateTypes(examples: ReadonlyArray<FourSlashInterface.GenerateTypesOptions>): void {
|
||||
for (const { name = "example", value, global, output, outputBaseline } of examples) {
|
||||
const actual = (global ? ts.generateTypesForGlobal : ts.generateTypesForModule)(name, value, this.formatCodeSettings);
|
||||
if (outputBaseline) {
|
||||
if (actual === undefined) throw ts.Debug.fail();
|
||||
Harness.Baseline.runBaseline(ts.combinePaths("generateTypes", outputBaseline + ts.Extension.Dts), actual);
|
||||
}
|
||||
else {
|
||||
assert.equal(actual, output, `generateTypes output for ${name} does not match`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public configurePlugin(pluginName: string, configuration: any): void {
|
||||
(<ts.server.SessionClient>this.languageService).configurePlugin(pluginName, configuration);
|
||||
}
|
||||
@@ -4140,19 +4127,6 @@ namespace FourSlashInterface {
|
||||
public noMoveToNewFile(): void {
|
||||
this.state.noMoveToNewFile();
|
||||
}
|
||||
|
||||
public generateTypes(...options: GenerateTypesOptions[]): void {
|
||||
this.state.generateTypes(options);
|
||||
}
|
||||
}
|
||||
|
||||
export interface GenerateTypesOptions {
|
||||
readonly name?: string;
|
||||
readonly value: unknown;
|
||||
readonly global?: boolean;
|
||||
// Exactly one of these should be set:
|
||||
readonly output?: string;
|
||||
readonly outputBaseline?: string;
|
||||
}
|
||||
|
||||
export class Edit {
|
||||
|
||||
@@ -4,7 +4,6 @@ namespace ts.server {
|
||||
export const ActionSet: ActionSet = "action::set";
|
||||
export const ActionInvalidate: ActionInvalidate = "action::invalidate";
|
||||
export const ActionPackageInstalled: ActionPackageInstalled = "action::packageInstalled";
|
||||
export const ActionValueInspected: ActionValueInspected = "action::valueInspected";
|
||||
export const EventTypesRegistry: EventTypesRegistry = "event::typesRegistry";
|
||||
export const EventBeginInstallTypes: EventBeginInstallTypes = "event::beginInstallTypes";
|
||||
export const EventEndInstallTypes: EventEndInstallTypes = "event::endInstallTypes";
|
||||
|
||||
+3
-16
@@ -2,14 +2,13 @@ declare namespace ts.server {
|
||||
export type ActionSet = "action::set";
|
||||
export type ActionInvalidate = "action::invalidate";
|
||||
export type ActionPackageInstalled = "action::packageInstalled";
|
||||
export type ActionValueInspected = "action::valueInspected";
|
||||
export type EventTypesRegistry = "event::typesRegistry";
|
||||
export type EventBeginInstallTypes = "event::beginInstallTypes";
|
||||
export type EventEndInstallTypes = "event::endInstallTypes";
|
||||
export type EventInitializationFailed = "event::initializationFailed";
|
||||
|
||||
export interface TypingInstallerResponse {
|
||||
readonly kind: ActionSet | ActionInvalidate | EventTypesRegistry | ActionPackageInstalled | ActionValueInspected | EventBeginInstallTypes | EventEndInstallTypes | EventInitializationFailed;
|
||||
readonly kind: ActionSet | ActionInvalidate | EventTypesRegistry | ActionPackageInstalled | EventBeginInstallTypes | EventEndInstallTypes | EventInitializationFailed;
|
||||
}
|
||||
|
||||
export interface TypingInstallerRequestWithProjectName {
|
||||
@@ -17,7 +16,7 @@ declare namespace ts.server {
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export type TypingInstallerRequestUnion = DiscoverTypings | CloseProject | TypesRegistryRequest | InstallPackageRequest | InspectValueRequest;
|
||||
export type TypingInstallerRequestUnion = DiscoverTypings | CloseProject | TypesRegistryRequest | InstallPackageRequest;
|
||||
|
||||
export interface DiscoverTypings extends TypingInstallerRequestWithProjectName {
|
||||
readonly fileNames: string[];
|
||||
@@ -44,12 +43,6 @@ declare namespace ts.server {
|
||||
readonly projectRootPath: Path;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface InspectValueRequest {
|
||||
readonly kind: "inspectValue";
|
||||
readonly options: InspectValueOptions;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface TypesRegistryResponse extends TypingInstallerResponse {
|
||||
readonly kind: EventTypesRegistry;
|
||||
@@ -62,12 +55,6 @@ declare namespace ts.server {
|
||||
readonly message: string;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface InspectValueResponse {
|
||||
readonly kind: ActionValueInspected;
|
||||
readonly result: ValueInfo;
|
||||
}
|
||||
|
||||
export interface InitializationFailedResponse extends TypingInstallerResponse {
|
||||
readonly kind: EventInitializationFailed;
|
||||
readonly message: string;
|
||||
@@ -115,5 +102,5 @@ declare namespace ts.server {
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export type TypingInstallerResponseUnion = SetTypings | InvalidateCachedTypings | TypesRegistryResponse | PackageInstalledResponse | InspectValueResponse | InstallTypes | InitializationFailedResponse;
|
||||
export type TypingInstallerResponseUnion = SetTypings | InvalidateCachedTypings | TypesRegistryResponse | PackageInstalledResponse | InstallTypes | InitializationFailedResponse;
|
||||
}
|
||||
|
||||
@@ -277,10 +277,6 @@ namespace ts.server {
|
||||
installPackage(options: InstallPackageOptions): Promise<ApplyCodeActionCommandResult> {
|
||||
return this.typingsCache.installPackage({ ...options, projectName: this.projectName, projectRootPath: this.toPath(this.currentDirectory) });
|
||||
}
|
||||
/* @internal */
|
||||
inspectValue(options: InspectValueOptions): Promise<ValueInfo> {
|
||||
return this.typingsCache.inspectValue(options);
|
||||
}
|
||||
|
||||
private get typingsCache(): TypingsCache {
|
||||
return this.projectService.typingsCache;
|
||||
|
||||
@@ -8,8 +8,6 @@ namespace ts.server {
|
||||
export interface ITypingsInstaller {
|
||||
isKnownTypesPackageName(name: string): boolean;
|
||||
installPackage(options: InstallPackageOptionsWithProject): Promise<ApplyCodeActionCommandResult>;
|
||||
/* @internal */
|
||||
inspectValue(options: InspectValueOptions): Promise<ValueInfo>;
|
||||
enqueueInstallTypingsRequest(p: Project, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray<string> | undefined): void;
|
||||
attach(projectService: ProjectService): void;
|
||||
onProjectClosed(p: Project): void;
|
||||
@@ -20,7 +18,6 @@ namespace ts.server {
|
||||
isKnownTypesPackageName: returnFalse,
|
||||
// Should never be called because we never provide a types registry.
|
||||
installPackage: notImplemented,
|
||||
inspectValue: notImplemented,
|
||||
enqueueInstallTypingsRequest: noop,
|
||||
attach: noop,
|
||||
onProjectClosed: noop,
|
||||
@@ -98,10 +95,6 @@ namespace ts.server {
|
||||
return this.installer.installPackage(options);
|
||||
}
|
||||
|
||||
inspectValue(options: InspectValueOptions): Promise<ValueInfo> {
|
||||
return this.installer.inspectValue(options);
|
||||
}
|
||||
|
||||
enqueueInstallTypingsForProject(project: Project, unresolvedImports: SortedReadonlyArray<string> | undefined, forceRefresh: boolean) {
|
||||
const typeAcquisition = project.getTypeAcquisition();
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
namespace ts.codefix {
|
||||
const fixName = "fixCannotFindModule";
|
||||
const fixIdInstallTypesPackage = "installTypesPackage";
|
||||
const fixIdGenerateTypes = "generateTypes";
|
||||
|
||||
const errorCodeCannotFindModule = Diagnostics.Cannot_find_module_0.code;
|
||||
const errorCodes = [
|
||||
@@ -17,13 +16,12 @@ namespace ts.codefix {
|
||||
if (packageName === undefined) return undefined;
|
||||
const typesPackageName = getTypesPackageNameToInstall(packageName, host, context.errorCode);
|
||||
return typesPackageName === undefined
|
||||
? singleElementArray(tryGetGenerateTypesAction(context, packageName))
|
||||
? []
|
||||
: [createCodeFixAction(fixName, /*changes*/ [], [Diagnostics.Install_0, typesPackageName], fixIdInstallTypesPackage, Diagnostics.Install_all_missing_types_packages, getInstallCommand(sourceFile.fileName, typesPackageName))];
|
||||
},
|
||||
fixIds: [fixIdInstallTypesPackage, fixIdGenerateTypes],
|
||||
fixIds: [fixIdInstallTypesPackage],
|
||||
getAllCodeActions: context => {
|
||||
let savedTypesDir: string | null | undefined = null; // tslint:disable-line no-null-keyword
|
||||
return codeFixAll(context, errorCodes, (changes, diag, commands) => {
|
||||
return codeFixAll(context, errorCodes, (_changes, diag, commands) => {
|
||||
const packageName = tryGetImportedPackageName(diag.file, diag.start);
|
||||
if (packageName === undefined) return undefined;
|
||||
switch (context.fixId) {
|
||||
@@ -34,12 +32,6 @@ namespace ts.codefix {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case fixIdGenerateTypes: {
|
||||
const typesDir = savedTypesDir !== null ? savedTypesDir : savedTypesDir = getOrCreateTypesDirectory(changes, context);
|
||||
const command = typesDir === undefined ? undefined : tryGenerateTypes(typesDir, packageName, context);
|
||||
if (command) commands.push(command);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
Debug.fail(`Bad fixId: ${context.fixId}`);
|
||||
}
|
||||
@@ -47,88 +39,6 @@ namespace ts.codefix {
|
||||
},
|
||||
});
|
||||
|
||||
function tryGetGenerateTypesAction(context: CodeFixContextBase, packageName: string): CodeFixAction | undefined {
|
||||
let command: GenerateTypesAction | undefined;
|
||||
const changes = textChanges.ChangeTracker.with(context, t => {
|
||||
const typesDir = getOrCreateTypesDirectory(t, context);
|
||||
command = typesDir === undefined ? undefined : tryGenerateTypes(typesDir, packageName, context);
|
||||
});
|
||||
return command && createCodeFixAction(fixName, changes, [Diagnostics.Generate_types_for_0, packageName], fixIdGenerateTypes, Diagnostics.Generate_types_for_all_packages_without_types, command);
|
||||
}
|
||||
|
||||
function tryGenerateTypes(typesDir: string, packageName: string, context: CodeFixContextBase): GenerateTypesAction | undefined {
|
||||
const file = context.sourceFile.fileName;
|
||||
const fileToGenerateTypesFor = tryResolveJSModule(packageName, getDirectoryPath(file), context.host as ModuleResolutionHost); // TODO: GH#18217
|
||||
if (fileToGenerateTypesFor === undefined) return undefined;
|
||||
|
||||
const outputFileName = resolvePath(getDirectoryPath(context.program.getCompilerOptions().configFile!.fileName), typesDir, packageName + ".d.ts");
|
||||
if (context.host.fileExists!(outputFileName)) return undefined;
|
||||
return { type: "generate types", file, fileToGenerateTypesFor, outputFileName };
|
||||
}
|
||||
|
||||
// If no types directory exists yet, adds it to tsconfig.json
|
||||
function getOrCreateTypesDirectory(changes: textChanges.ChangeTracker, context: CodeFixContextBase): string | undefined {
|
||||
const { configFile } = context.program.getCompilerOptions();
|
||||
if (!configFile) return undefined;
|
||||
|
||||
const tsconfigObjectLiteral = getTsConfigObjectLiteralExpression(configFile);
|
||||
if (!tsconfigObjectLiteral) return undefined;
|
||||
|
||||
const compilerOptionsProperty = findJsonProperty(tsconfigObjectLiteral, "compilerOptions");
|
||||
if (!compilerOptionsProperty) {
|
||||
const newCompilerOptions = createObjectLiteral([makeDefaultBaseUrl(), makeDefaultPaths()]);
|
||||
changes.insertNodeAtObjectStart(configFile, tsconfigObjectLiteral, createJsonPropertyAssignment("compilerOptions", newCompilerOptions));
|
||||
return defaultTypesDirectoryName;
|
||||
}
|
||||
|
||||
const compilerOptions = compilerOptionsProperty.initializer;
|
||||
if (!isObjectLiteralExpression(compilerOptions)) return defaultTypesDirectoryName;
|
||||
|
||||
const baseUrl = getOrAddBaseUrl(changes, configFile, compilerOptions);
|
||||
const typesDirectoryFromPathMapping = getOrAddPathMapping(changes, configFile, compilerOptions);
|
||||
return combinePaths(baseUrl, typesDirectoryFromPathMapping);
|
||||
}
|
||||
|
||||
const defaultBaseUrl = ".";
|
||||
function makeDefaultBaseUrl(): PropertyAssignment {
|
||||
return createJsonPropertyAssignment("baseUrl", createStringLiteral(defaultBaseUrl));
|
||||
}
|
||||
function getOrAddBaseUrl(changes: textChanges.ChangeTracker, tsconfig: TsConfigSourceFile, compilerOptions: ObjectLiteralExpression): string {
|
||||
const baseUrlProp = findJsonProperty(compilerOptions, "baseUrl");
|
||||
if (baseUrlProp) {
|
||||
return isStringLiteral(baseUrlProp.initializer) ? baseUrlProp.initializer.text : defaultBaseUrl;
|
||||
}
|
||||
else {
|
||||
changes.insertNodeAtObjectStart(tsconfig, compilerOptions, makeDefaultBaseUrl());
|
||||
return defaultBaseUrl;
|
||||
}
|
||||
}
|
||||
|
||||
const defaultTypesDirectoryName = "types";
|
||||
function makeDefaultPathMapping(): PropertyAssignment {
|
||||
return createJsonPropertyAssignment("*", createArrayLiteral([createStringLiteral(`${defaultTypesDirectoryName}/*`)]));
|
||||
}
|
||||
function makeDefaultPaths(): PropertyAssignment {
|
||||
return createJsonPropertyAssignment("paths", createObjectLiteral([makeDefaultPathMapping()]));
|
||||
}
|
||||
function getOrAddPathMapping(changes: textChanges.ChangeTracker, tsconfig: TsConfigSourceFile, compilerOptions: ObjectLiteralExpression) {
|
||||
const paths = findJsonProperty(compilerOptions, "paths");
|
||||
if (!paths || !isObjectLiteralExpression(paths.initializer)) {
|
||||
changes.insertNodeAtObjectStart(tsconfig, compilerOptions, makeDefaultPaths());
|
||||
return defaultTypesDirectoryName;
|
||||
}
|
||||
|
||||
// Look for an existing path mapping. Should look like `"*": "foo/*"`.
|
||||
const existing = firstDefined(paths.initializer.properties, prop =>
|
||||
isPropertyAssignment(prop) && isStringLiteral(prop.name) && prop.name.text === "*" && isArrayLiteralExpression(prop.initializer)
|
||||
? firstDefined(prop.initializer.elements, value => isStringLiteral(value) ? tryRemoveSuffix(value.text, "/*") : undefined)
|
||||
: undefined);
|
||||
if (existing) return existing;
|
||||
|
||||
changes.insertNodeAtObjectStart(tsconfig, paths.initializer, makeDefaultPathMapping());
|
||||
return defaultTypesDirectoryName;
|
||||
}
|
||||
|
||||
function getInstallCommand(fileName: string, packageName: string): InstallPackageAction {
|
||||
return { type: "install package", file: fileName, packageName };
|
||||
}
|
||||
|
||||
@@ -1,252 +0,0 @@
|
||||
namespace ts {
|
||||
export function generateTypesForModule(name: string, moduleValue: unknown, formatSettings: FormatCodeSettings): string {
|
||||
return generateTypesForModuleOrGlobal(name, moduleValue, formatSettings, OutputKind.ExportEquals);
|
||||
}
|
||||
|
||||
export function generateTypesForGlobal(name: string, globalValue: unknown, formatSettings: FormatCodeSettings): string {
|
||||
return generateTypesForModuleOrGlobal(name, globalValue, formatSettings, OutputKind.Global);
|
||||
}
|
||||
|
||||
function generateTypesForModuleOrGlobal(name: string, globalValue: unknown, formatSettings: FormatCodeSettings, outputKind: OutputKind.ExportEquals | OutputKind.Global): string {
|
||||
return valueInfoToDeclarationFileText(inspectValue(name, globalValue), formatSettings, outputKind);
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function valueInfoToDeclarationFileText(valueInfo: ValueInfo, formatSettings: FormatCodeSettings, outputKind: OutputKind.ExportEquals | OutputKind.Global = OutputKind.ExportEquals): string {
|
||||
return textChanges.getNewFileText(toStatements(valueInfo, outputKind), ScriptKind.TS, formatSettings.newLineCharacter || "\n", formatting.getFormatContext(formatSettings));
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
const enum OutputKind { ExportEquals, NamedExport, NamespaceMember, Global }
|
||||
function toNamespaceMemberStatements(info: ValueInfo): ReadonlyArray<Statement> {
|
||||
return toStatements(info, OutputKind.NamespaceMember);
|
||||
}
|
||||
function toStatements(info: ValueInfo, kind: OutputKind): ReadonlyArray<Statement> {
|
||||
const isDefault = info.name === InternalSymbolName.Default;
|
||||
const name = isDefault ? "_default" : info.name;
|
||||
if (!isValidIdentifier(name) || isDefault && kind !== OutputKind.NamedExport) return emptyArray;
|
||||
|
||||
const modifiers = isDefault && info.kind === ValueKind.FunctionOrClass ? [createModifier(SyntaxKind.ExportKeyword), createModifier(SyntaxKind.DefaultKeyword)]
|
||||
: kind === OutputKind.Global || kind === OutputKind.ExportEquals ? [createModifier(SyntaxKind.DeclareKeyword)]
|
||||
: kind === OutputKind.NamedExport ? [createModifier(SyntaxKind.ExportKeyword)]
|
||||
: undefined;
|
||||
const exportEquals = () => kind === OutputKind.ExportEquals ? [exportEqualsOrDefault(info.name, /*isExportEquals*/ true)] : emptyArray;
|
||||
const exportDefault = () => isDefault ? [exportEqualsOrDefault("_default", /*isExportEquals*/ false)] : emptyArray;
|
||||
|
||||
switch (info.kind) {
|
||||
case ValueKind.FunctionOrClass:
|
||||
return [...exportEquals(), ...functionOrClassToStatements(modifiers, name, info)];
|
||||
case ValueKind.Object:
|
||||
const { members, hasNontrivialPrototype } = info;
|
||||
if (!hasNontrivialPrototype) {
|
||||
if (kind === OutputKind.ExportEquals) {
|
||||
return flatMap(members, v => toStatements(v, OutputKind.NamedExport));
|
||||
}
|
||||
if (members.some(m => m.kind === ValueKind.FunctionOrClass)) {
|
||||
// If some member is a function, use a namespace so it gets a FunctionDeclaration or ClassDeclaration.
|
||||
return [...exportDefault(), createNamespace(modifiers, name, flatMap(members, toNamespaceMemberStatements))];
|
||||
}
|
||||
}
|
||||
// falls through
|
||||
case ValueKind.Const:
|
||||
case ValueKind.Array: {
|
||||
const comment = info.kind === ValueKind.Const ? info.comment : undefined;
|
||||
const constVar = createVariableStatement(modifiers, createVariableDeclarationList([createVariableDeclaration(name, toType(info))], NodeFlags.Const));
|
||||
return [...exportEquals(), ...exportDefault(), addComment(constVar, comment)];
|
||||
}
|
||||
default:
|
||||
return Debug.assertNever(info);
|
||||
}
|
||||
}
|
||||
function exportEqualsOrDefault(name: string, isExportEquals: boolean): ExportAssignment {
|
||||
return createExportAssignment(/*decorators*/ undefined, /*modifiers*/ undefined, isExportEquals, createIdentifier(name));
|
||||
}
|
||||
|
||||
function functionOrClassToStatements(modifiers: Modifiers, name: string, { source, prototypeMembers, namespaceMembers }: ValueInfoFunctionOrClass): ReadonlyArray<Statement> {
|
||||
const fnAst = parseClassOrFunctionBody(source);
|
||||
const { parameters, returnType } = fnAst === undefined ? { parameters: emptyArray, returnType: anyType() } : getParametersAndReturnType(fnAst);
|
||||
const protoOrInstanceMembers = createMap<MethodDeclaration | PropertyDeclaration>();
|
||||
if (typeof fnAst === "object") getConstructorFunctionInstanceProperties(fnAst, protoOrInstanceMembers);
|
||||
for (const p of prototypeMembers) {
|
||||
// ignore non-functions on the prototype
|
||||
if (p.kind === ValueKind.FunctionOrClass) {
|
||||
const m = tryGetMethod(p);
|
||||
if (m) {
|
||||
protoOrInstanceMembers.set(p.name, m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const classStaticMembers: ClassElement[] | undefined =
|
||||
protoOrInstanceMembers.size !== 0 || fnAst === undefined || typeof fnAst !== "number" && fnAst.kind === SyntaxKind.Constructor ? [] : undefined;
|
||||
|
||||
const namespaceStatements = flatMap(namespaceMembers, info => {
|
||||
if (!isValidIdentifier(info.name)) return undefined;
|
||||
if (classStaticMembers) {
|
||||
switch (info.kind) {
|
||||
case ValueKind.Object:
|
||||
if (info.members.some(m => m.kind === ValueKind.FunctionOrClass)) {
|
||||
break;
|
||||
}
|
||||
// falls through
|
||||
case ValueKind.Array:
|
||||
case ValueKind.Const:
|
||||
classStaticMembers.push(
|
||||
addComment(
|
||||
createProperty(/*decorators*/ undefined, [createModifier(SyntaxKind.StaticKeyword)], info.name, /*questionOrExclamationToken*/ undefined, toType(info), /*initializer*/ undefined),
|
||||
info.kind === ValueKind.Const ? info.comment : undefined));
|
||||
return undefined;
|
||||
case ValueKind.FunctionOrClass:
|
||||
if (!info.namespaceMembers.length) { // Else, can't merge a static method with a namespace. Must make it a function on the namespace.
|
||||
const sig = tryGetMethod(info, [createModifier(SyntaxKind.StaticKeyword)]);
|
||||
if (sig) {
|
||||
classStaticMembers.push(sig);
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Debug.assertNever(info);
|
||||
}
|
||||
}
|
||||
return toStatements(info, OutputKind.NamespaceMember);
|
||||
});
|
||||
|
||||
const decl = classStaticMembers
|
||||
? createClassDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
modifiers,
|
||||
name,
|
||||
/*typeParameters*/ undefined,
|
||||
/*heritageClauses*/ undefined,
|
||||
[
|
||||
...classStaticMembers,
|
||||
...(parameters.length ? [createConstructor(/*decorators*/ undefined, /*modifiers*/ undefined, parameters, /*body*/ undefined)] : emptyArray),
|
||||
...arrayFrom(protoOrInstanceMembers.values()),
|
||||
])
|
||||
: createFunctionDeclaration(/*decorators*/ undefined, modifiers, /*asteriskToken*/ undefined, name, /*typeParameters*/ undefined, parameters, returnType, /*body*/ undefined);
|
||||
return [decl, ...(namespaceStatements.length === 0 ? emptyArray : [createNamespace(modifiers && modifiers.map(m => getSynthesizedDeepClone(m)), name, namespaceStatements)])];
|
||||
}
|
||||
|
||||
function tryGetMethod({ name, source }: ValueInfoFunctionOrClass, modifiers?: Modifiers): MethodDeclaration | undefined {
|
||||
if (!isValidIdentifier(name)) return undefined;
|
||||
const fnAst = parseClassOrFunctionBody(source);
|
||||
if (fnAst === undefined || (typeof fnAst !== "number" && fnAst.kind === SyntaxKind.Constructor)) return undefined;
|
||||
const sig = getParametersAndReturnType(fnAst);
|
||||
return sig && createMethod(
|
||||
/*decorators*/ undefined,
|
||||
modifiers,
|
||||
/*asteriskToken*/ undefined,
|
||||
name,
|
||||
/*questionToken*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
sig.parameters,
|
||||
sig.returnType,
|
||||
/*body*/ undefined);
|
||||
}
|
||||
|
||||
function toType(info: ValueInfo): TypeNode {
|
||||
switch (info.kind) {
|
||||
case ValueKind.Const:
|
||||
return createTypeReferenceNode(info.typeName, /*typeArguments*/ undefined);
|
||||
case ValueKind.Array:
|
||||
return createArrayTypeNode(toType(info.inner));
|
||||
case ValueKind.FunctionOrClass:
|
||||
return createTypeReferenceNode("Function", /*typeArguments*/ undefined); // Normally we create a FunctionDeclaration, but this can happen for a function in an array.
|
||||
case ValueKind.Object:
|
||||
return createTypeLiteralNode(info.members.map(m => createPropertySignature(/*modifiers*/ undefined, toPropertyName(m.name), /*questionToken*/ undefined, toType(m), /*initializer*/ undefined)));
|
||||
default:
|
||||
return Debug.assertNever(info);
|
||||
}
|
||||
}
|
||||
function toPropertyName(name: string): Identifier | StringLiteral {
|
||||
return isIdentifierText(name, ScriptTarget.ESNext) ? createIdentifier(name) : createStringLiteral(name);
|
||||
}
|
||||
|
||||
// Parses assignments to "this.x" in the constructor into class property declarations
|
||||
function getConstructorFunctionInstanceProperties(fnAst: FunctionOrConstructorNode, members: Map<MethodDeclaration | PropertyDeclaration>): void {
|
||||
forEachOwnNodeOfFunction(fnAst, node => {
|
||||
if (isAssignmentExpression(node, /*excludeCompoundAssignment*/ true) &&
|
||||
isPropertyAccessExpression(node.left) && node.left.expression.kind === SyntaxKind.ThisKeyword) {
|
||||
const name = node.left.name.text;
|
||||
if (!isJsPrivate(name)) {
|
||||
getOrUpdate(members, name, () => createProperty(/*decorators*/ undefined, /*modifiers*/ undefined, name, /*questionOrExclamationToken*/ undefined, anyType(), /*initializer*/ undefined));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
interface ParametersAndReturnType { readonly parameters: ReadonlyArray<ParameterDeclaration>; readonly returnType: TypeNode; }
|
||||
function getParametersAndReturnType(fnAst: FunctionOrConstructor): ParametersAndReturnType {
|
||||
if (typeof fnAst === "number") {
|
||||
return { parameters: fill(fnAst, i => makeParameter(`p${i}`, anyType())), returnType: anyType() };
|
||||
}
|
||||
let usedArguments = false, hasReturn = false;
|
||||
forEachOwnNodeOfFunction(fnAst, node => {
|
||||
usedArguments = usedArguments || isIdentifier(node) && node.text === "arguments";
|
||||
hasReturn = hasReturn || isReturnStatement(node) && !!node.expression && node.expression.kind !== SyntaxKind.VoidExpression;
|
||||
});
|
||||
const parameters = [
|
||||
...fnAst.parameters.map(p => makeParameter(`${p.name.getText()}`, inferParameterType(fnAst, p))),
|
||||
...(usedArguments ? [makeRestParameter()] : emptyArray),
|
||||
];
|
||||
return { parameters, returnType: hasReturn ? anyType() : createKeywordTypeNode(SyntaxKind.VoidKeyword) };
|
||||
}
|
||||
function makeParameter(name: string, type: TypeNode): ParameterDeclaration {
|
||||
return createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, name, /*questionToken*/ undefined, type);
|
||||
}
|
||||
function makeRestParameter(): ParameterDeclaration {
|
||||
return createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, createToken(SyntaxKind.DotDotDotToken), "args", /*questionToken*/ undefined, createArrayTypeNode(anyType()));
|
||||
}
|
||||
|
||||
type FunctionOrConstructorNode = FunctionExpression | ArrowFunction | ConstructorDeclaration | MethodDeclaration;
|
||||
type FunctionOrConstructor = FunctionOrConstructorNode | number; // number is for native function
|
||||
/** Returns 'undefined' for class with no declared constructor */
|
||||
function parseClassOrFunctionBody(source: string | number): FunctionOrConstructor | undefined {
|
||||
if (typeof source === "number") return source;
|
||||
const classOrFunction = tryCast(parseExpression(source), (node): node is FunctionExpression | ArrowFunction | ClassExpression => isFunctionExpression(node) || isArrowFunction(node) || isClassExpression(node));
|
||||
return classOrFunction
|
||||
? isClassExpression(classOrFunction) ? find(classOrFunction.members, isConstructorDeclaration) : classOrFunction
|
||||
// If that didn't parse, it's a method `m() {}`. Parse again inside of an object literal.
|
||||
: cast(first(cast(parseExpression(`{ ${source} }`), isObjectLiteralExpression).properties), isMethodDeclaration);
|
||||
}
|
||||
|
||||
function parseExpression(expr: string): Expression {
|
||||
const text = `const _ = ${expr}`;
|
||||
const srcFile = createSourceFile("test.ts", text, ScriptTarget.Latest, /*setParentNodes*/ true);
|
||||
return first(cast(first(srcFile.statements), isVariableStatement).declarationList.declarations).initializer!;
|
||||
}
|
||||
|
||||
function inferParameterType(_fn: FunctionOrConstructor, _param: ParameterDeclaration): TypeNode {
|
||||
// TODO: Inspect function body for clues (see inferFromUsage.ts)
|
||||
return anyType();
|
||||
}
|
||||
|
||||
// Descends through all nodes in a function, but not in nested functions.
|
||||
function forEachOwnNodeOfFunction(fnAst: FunctionOrConstructorNode, cb: (node: Node) => void) {
|
||||
fnAst.body!.forEachChild(function recur(node) {
|
||||
cb(node);
|
||||
if (!isFunctionLike(node)) node.forEachChild(recur);
|
||||
});
|
||||
}
|
||||
|
||||
function isValidIdentifier(name: string): boolean {
|
||||
const keyword = stringToToken(name);
|
||||
return !(keyword && isNonContextualKeyword(keyword)) && isIdentifierText(name, ScriptTarget.ESNext);
|
||||
}
|
||||
|
||||
type Modifiers = ReadonlyArray<Modifier> | undefined;
|
||||
|
||||
function addComment<T extends Node>(node: T, comment: string | undefined): T {
|
||||
if (comment !== undefined) addSyntheticLeadingComment(node, SyntaxKind.SingleLineCommentTrivia, comment);
|
||||
return node;
|
||||
}
|
||||
|
||||
function anyType(): KeywordTypeNode {
|
||||
return createKeywordTypeNode(SyntaxKind.AnyKeyword);
|
||||
}
|
||||
|
||||
function createNamespace(modifiers: Modifiers, name: string, statements: ReadonlyArray<Statement>): NamespaceDeclaration {
|
||||
return createModuleDeclaration(/*decorators*/ undefined, modifiers, createIdentifier(name), createModuleBlock(statements), NodeFlags.Namespace) as NamespaceDeclaration;
|
||||
}
|
||||
}
|
||||
@@ -1833,30 +1833,15 @@ namespace ts {
|
||||
function applyCodeActionCommand(fileName: Path, action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
|
||||
function applyCodeActionCommand(fileName: Path | CodeActionCommand | CodeActionCommand[], actionOrFormatSettingsOrUndefined?: CodeActionCommand | CodeActionCommand[] | FormatCodeSettings): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]> {
|
||||
const action = typeof fileName === "string" ? actionOrFormatSettingsOrUndefined as CodeActionCommand | CodeActionCommand[] : fileName as CodeActionCommand[];
|
||||
const formatSettings = typeof fileName !== "string" ? actionOrFormatSettingsOrUndefined as FormatCodeSettings : undefined;
|
||||
return isArray(action) ? Promise.all(action.map(a => applySingleCodeActionCommand(a, formatSettings))) : applySingleCodeActionCommand(action, formatSettings);
|
||||
return isArray(action) ? Promise.all(action.map(a => applySingleCodeActionCommand(a))) : applySingleCodeActionCommand(action);
|
||||
}
|
||||
|
||||
function applySingleCodeActionCommand(action: CodeActionCommand, formatSettings: FormatCodeSettings | undefined): Promise<ApplyCodeActionCommandResult> {
|
||||
function applySingleCodeActionCommand(action: CodeActionCommand): Promise<ApplyCodeActionCommandResult> {
|
||||
const getPath = (path: string): Path => toPath(path, currentDirectory, getCanonicalFileName);
|
||||
switch (action.type) {
|
||||
case "install package":
|
||||
return host.installPackage
|
||||
? host.installPackage({ fileName: getPath(action.file), packageName: action.packageName })
|
||||
: Promise.reject("Host does not implement `installPackage`");
|
||||
case "generate types": {
|
||||
const { fileToGenerateTypesFor, outputFileName } = action;
|
||||
if (!host.inspectValue) return Promise.reject("Host does not implement `installPackage`");
|
||||
const valueInfoPromise = host.inspectValue({ fileNameToRequire: fileToGenerateTypesFor });
|
||||
return valueInfoPromise.then(valueInfo => {
|
||||
const fullOut = getPath(outputFileName);
|
||||
host.writeFile!(fullOut, valueInfoToDeclarationFileText(valueInfo, formatSettings || testFormatSettings)); // TODO: GH#18217
|
||||
return { successMessage: `Wrote types to '${fullOut}'` };
|
||||
});
|
||||
}
|
||||
default:
|
||||
return Debug.assertNever(action);
|
||||
}
|
||||
Debug.assertEqual(action.type, "install package");
|
||||
return host.installPackage
|
||||
? host.installPackage({ fileName: getPath(action.file), packageName: action.packageName })
|
||||
: Promise.reject("Host does not implement `installPackage`");
|
||||
}
|
||||
|
||||
function getDocCommentTemplateAtPosition(fileName: string, position: number): TextInsertion | undefined {
|
||||
|
||||
@@ -73,7 +73,6 @@
|
||||
"codefixes/helpers.ts",
|
||||
"codefixes/fixInvalidImportSyntax.ts",
|
||||
"codefixes/fixStrictClassInitialization.ts",
|
||||
"codefixes/generateTypes.ts",
|
||||
"codefixes/requireInTs.ts",
|
||||
"codefixes/useDefaultImport.ts",
|
||||
"codefixes/fixAddModuleReferTypeMissingTypeof.ts",
|
||||
|
||||
+1
-12
@@ -230,7 +230,6 @@ namespace ts {
|
||||
|
||||
isKnownTypesPackageName?(name: string): boolean;
|
||||
installPackage?(options: InstallPackageOptions): Promise<ApplyCodeActionCommandResult>;
|
||||
/* @internal */ inspectValue?(options: InspectValueOptions): Promise<ValueInfo>;
|
||||
writeFile?(fileName: string, content: string): void;
|
||||
|
||||
/* @internal */
|
||||
@@ -534,7 +533,7 @@ namespace ts {
|
||||
|
||||
// Publicly, this type is just `{}`. Internally it is a union of all the actions we use.
|
||||
// See `commands?: {}[]` in protocol.ts
|
||||
export type CodeActionCommand = InstallPackageAction | GenerateTypesAction;
|
||||
export type CodeActionCommand = InstallPackageAction;
|
||||
|
||||
export interface InstallPackageAction {
|
||||
/* @internal */ readonly type: "install package";
|
||||
@@ -542,16 +541,6 @@ namespace ts {
|
||||
/* @internal */ readonly packageName: string;
|
||||
}
|
||||
|
||||
export interface GenerateTypesAction extends GenerateTypesOptions {
|
||||
/* @internal */ readonly type: "generate types";
|
||||
}
|
||||
|
||||
export interface GenerateTypesOptions {
|
||||
readonly file: string; // File that was importing fileToGenerateTypesFor; used for formatting options.
|
||||
readonly fileToGenerateTypesFor: string;
|
||||
readonly outputFileName: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* A set of one or more available refactoring actions, grouped under a parent refactoring.
|
||||
*/
|
||||
|
||||
@@ -390,7 +390,6 @@ namespace ts.projectSystem {
|
||||
const typingsInstaller: server.ITypingsInstaller = {
|
||||
isKnownTypesPackageName: returnFalse,
|
||||
installPackage: notImplemented,
|
||||
inspectValue: notImplemented,
|
||||
enqueueInstallTypingsRequest: (proj, typeAcquisition, unresolvedImports) => {
|
||||
assert.isUndefined(request);
|
||||
request = JSON.stringify(server.createInstallTypingsRequest(proj, typeAcquisition, unresolvedImports || server.emptyArray, cachePath));
|
||||
|
||||
+1
-12
@@ -232,7 +232,6 @@ namespace ts.server {
|
||||
private static readonly maxActiveRequestCount = 10;
|
||||
private static readonly requestDelayMillis = 100;
|
||||
private packageInstalledPromise: { resolve(value: ApplyCodeActionCommandResult): void, reject(reason: unknown): void } | undefined;
|
||||
private inspectValuePromise: { resolve(value: ValueInfo): void } | undefined;
|
||||
|
||||
constructor(
|
||||
private readonly telemetryEnabled: boolean,
|
||||
@@ -270,12 +269,6 @@ namespace ts.server {
|
||||
});
|
||||
}
|
||||
|
||||
inspectValue(options: InspectValueOptions): Promise<ValueInfo> {
|
||||
this.send<InspectValueRequest>({ kind: "inspectValue", options });
|
||||
Debug.assert(this.inspectValuePromise === undefined);
|
||||
return new Promise<ValueInfo>(resolve => { this.inspectValuePromise = { resolve }; });
|
||||
}
|
||||
|
||||
attach(projectService: ProjectService) {
|
||||
this.projectService = projectService;
|
||||
if (this.logger.hasLevel(LogLevel.requestTime)) {
|
||||
@@ -363,7 +356,7 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
private handleMessage(response: TypesRegistryResponse | PackageInstalledResponse | InspectValueResponse | SetTypings | InvalidateCachedTypings | BeginInstallTypes | EndInstallTypes | InitializationFailedResponse) {
|
||||
private handleMessage(response: TypesRegistryResponse | PackageInstalledResponse | SetTypings | InvalidateCachedTypings | BeginInstallTypes | EndInstallTypes | InitializationFailedResponse) {
|
||||
if (this.logger.hasLevel(LogLevel.verbose)) {
|
||||
this.logger.info(`Received response:${stringifyIndented(response)}`);
|
||||
}
|
||||
@@ -388,10 +381,6 @@ namespace ts.server {
|
||||
this.event(response, "setTypings");
|
||||
break;
|
||||
}
|
||||
case ActionValueInspected:
|
||||
this.inspectValuePromise!.resolve(response.result);
|
||||
this.inspectValuePromise = undefined;
|
||||
break;
|
||||
case EventInitializationFailed: {
|
||||
const body: protocol.TypesInstallerInitializationFailedEventBody = {
|
||||
message: response.message
|
||||
|
||||
@@ -168,11 +168,6 @@ namespace ts.server.typingsInstaller {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "inspectValue": {
|
||||
const response: InspectValueResponse = { kind: ActionValueInspected, result: inspectModule(req.options.fileNameToRequire) };
|
||||
this.sendResponse(response);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
Debug.assertNever(req);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user