Revert "Proposed expandable hover API" (#61132)

This commit is contained in:
Gabriela Araujo Britto
2025-02-07 12:44:02 -08:00
committed by GitHub
parent c3ae7c418f
commit 34ea32f8ce
30 changed files with 57 additions and 8169 deletions
+32 -105
View File
@@ -1132,7 +1132,6 @@ import {
WhileStatement,
WideningContext,
WithStatement,
WriterContextOut,
YieldExpression,
} from "./_namespaces/ts.js";
import * as moduleSpecifiers from "./_namespaces/ts.moduleSpecifiers.js";
@@ -1720,8 +1719,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
writeSignature: (signature, enclosingDeclaration, flags, kind, writer) => {
return signatureToString(signature, getParseTreeNode(enclosingDeclaration), flags, kind, writer);
},
writeType: (type, enclosingDeclaration, flags, writer, verbosityLevel, out) => {
return typeToString(type, getParseTreeNode(enclosingDeclaration), flags, writer, verbosityLevel, out);
writeType: (type, enclosingDeclaration, flags, writer) => {
return typeToString(type, getParseTreeNode(enclosingDeclaration), flags, writer);
},
writeSymbol: (symbol, enclosingDeclaration, meaning, flags, writer) => {
return symbolToString(symbol, getParseTreeNode(enclosingDeclaration), meaning, flags, writer);
@@ -6047,24 +6046,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
}
function typeToString(
type: Type,
enclosingDeclaration?: Node,
flags: TypeFormatFlags = TypeFormatFlags.AllowUniqueESSymbolType | TypeFormatFlags.UseAliasDefinedOutsideCurrentScope,
writer: EmitTextWriter = createTextWriter(""),
verbosityLevel?: number,
out?: WriterContextOut,
): string {
const noTruncation = compilerOptions.noErrorTruncation || flags & TypeFormatFlags.NoTruncation || verbosityLevel !== undefined;
const typeNode = nodeBuilder.typeToTypeNode(
type,
enclosingDeclaration,
toNodeBuilderFlags(flags) | NodeBuilderFlags.IgnoreErrors | (noTruncation ? NodeBuilderFlags.NoTruncation : 0),
/*internalFlags*/ undefined,
/*tracker*/ undefined,
verbosityLevel,
out,
);
function typeToString(type: Type, enclosingDeclaration?: Node, flags: TypeFormatFlags = TypeFormatFlags.AllowUniqueESSymbolType | TypeFormatFlags.UseAliasDefinedOutsideCurrentScope, writer: EmitTextWriter = createTextWriter("")): string {
const noTruncation = compilerOptions.noErrorTruncation || flags & TypeFormatFlags.NoTruncation;
const typeNode = nodeBuilder.typeToTypeNode(type, enclosingDeclaration, toNodeBuilderFlags(flags) | NodeBuilderFlags.IgnoreErrors | (noTruncation ? NodeBuilderFlags.NoTruncation : NodeBuilderFlags.None), /*internalFlags*/ undefined);
if (typeNode === undefined) return Debug.fail("should always get typenode");
// The unresolved type gets a synthesized comment on `any` to hint to users that it's not a plain `any`.
// Otherwise, we always strip comments out.
@@ -6281,20 +6265,20 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
};
return {
syntacticBuilderResolver,
typeToTypeNode: (type: Type, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker, verbosityLevel?: number, out?: { couldUnfoldMore: boolean; }) => withContext(enclosingDeclaration, flags, internalFlags, tracker, verbosityLevel, context => typeToTypeNodeHelper(type, context), out),
typePredicateToTypePredicateNode: (typePredicate: TypePredicate, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, internalFlags, tracker, /*verbosityLevel*/ undefined, context => typePredicateToTypePredicateNodeHelper(typePredicate, context)),
serializeTypeForDeclaration: (declaration: HasInferredType, symbol: Symbol, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, internalFlags, tracker, /*verbosityLevel*/ undefined, context => syntacticNodeBuilder.serializeTypeOfDeclaration(declaration, symbol, context)),
serializeReturnTypeForSignature: (signature: SignatureDeclaration, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, internalFlags, tracker, /*verbosityLevel*/ undefined, context => syntacticNodeBuilder.serializeReturnTypeForSignature(signature, getSymbolOfDeclaration(signature), context)),
serializeTypeForExpression: (expr: Expression, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, internalFlags, tracker, /*verbosityLevel*/ undefined, context => syntacticNodeBuilder.serializeTypeOfExpression(expr, context)),
indexInfoToIndexSignatureDeclaration: (indexInfo: IndexInfo, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, internalFlags, tracker, /*verbosityLevel*/ undefined, context => indexInfoToIndexSignatureDeclarationHelper(indexInfo, context, /*typeNode*/ undefined)),
signatureToSignatureDeclaration: (signature: Signature, kind: SignatureDeclaration["kind"], enclosingDeclaration?: Node, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, internalFlags, tracker, /*verbosityLevel*/ undefined, context => signatureToSignatureDeclarationHelper(signature, kind, context)),
symbolToEntityName: (symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, internalFlags, tracker, /*verbosityLevel*/ undefined, context => symbolToName(symbol, context, meaning, /*expectsIdentifier*/ false)),
symbolToExpression: (symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, internalFlags, tracker, /*verbosityLevel*/ undefined, context => symbolToExpression(symbol, context, meaning)),
symbolToTypeParameterDeclarations: (symbol: Symbol, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, internalFlags, tracker, /*verbosityLevel*/ undefined, context => typeParametersToTypeParameterDeclarations(symbol, context)),
symbolToParameterDeclaration: (symbol: Symbol, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, internalFlags, tracker, /*verbosityLevel*/ undefined, context => symbolToParameterDeclaration(symbol, context)),
typeParameterToDeclaration: (parameter: TypeParameter, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker, verbosityLevel?: number) => withContext(enclosingDeclaration, flags, internalFlags, tracker, verbosityLevel, context => typeParameterToDeclaration(parameter, context)),
symbolTableToDeclarationStatements: (symbolTable: SymbolTable, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, internalFlags, tracker, /*verbosityLevel*/ undefined, context => symbolTableToDeclarationStatements(symbolTable, context)),
symbolToNode: (symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, internalFlags, tracker, /*verbosityLevel*/ undefined, context => symbolToNode(symbol, context, meaning)),
typeToTypeNode: (type: Type, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, internalFlags, tracker, context => typeToTypeNodeHelper(type, context)),
typePredicateToTypePredicateNode: (typePredicate: TypePredicate, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, internalFlags, tracker, context => typePredicateToTypePredicateNodeHelper(typePredicate, context)),
serializeTypeForExpression: (expr: Expression, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, internalFlags, tracker, context => syntacticNodeBuilder.serializeTypeOfExpression(expr, context)),
serializeTypeForDeclaration: (declaration: HasInferredType, symbol: Symbol, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, internalFlags, tracker, context => syntacticNodeBuilder.serializeTypeOfDeclaration(declaration, symbol, context)),
serializeReturnTypeForSignature: (signature: SignatureDeclaration, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, internalFlags, tracker, context => syntacticNodeBuilder.serializeReturnTypeForSignature(signature, getSymbolOfDeclaration(signature), context)),
indexInfoToIndexSignatureDeclaration: (indexInfo: IndexInfo, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, internalFlags, tracker, context => indexInfoToIndexSignatureDeclarationHelper(indexInfo, context, /*typeNode*/ undefined)),
signatureToSignatureDeclaration: (signature: Signature, kind: SignatureDeclaration["kind"], enclosingDeclaration?: Node, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, internalFlags, tracker, context => signatureToSignatureDeclarationHelper(signature, kind, context)),
symbolToEntityName: (symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, internalFlags, tracker, context => symbolToName(symbol, context, meaning, /*expectsIdentifier*/ false)),
symbolToExpression: (symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, internalFlags, tracker, context => symbolToExpression(symbol, context, meaning)),
symbolToTypeParameterDeclarations: (symbol: Symbol, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, internalFlags, tracker, context => typeParametersToTypeParameterDeclarations(symbol, context)),
symbolToParameterDeclaration: (symbol: Symbol, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, internalFlags, tracker, context => symbolToParameterDeclaration(symbol, context)),
typeParameterToDeclaration: (parameter: TypeParameter, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, internalFlags, tracker, context => typeParameterToDeclaration(parameter, context)),
symbolTableToDeclarationStatements: (symbolTable: SymbolTable, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, internalFlags, tracker, context => symbolTableToDeclarationStatements(symbolTable, context)),
symbolToNode: (symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, internalFlags, tracker, context => symbolToNode(symbol, context, meaning)),
};
function getTypeFromTypeNode(context: NodeBuilderContext, node: TypeNode, noMappedTypes?: false): Type;
@@ -6354,15 +6338,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return symbolToExpression(symbol, context, meaning);
}
function withContext<T>(
enclosingDeclaration: Node | undefined,
flags: NodeBuilderFlags | undefined,
internalFlags: InternalNodeBuilderFlags | undefined,
tracker: SymbolTracker | undefined,
verbosityLevel: number | undefined,
cb: (context: NodeBuilderContext) => T,
out?: WriterContextOut,
): T | undefined {
function withContext<T>(enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined, internalFlags: InternalNodeBuilderFlags | undefined, tracker: SymbolTracker | undefined, cb: (context: NodeBuilderContext) => T): T | undefined {
const moduleResolverHost = tracker?.trackSymbol ? tracker.moduleResolverHost :
(internalFlags || InternalNodeBuilderFlags.None) & InternalNodeBuilderFlags.DoNotIncludeSymbolChain ? createBasicNodeBuilderModuleSpecifierResolutionHost(host) :
undefined;
@@ -6372,7 +6348,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
flags: flags || NodeBuilderFlags.None,
internalFlags: internalFlags || InternalNodeBuilderFlags.None,
tracker: undefined!,
unfoldDepth: verbosityLevel ?? -1,
encounteredError: false,
suppressReportInferenceFallback: false,
reportedDiagnostic: false,
@@ -6395,17 +6370,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
typeParameterNamesByTextNextNameCount: undefined,
enclosingSymbolTypes: new Map(),
mapper: undefined,
depth: 0,
couldUnfoldMore: false,
};
context.tracker = new SymbolTrackerImpl(context, tracker, moduleResolverHost);
const resultingNode = cb(context);
if (context.truncating && context.flags & NodeBuilderFlags.NoTruncation) {
context.tracker.reportTruncationError();
}
if (out) {
out.couldUnfoldMore = context.couldUnfoldMore;
}
return context.encounteredError ? undefined : resultingNode;
}
@@ -6426,14 +6396,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
function saveRestoreFlags(context: NodeBuilderContext) {
const flags = context.flags;
const internalFlags = context.internalFlags;
const depth = context.depth;
return restore;
function restore() {
context.flags = flags;
context.internalFlags = internalFlags;
context.depth = depth;
}
}
@@ -6442,25 +6410,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return context.truncating = context.approximateLength > ((context.flags & NodeBuilderFlags.NoTruncation) ? noTruncationMaximumTruncationLength : defaultMaximumTruncationLength);
}
function couldUnfoldType(type: Type, context: NodeBuilderContext): boolean {
if (context.visitedTypes?.has(type.id)) {
return false;
}
return context.depth < context.unfoldDepth || context.depth === context.unfoldDepth && !context.couldUnfoldMore;
}
// Determines if a type can be unfolded, based on how many layers of type aliases we're allowed to unfold.
function canUnfoldType(type: Type, context: NodeBuilderContext): boolean {
if (context.visitedTypes?.has(type.id)) {
return false;
}
const result = context.depth < context.unfoldDepth;
if (!result) {
context.couldUnfoldMore = true;
}
return result;
}
function typeToTypeNodeHelper(type: Type, context: NodeBuilderContext): TypeNode {
const restoreFlags = saveRestoreFlags(context);
const typeNode = typeToTypeNodeWorker(type, context);
@@ -6610,25 +6559,18 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
if (!inTypeAlias && type.aliasSymbol && (context.flags & NodeBuilderFlags.UseAliasDefinedOutsideCurrentScope || isTypeSymbolAccessible(type.aliasSymbol, context.enclosingDeclaration))) {
if (!canUnfoldType(type, context)) {
const typeArgumentNodes = mapToTypeNodes(type.aliasTypeArguments, context);
if (isReservedMemberName(type.aliasSymbol.escapedName) && !(type.aliasSymbol.flags & SymbolFlags.Class)) return factory.createTypeReferenceNode(factory.createIdentifier(""), typeArgumentNodes);
if (length(typeArgumentNodes) === 1 && type.aliasSymbol === globalArrayType.symbol) {
return factory.createArrayTypeNode(typeArgumentNodes![0]);
}
return symbolToTypeNode(type.aliasSymbol, context, SymbolFlags.Type, typeArgumentNodes);
const typeArgumentNodes = mapToTypeNodes(type.aliasTypeArguments, context);
if (isReservedMemberName(type.aliasSymbol.escapedName) && !(type.aliasSymbol.flags & SymbolFlags.Class)) return factory.createTypeReferenceNode(factory.createIdentifier(""), typeArgumentNodes);
if (length(typeArgumentNodes) === 1 && type.aliasSymbol === globalArrayType.symbol) {
return factory.createArrayTypeNode(typeArgumentNodes![0]);
}
context.depth += 1;
return symbolToTypeNode(type.aliasSymbol, context, SymbolFlags.Type, typeArgumentNodes);
}
const objectFlags = getObjectFlags(type);
if (objectFlags & ObjectFlags.Reference) {
Debug.assert(!!(type.flags & TypeFlags.Object));
if (canUnfoldType(type, context)) {
context.depth += 1;
return createAnonymousTypeNode(type as TypeReference, /*forceClassExpansion*/ true);
}
return (type as TypeReference).node ? visitAndTransformType(type as TypeReference, typeReferenceToTypeNode) : typeReferenceToTypeNode(type as TypeReference);
}
if (type.flags & TypeFlags.TypeParameter || objectFlags & ObjectFlags.ClassOrInterface) {
@@ -6657,10 +6599,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
context.approximateLength += idText(name).length;
return factory.createTypeReferenceNode(factory.createIdentifier(idText(name)), /*typeArguments*/ undefined);
}
if (objectFlags & ObjectFlags.ClassOrInterface && canUnfoldType(type, context)) {
context.depth += 1;
return createAnonymousTypeNode(type as InterfaceType, /*forceClassExpansion*/ true);
}
// Ignore constraint/default when creating a usage (as opposed to declaration) of a type parameter.
if (type.symbol) {
return symbolToTypeNode(type.symbol, context, SymbolFlags.Type);
@@ -6868,7 +6806,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return result;
}
function createAnonymousTypeNode(type: ObjectType, forceClassExpansion = false): TypeNode {
function createAnonymousTypeNode(type: ObjectType): TypeNode {
const typeId = type.id;
const symbol = type.symbol;
if (symbol) {
@@ -6902,15 +6840,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// Always use 'typeof T' for type of class, enum, and module objects
else if (
symbol.flags & SymbolFlags.Class
&& !forceClassExpansion
&& !getBaseTypeVariableOfClass(symbol)
&& !(symbol.valueDeclaration
&& isClassLike(symbol.valueDeclaration)
&& context.flags & NodeBuilderFlags.WriteClassExpressionAsTypeLiteral
&& (!isClassDeclaration(symbol.valueDeclaration)
|| isSymbolAccessible(symbol, context.enclosingDeclaration, isInstanceType, /*shouldComputeAliasesToMakeVisible*/ false).accessibility !== SymbolAccessibility.Accessible))
|| symbol.flags & (SymbolFlags.Enum | SymbolFlags.ValueModule)
|| shouldWriteTypeOfFunctionSymbol()
&& !(symbol.valueDeclaration && isClassLike(symbol.valueDeclaration) && context.flags & NodeBuilderFlags.WriteClassExpressionAsTypeLiteral && (!isClassDeclaration(symbol.valueDeclaration) || isSymbolAccessible(symbol, context.enclosingDeclaration, isInstanceType, /*shouldComputeAliasesToMakeVisible*/ false).accessibility !== SymbolAccessibility.Accessible)) ||
symbol.flags & (SymbolFlags.Enum | SymbolFlags.ValueModule) ||
shouldWriteTypeOfFunctionSymbol()
) {
return symbolToTypeNode(symbol, context, isInstanceType);
}
@@ -6963,8 +6896,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
context.symbolDepth = new Map();
}
// Don't rely on type cache if we're unfolding a type, because we need to compute `couldUnfoldMore`.
const links = context.unfoldDepth >= 0 ? undefined : context.enclosingDeclaration && getNodeLinks(context.enclosingDeclaration);
const links = context.enclosingDeclaration && getNodeLinks(context.enclosingDeclaration);
const key = `${getTypeId(type)}|${context.flags}|${context.internalFlags}`;
if (links) {
links.serializedTypes ||= new Map();
@@ -7990,7 +7922,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
function typeToTypeNodeHelperWithPossibleReusableTypeNode(type: Type, typeNode: TypeNode | undefined, context: NodeBuilderContext) {
return !couldUnfoldType(type, context) && typeNode && getTypeFromTypeNode(context, typeNode) === type && syntacticNodeBuilder.tryReuseExistingTypeNode(context, typeNode)
return typeNode && getTypeFromTypeNode(context, typeNode) === type && syntacticNodeBuilder.tryReuseExistingTypeNode(context, typeNode)
|| typeToTypeNodeHelper(type, context);
}
@@ -8729,7 +8661,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
let result;
const addUndefinedForParameter = declaration && (isParameter(declaration) || isJSDocParameterTag(declaration)) && requiresAddingImplicitUndefined(declaration, context.enclosingDeclaration);
const decl = declaration ?? symbol.valueDeclaration ?? getDeclarationWithTypeAnnotation(symbol) ?? symbol.declarations?.[0];
if (!couldUnfoldType(type, context) && decl) {
if (decl) {
if (isAccessor(decl)) {
result = syntacticNodeBuilder.serializeTypeOfAccessor(decl, symbol, context);
}
@@ -52939,7 +52871,6 @@ interface NodeBuilderContext extends SyntacticTypeNodeBuilderContext {
flags: NodeBuilderFlags;
internalFlags: InternalNodeBuilderFlags;
tracker: SymbolTrackerImpl;
readonly unfoldDepth: number;
// State
encounteredError: boolean;
@@ -52963,11 +52894,7 @@ interface NodeBuilderContext extends SyntacticTypeNodeBuilderContext {
reverseMappedStack: ReverseMappedSymbol[] | undefined;
bundled: boolean;
mapper: TypeMapper | undefined;
depth: number; // How many levels of nested type aliases we have unfolded so far
suppressReportInferenceFallback: boolean;
// Output
couldUnfoldMore: boolean; // Whether we found a type alias that we could unfold but didn't
}
class SymbolTrackerImpl implements SymbolTracker {
+1 -7
View File
@@ -5048,11 +5048,6 @@ export interface TypeCheckerHost extends ModuleSpecifierResolutionHost, SourceFi
packageBundlesTypes(packageName: string): boolean;
}
/** @internal */
export interface WriterContextOut {
couldUnfoldMore: boolean;
}
export interface TypeChecker {
getTypeOfSymbolAtLocation(symbol: Symbol, node: Node): Type;
getTypeOfSymbol(symbol: Symbol): Type;
@@ -5139,7 +5134,6 @@ export interface TypeChecker {
symbolToParameterDeclaration(symbol: Symbol, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): ParameterDeclaration | undefined;
/** Note that the resulting nodes cannot be checked. */
typeParameterToDeclaration(parameter: TypeParameter, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): TypeParameterDeclaration | undefined;
/** @internal */ typeParameterToDeclaration(parameter: TypeParameter, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker, verbosityLevel?: number): TypeParameterDeclaration | undefined; // eslint-disable-line @typescript-eslint/unified-signatures
getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[];
getSymbolAtLocation(node: Node): Symbol | undefined;
@@ -5172,7 +5166,7 @@ export interface TypeChecker {
typePredicateToString(predicate: TypePredicate, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string;
/** @internal */ writeSignature(signature: Signature, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind, writer?: EmitTextWriter): string;
/** @internal */ writeType(type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags, writer?: EmitTextWriter, verbosityLevel?: number, out?: WriterContextOut): string;
/** @internal */ writeType(type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags, writer?: EmitTextWriter): string;
/** @internal */ writeSymbol(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags, writer?: EmitTextWriter): string;
/** @internal */ writeTypePredicate(predicate: TypePredicate, enclosingDeclaration?: Node, flags?: TypeFormatFlags, writer?: EmitTextWriter): string;
+2 -3
View File
@@ -254,8 +254,8 @@ export class SessionClient implements LanguageService {
return { line, character: offset };
}
getQuickInfoAtPosition(fileName: string, position: number, verbosityLevel?: number | undefined): QuickInfo {
const args = { ...this.createFileLocationRequestArgs(fileName, position), verbosityLevel };
getQuickInfoAtPosition(fileName: string, position: number): QuickInfo {
const args = this.createFileLocationRequestArgs(fileName, position);
const request = this.processRequest<protocol.QuickInfoRequest>(protocol.CommandTypes.Quickinfo, args);
const response = this.processResponse<protocol.QuickInfoResponse>(request);
@@ -268,7 +268,6 @@ export class SessionClient implements LanguageService {
displayParts: [{ kind: "text", text: body.displayString }],
documentation: typeof body.documentation === "string" ? [{ kind: "text", text: body.documentation }] : body.documentation,
tags: this.decodeLinkDisplayParts(body.tags),
canIncreaseVerbosityLevel: body.canIncreaseVerbosityLevel,
};
}
+6 -19
View File
@@ -86,10 +86,6 @@ export interface TextSpan {
end: number;
}
export interface VerbosityLevels {
[markerName: string]: number | number[] | undefined;
}
// Name of testcase metadata including ts.CompilerOptions properties that will be used by globalOptions
// To add additional option, add property into the testOptMetadataNames, refer the property in either globalMetadataNames or fileMetadataNames
// Add cases into convertGlobalOptionsToCompilationsSettings function for the compiler to acknowledge such option from meta data
@@ -2455,28 +2451,19 @@ export class TestState {
return result;
}
public baselineQuickInfo(verbosityLevels?: VerbosityLevels): void {
const result = ts.arrayFrom(this.testData.markerPositions.entries(), ([name, marker]) => {
const verbosityLevel = toArray(verbosityLevels?.[name]);
const items = verbosityLevel.map(verbosityLevel => {
const item: ts.QuickInfo & { verbosityLevel?: number; } | undefined = this.languageService.getQuickInfoAtPosition(marker.fileName, marker.position, verbosityLevel);
if (item) item.verbosityLevel = verbosityLevel;
return {
marker: { ...marker, name },
item,
};
});
return items;
}).flat();
public baselineQuickInfo(): void {
const result = ts.arrayFrom(this.testData.markerPositions.entries(), ([name, marker]) => ({
marker: { ...marker, name },
item: this.languageService.getQuickInfoAtPosition(marker.fileName, marker.position),
}));
const annotations = this.annotateContentWithTooltips(
result,
"quickinfo",
item => item.textSpan,
({ displayParts, documentation, tags, verbosityLevel }) => [
({ displayParts, documentation, tags }) => [
...(displayParts ? displayParts.map(p => p.text).join("").split("\n") : []),
...(documentation?.length ? documentation.map(p => p.text).join("").split("\n") : []),
...(tags?.length ? tags.map(p => `@${p.name} ${p.text?.map(dp => dp.text).join("") ?? ""}`).join("\n").split("\n") : []),
...(verbosityLevel !== undefined ? [`(verbosity level: ${verbosityLevel})`] : []),
],
);
this.baseline("QuickInfo", annotations + "\n\n" + stringify(result));
+2 -2
View File
@@ -449,8 +449,8 @@ export class Verify extends VerifyNegatable {
this.state.baselineGetEmitOutput();
}
public baselineQuickInfo(verbosityLevels?: FourSlash.VerbosityLevels): void {
this.state.baselineQuickInfo(verbosityLevels);
public baselineQuickInfo(): void {
this.state.baselineQuickInfo();
}
public baselineSignatureHelp(): void {
-10
View File
@@ -2005,11 +2005,6 @@ export interface QuickInfoRequest extends FileLocationRequest {
arguments: FileLocationRequestArgs;
}
export interface QuickInfoRequestArgs extends FileLocationRequestArgs {
/** TODO */
verbosityLevel?: number;
}
/**
* Body of QuickInfoResponse.
*/
@@ -2049,11 +2044,6 @@ export interface QuickInfoResponseBody {
* JSDoc tags associated with symbol.
*/
tags: JSDocTagInfo[];
/**
* TODO
*/
canIncreaseVerbosityLevel?: boolean;
}
/**
+2 -3
View File
@@ -2392,10 +2392,10 @@ export class Session<TMessage = string> implements EventSender {
return languageService.isValidBraceCompletionAtPosition(file, position, args.openingBrace.charCodeAt(0));
}
private getQuickInfoWorker(args: protocol.QuickInfoRequestArgs, simplifiedResult: boolean): protocol.QuickInfoResponseBody | QuickInfo | undefined {
private getQuickInfoWorker(args: protocol.FileLocationRequestArgs, simplifiedResult: boolean): protocol.QuickInfoResponseBody | QuickInfo | undefined {
const { file, project } = this.getFileAndProject(args);
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file)!;
const quickInfo = project.getLanguageService().getQuickInfoAtPosition(file, this.getPosition(args, scriptInfo), args.verbosityLevel);
const quickInfo = project.getLanguageService().getQuickInfoAtPosition(file, this.getPosition(args, scriptInfo));
if (!quickInfo) {
return undefined;
}
@@ -2411,7 +2411,6 @@ export class Session<TMessage = string> implements EventSender {
displayString,
documentation: useDisplayParts ? this.mapDisplayParts(quickInfo.documentation, project) : displayPartsToString(quickInfo.documentation),
tags: this.mapJSDocTagInfo(quickInfo.tags, project, useDisplayParts),
canIncreaseVerbosityLevel: quickInfo.canIncreaseVerbosityLevel,
};
}
else {
+3 -17
View File
@@ -2274,7 +2274,7 @@ export function createLanguageService(
return Completions.getCompletionEntrySymbol(program, log, getValidSourceFile(fileName), position, { name, source }, host, preferences);
}
function getQuickInfoAtPosition(fileName: string, position: number, verbosityLevel?: number): QuickInfo | undefined {
function getQuickInfoAtPosition(fileName: string, position: number): QuickInfo | undefined {
synchronizeHostData();
const sourceFile = getValidSourceFile(fileName);
@@ -2293,26 +2293,13 @@ export function createLanguageService(
kind: ScriptElementKind.unknown,
kindModifiers: ScriptElementKindModifier.none,
textSpan: createTextSpanFromNode(nodeForQuickInfo, sourceFile),
displayParts: typeChecker.runWithCancellationToken(cancellationToken, typeChecker => typeToDisplayParts(typeChecker, type, getContainerNode(nodeForQuickInfo), /*flags*/ undefined, verbosityLevel)),
displayParts: typeChecker.runWithCancellationToken(cancellationToken, typeChecker => typeToDisplayParts(typeChecker, type, getContainerNode(nodeForQuickInfo))),
documentation: type.symbol ? type.symbol.getDocumentationComment(typeChecker) : undefined,
tags: type.symbol ? type.symbol.getJsDocTags(typeChecker) : undefined,
};
}
const { symbolKind, displayParts, documentation, tags, canIncreaseVerbosityLevel } = typeChecker.runWithCancellationToken(
cancellationToken,
typeChecker =>
SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(
typeChecker,
symbol,
sourceFile,
getContainerNode(nodeForQuickInfo),
nodeForQuickInfo,
/*semanticMeaning*/ undefined,
/*alias*/ undefined,
verbosityLevel,
),
);
const { symbolKind, displayParts, documentation, tags } = typeChecker.runWithCancellationToken(cancellationToken, typeChecker => SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker, symbol, sourceFile, getContainerNode(nodeForQuickInfo), nodeForQuickInfo));
return {
kind: symbolKind,
kindModifiers: SymbolDisplay.getSymbolModifiers(typeChecker, symbol),
@@ -2320,7 +2307,6 @@ export function createLanguageService(
displayParts,
documentation,
tags,
canIncreaseVerbosityLevel,
};
}
+6 -53
View File
@@ -108,7 +108,6 @@ import {
TypeParameter,
typeToDisplayParts,
VariableDeclaration,
WriterContextOut,
} from "./_namespaces/ts.js";
const symbolDisplayNodeBuilderFlags = NodeBuilderFlags.OmitParameterModifiers | NodeBuilderFlags.IgnoreErrors | NodeBuilderFlags.UseAliasDefinedOutsideCurrentScope;
@@ -255,20 +254,9 @@ export interface SymbolDisplayPartsDocumentationAndSymbolKind {
documentation: SymbolDisplayPart[];
symbolKind: ScriptElementKind;
tags: JSDocTagInfo[] | undefined;
canIncreaseVerbosityLevel?: boolean;
}
function getSymbolDisplayPartsDocumentationAndSymbolKindWorker(
typeChecker: TypeChecker,
symbol: Symbol,
sourceFile: SourceFile,
enclosingDeclaration: Node | undefined,
location: Node,
type: Type | undefined,
semanticMeaning: SemanticMeaning,
alias?: Symbol,
verbosityLevel?: number,
): SymbolDisplayPartsDocumentationAndSymbolKind {
function getSymbolDisplayPartsDocumentationAndSymbolKindWorker(typeChecker: TypeChecker, symbol: Symbol, sourceFile: SourceFile, enclosingDeclaration: Node | undefined, location: Node, type: Type | undefined, semanticMeaning: SemanticMeaning, alias?: Symbol): SymbolDisplayPartsDocumentationAndSymbolKind {
const displayParts: SymbolDisplayPart[] = [];
let documentation: SymbolDisplayPart[] = [];
let tags: JSDocTagInfo[] = [];
@@ -279,7 +267,6 @@ function getSymbolDisplayPartsDocumentationAndSymbolKindWorker(
let documentationFromAlias: SymbolDisplayPart[] | undefined;
let tagsFromAlias: JSDocTagInfo[] | undefined;
let hasMultipleSignatures = false;
const typeWriterOut: WriterContextOut | undefined = verbosityLevel !== undefined ? { couldUnfoldMore: false } : undefined;
if (location.kind === SyntaxKind.ThisKeyword && !isThisExpression) {
return { displayParts: [keywordPart(SyntaxKind.ThisKeyword)], documentation: [], symbolKind: ScriptElementKind.primitiveType, tags: undefined };
@@ -475,17 +462,7 @@ function getSymbolDisplayPartsDocumentationAndSymbolKindWorker(
displayParts.push(spacePart());
displayParts.push(operatorPart(SyntaxKind.EqualsToken));
displayParts.push(spacePart());
addRange(
displayParts,
typeToDisplayParts(
typeChecker,
location.parent && isConstTypeReference(location.parent) ? typeChecker.getTypeAtLocation(location.parent) : typeChecker.getDeclaredTypeOfSymbol(symbol),
enclosingDeclaration,
TypeFormatFlags.InTypeAlias,
verbosityLevel,
typeWriterOut,
),
);
addRange(displayParts, typeToDisplayParts(typeChecker, location.parent && isConstTypeReference(location.parent) ? typeChecker.getTypeAtLocation(location.parent) : typeChecker.getDeclaredTypeOfSymbol(symbol), enclosingDeclaration, TypeFormatFlags.InTypeAlias));
}
if (symbolFlags & SymbolFlags.Enum) {
prefixNextMeaning();
@@ -673,30 +650,13 @@ function getSymbolDisplayPartsDocumentationAndSymbolKindWorker(
// If the type is type parameter, format it specially
if (type.symbol && type.symbol.flags & SymbolFlags.TypeParameter && symbolKind !== ScriptElementKind.indexSignatureElement) {
const typeParameterParts = mapToDisplayParts(writer => {
const param = typeChecker.typeParameterToDeclaration(
type as TypeParameter,
enclosingDeclaration,
symbolDisplayNodeBuilderFlags,
/*internalFlags*/ undefined,
/*tracker*/ undefined,
verbosityLevel,
)!;
const param = typeChecker.typeParameterToDeclaration(type as TypeParameter, enclosingDeclaration, symbolDisplayNodeBuilderFlags)!;
getPrinter().writeNode(EmitHint.Unspecified, param, getSourceFileOfNode(getParseTreeNode(enclosingDeclaration)), writer);
});
addRange(displayParts, typeParameterParts);
}
else {
addRange(
displayParts,
typeToDisplayParts(
typeChecker,
type,
enclosingDeclaration,
/*flags*/ undefined,
verbosityLevel,
typeWriterOut,
),
);
addRange(displayParts, typeToDisplayParts(typeChecker, type, enclosingDeclaration));
}
if (isTransientSymbol(symbol) && symbol.links.target && isTransientSymbol(symbol.links.target) && symbol.links.target.links.tupleLabelDeclaration) {
const labelDecl = symbol.links.target.links.tupleLabelDeclaration;
@@ -782,13 +742,7 @@ function getSymbolDisplayPartsDocumentationAndSymbolKindWorker(
tags = tagsFromAlias;
}
return {
displayParts,
documentation,
symbolKind,
tags: tags.length === 0 ? undefined : tags,
canIncreaseVerbosityLevel: typeWriterOut?.couldUnfoldMore,
};
return { displayParts, documentation, symbolKind, tags: tags.length === 0 ? undefined : tags };
function getPrinter() {
return createPrinterWithRemoveComments();
@@ -920,9 +874,8 @@ export function getSymbolDisplayPartsDocumentationAndSymbolKind(
location: Node,
semanticMeaning: SemanticMeaning = getMeaningFromLocation(location),
alias?: Symbol,
verbosityLevel?: number,
): SymbolDisplayPartsDocumentationAndSymbolKind {
return getSymbolDisplayPartsDocumentationAndSymbolKindWorker(typeChecker, symbol, sourceFile, enclosingDeclaration, location, /*type*/ undefined, semanticMeaning, alias, verbosityLevel);
return getSymbolDisplayPartsDocumentationAndSymbolKindWorker(typeChecker, symbol, sourceFile, enclosingDeclaration, location, /*type*/ undefined, semanticMeaning, alias);
}
function isLocalVariableOrFunction(symbol: Symbol) {
-3
View File
@@ -583,8 +583,6 @@ export interface LanguageService {
* @param position A zero-based index of the character where you want the quick info
*/
getQuickInfoAtPosition(fileName: string, position: number): QuickInfo | undefined;
/** @internal */
getQuickInfoAtPosition(fileName: string, position: number, verbosityLevel: number | undefined): QuickInfo | undefined; // eslint-disable-line @typescript-eslint/unified-signatures
getNameOrDottedNameSpan(fileName: string, startPos: number, endPos: number): TextSpan | undefined;
@@ -1326,7 +1324,6 @@ export interface QuickInfo {
displayParts?: SymbolDisplayPart[];
documentation?: SymbolDisplayPart[];
tags?: JSDocTagInfo[];
canIncreaseVerbosityLevel?: boolean;
}
export type RenameInfo = RenameInfoSuccess | RenameInfoFailure;
+2 -3
View File
@@ -390,7 +390,6 @@ import {
visitEachChild,
VoidExpression,
walkUpParenthesizedExpressions,
WriterContextOut,
YieldExpression,
} from "./_namespaces/ts.js";
@@ -3056,9 +3055,9 @@ export function mapToDisplayParts(writeDisplayParts: (writer: DisplayPartsSymbol
}
/** @internal */
export function typeToDisplayParts(typechecker: TypeChecker, type: Type, enclosingDeclaration?: Node, flags: TypeFormatFlags = TypeFormatFlags.None, verbosityLevel?: number, out?: WriterContextOut): SymbolDisplayPart[] {
export function typeToDisplayParts(typechecker: TypeChecker, type: Type, enclosingDeclaration?: Node, flags: TypeFormatFlags = TypeFormatFlags.None): SymbolDisplayPart[] {
return mapToDisplayParts(writer => {
typechecker.writeType(type, enclosingDeclaration, flags | TypeFormatFlags.MultilineObjectLiterals | TypeFormatFlags.UseAliasDefinedOutsideCurrentScope, writer, verbosityLevel, out);
typechecker.writeType(type, enclosingDeclaration, flags | TypeFormatFlags.MultilineObjectLiterals | TypeFormatFlags.UseAliasDefinedOutsideCurrentScope, writer);
});
}