mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Reduce polymorphism resulting from unstable Node shapes (#51682)
* Move .symbol to Declaration * simplify some factories * Move localSymbol to Declaration * Ensure JSDocContainer types are properly initialized * Move contextualType from Node to NodeLinks * Move 'locals' and 'nextContainer' out of Node * Move 'flowNode' out of 'Node' * Pre-define endFlowNode/returnFlowNode * Pre-define some SourceFile properties and a more stable cloneNode * Don't add excess properties to type nodes in typeToTypeNode * Refactor wrapSymbolTrackerToReportForContext to improve perf
This commit is contained in:
@@ -6,6 +6,7 @@ import {
|
||||
Block,
|
||||
CallExpression,
|
||||
canBeConvertedToAsync,
|
||||
canHaveSymbol,
|
||||
CodeFixContext,
|
||||
concatenate,
|
||||
createMultiMap,
|
||||
@@ -867,7 +868,7 @@ function getArgBindingName(funcNode: Expression, transformer: Transformer): Synt
|
||||
}
|
||||
|
||||
function getSymbol(node: Node): Symbol | undefined {
|
||||
return node.symbol ? node.symbol : transformer.checker.getSymbolAtLocation(node);
|
||||
return tryCast(node, canHaveSymbol)?.symbol ?? transformer.checker.getSymbolAtLocation(node);
|
||||
}
|
||||
|
||||
function getOriginalNode(node: Node): Node {
|
||||
|
||||
@@ -46,10 +46,10 @@ function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, po
|
||||
const token = getTokenAtPosition(sourceFile, pos);
|
||||
if (!isThis(token)) return undefined;
|
||||
|
||||
const fn = getThisContainer(token, /*includeArrowFunctions*/ false);
|
||||
const fn = getThisContainer(token, /*includeArrowFunctions*/ false, /*includeClassComputedPropertyName*/ false);
|
||||
if (!isFunctionDeclaration(fn) && !isFunctionExpression(fn)) return undefined;
|
||||
|
||||
if (!isSourceFile(getThisContainer(fn, /*includeArrowFunctions*/ false))) { // 'this' is defined outside, convert to arrow function
|
||||
if (!isSourceFile(getThisContainer(fn, /*includeArrowFunctions*/ false, /*includeClassComputedPropertyName*/ false))) { // 'this' is defined outside, convert to arrow function
|
||||
const fnKeyword = Debug.checkDefined(findChildOfKind(fn, SyntaxKind.FunctionKeyword, sourceFile));
|
||||
const { name } = fn;
|
||||
const body = Debug.checkDefined(fn.body); // Should be defined because the function contained a 'this' expression
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import {
|
||||
canHaveExportModifier,
|
||||
canHaveLocals,
|
||||
Declaration,
|
||||
Diagnostics,
|
||||
ExportDeclaration,
|
||||
@@ -125,7 +126,7 @@ function getInfo(sourceFile: SourceFile, pos: number, program: Program): Info |
|
||||
if (moduleSourceFile === undefined || isSourceFileFromLibrary(program, moduleSourceFile)) return undefined;
|
||||
|
||||
const moduleSymbol = moduleSourceFile.symbol;
|
||||
const locals = moduleSymbol.valueDeclaration?.locals;
|
||||
const locals = tryCast(moduleSymbol.valueDeclaration, canHaveLocals)?.locals;
|
||||
if (locals === undefined) return undefined;
|
||||
|
||||
const localSymbol = locals.get(token.escapedText);
|
||||
|
||||
@@ -294,6 +294,7 @@ import {
|
||||
PropertyAccessExpression,
|
||||
PropertyDeclaration,
|
||||
PropertyName,
|
||||
PropertySignature,
|
||||
PseudoBigInt,
|
||||
pseudoBigIntToString,
|
||||
QualifiedName,
|
||||
@@ -334,6 +335,7 @@ import {
|
||||
textPart,
|
||||
TextRange,
|
||||
TextSpan,
|
||||
ThisContainer,
|
||||
timestamp,
|
||||
Token,
|
||||
TokenSyntaxKind,
|
||||
@@ -3308,7 +3310,7 @@ function getCompletionData(
|
||||
|
||||
// Need to insert 'this.' before properties of `this` type, so only do that if `includeInsertTextCompletions`
|
||||
if (preferences.includeCompletionsWithInsertText && scopeNode.kind !== SyntaxKind.SourceFile) {
|
||||
const thisType = typeChecker.tryGetThisTypeAt(scopeNode, /*includeGlobalThis*/ false, isClassLike(scopeNode.parent) ? scopeNode : undefined);
|
||||
const thisType = typeChecker.tryGetThisTypeAt(scopeNode, /*includeGlobalThis*/ false, isClassLike(scopeNode.parent) ? scopeNode as ThisContainer : undefined);
|
||||
if (thisType && !isProbablyGlobalType(thisType, sourceFile, typeChecker)) {
|
||||
for (const symbol of getPropertiesForCompletion(thisType, typeChecker)) {
|
||||
symbolToOriginInfoMap[symbols.length] = { kind: SymbolOriginInfoKind.ThisType };
|
||||
@@ -4877,7 +4879,7 @@ function getConstraintOfTypeArgumentProperty(node: Node, checker: TypeChecker):
|
||||
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.PropertySignature:
|
||||
return checker.getTypeOfPropertyOfContextualType(t, node.symbol.escapedName);
|
||||
return checker.getTypeOfPropertyOfContextualType(t, (node as PropertySignature).symbol.escapedName);
|
||||
case SyntaxKind.IntersectionType:
|
||||
case SyntaxKind.TypeLiteral:
|
||||
case SyntaxKind.UnionType:
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
Block,
|
||||
BreakOrContinueStatement,
|
||||
CancellationToken,
|
||||
canHaveSymbol,
|
||||
CaseClause,
|
||||
cast,
|
||||
concatenate,
|
||||
@@ -78,6 +79,7 @@ import {
|
||||
ThrowStatement,
|
||||
toArray,
|
||||
toPath,
|
||||
tryCast,
|
||||
TryStatement,
|
||||
} from "./_namespaces/ts";
|
||||
|
||||
@@ -184,7 +186,7 @@ export namespace DocumentHighlights {
|
||||
}
|
||||
|
||||
function getFromAllDeclarations<T extends Node>(nodeTest: (node: Node) => node is T, keywords: readonly SyntaxKind[]): HighlightSpan[] | undefined {
|
||||
return useParent(node.parent, nodeTest, decl => mapDefined(decl.symbol.declarations, d =>
|
||||
return useParent(node.parent, nodeTest, decl => mapDefined(tryCast(decl, canHaveSymbol)?.symbol.declarations, d =>
|
||||
nodeTest(d) ? find(d.getChildren(sourceFile), c => contains(keywords, c.kind)) : undefined));
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
Block,
|
||||
CallExpression,
|
||||
CancellationToken,
|
||||
canHaveSymbol,
|
||||
cast,
|
||||
CheckFlags,
|
||||
ClassLikeDeclaration,
|
||||
@@ -190,6 +191,7 @@ import {
|
||||
NodeFlags,
|
||||
nodeSeenTracker,
|
||||
NumericLiteral,
|
||||
ObjectLiteralExpression,
|
||||
ParameterDeclaration,
|
||||
ParenthesizedExpression,
|
||||
Path,
|
||||
@@ -218,6 +220,7 @@ import {
|
||||
StringLiteral,
|
||||
StringLiteralLike,
|
||||
stripQuotes,
|
||||
SuperContainer,
|
||||
Symbol,
|
||||
SymbolDisplay,
|
||||
SymbolDisplayPart,
|
||||
@@ -234,6 +237,7 @@ import {
|
||||
tryGetClassExtendingExpressionWithTypeArguments,
|
||||
tryGetImportFromModuleSpecifier,
|
||||
TypeChecker,
|
||||
TypeLiteralNode,
|
||||
VariableDeclaration,
|
||||
} from "./_namespaces/ts";
|
||||
import {
|
||||
@@ -1882,7 +1886,7 @@ export namespace Core {
|
||||
|
||||
// Use the parent symbol if the location is commonjs require syntax on javascript files only.
|
||||
if (isInJSFile(referenceLocation)
|
||||
&& referenceLocation.parent.kind === SyntaxKind.BindingElement
|
||||
&& isBindingElement(referenceLocation.parent)
|
||||
&& isVariableDeclarationInitializedToBareOrAccessedRequire(referenceLocation.parent.parent.parent)) {
|
||||
referenceSymbol = referenceLocation.parent.symbol;
|
||||
// The parent will not have a symbol if it's an ObjectBindingPattern (when destructuring is used). In
|
||||
@@ -2253,7 +2257,7 @@ export namespace Core {
|
||||
}
|
||||
|
||||
function getReferencesForSuperKeyword(superKeyword: Node): SymbolAndEntries[] | undefined {
|
||||
let searchSpaceNode = getSuperContainer(superKeyword, /*stopOnFunctions*/ false);
|
||||
let searchSpaceNode: SuperContainer | ClassLikeDeclaration | TypeLiteralNode | InterfaceDeclaration | ObjectLiteralExpression | undefined = getSuperContainer(superKeyword, /*stopOnFunctions*/ false);
|
||||
if (!searchSpaceNode) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -2286,7 +2290,7 @@ export namespace Core {
|
||||
// If we have a 'super' container, we must have an enclosing class.
|
||||
// Now make sure the owning class is the same as the search-space
|
||||
// and has the same static qualifier as the original 'super's owner.
|
||||
return container && isStatic(container) === !!staticFlag && container.parent.symbol === searchSpaceNode.symbol ? nodeEntry(node) : undefined;
|
||||
return container && isStatic(container) === !!staticFlag && container.parent.symbol === searchSpaceNode!.symbol ? nodeEntry(node) : undefined;
|
||||
});
|
||||
|
||||
return [{ definition: { type: DefinitionKind.Symbol, symbol: searchSpaceNode.symbol }, references }];
|
||||
@@ -2297,7 +2301,7 @@ export namespace Core {
|
||||
}
|
||||
|
||||
function getReferencesForThisKeyword(thisOrSuperKeyword: Node, sourceFiles: readonly SourceFile[], cancellationToken: CancellationToken): SymbolAndEntries[] | undefined {
|
||||
let searchSpaceNode = getThisContainer(thisOrSuperKeyword, /* includeArrowFunctions */ false);
|
||||
let searchSpaceNode: Node = getThisContainer(thisOrSuperKeyword, /* includeArrowFunctions */ false, /*includeClassComputedPropertyName*/ false);
|
||||
|
||||
// Whether 'this' occurs in a static context within a class.
|
||||
let staticFlag = ModifierFlags.Static;
|
||||
@@ -2339,11 +2343,12 @@ export namespace Core {
|
||||
if (!isThis(node)) {
|
||||
return false;
|
||||
}
|
||||
const container = getThisContainer(node, /* includeArrowFunctions */ false);
|
||||
const container = getThisContainer(node, /* includeArrowFunctions */ false, /*includeClassComputedPropertyName*/ false);
|
||||
if (!canHaveSymbol(container)) return false;
|
||||
switch (searchSpaceNode.kind) {
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
return searchSpaceNode.symbol === container.symbol;
|
||||
return (searchSpaceNode as FunctionExpression | FunctionDeclaration).symbol === container.symbol;
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.MethodSignature:
|
||||
return isObjectLiteralMethod(searchSpaceNode) && searchSpaceNode.symbol === container.symbol;
|
||||
@@ -2352,9 +2357,9 @@ export namespace Core {
|
||||
case SyntaxKind.ObjectLiteralExpression:
|
||||
// Make sure the container belongs to the same class/object literals
|
||||
// and has the appropriate static modifier from the original container.
|
||||
return container.parent && searchSpaceNode.symbol === container.parent.symbol && isStatic(container) === !!staticFlag;
|
||||
return container.parent && canHaveSymbol(container.parent) && (searchSpaceNode as ClassLikeDeclaration | ObjectLiteralExpression).symbol === container.parent.symbol && isStatic(container) === !!staticFlag;
|
||||
case SyntaxKind.SourceFile:
|
||||
return container.kind === SyntaxKind.SourceFile && !isExternalModule(container as SourceFile) && !isParameterName(node);
|
||||
return container.kind === SyntaxKind.SourceFile && !isExternalModule(container) && !isParameterName(node);
|
||||
}
|
||||
});
|
||||
}).map(n => nodeEntry(n));
|
||||
|
||||
@@ -3,7 +3,7 @@ import {
|
||||
AssignmentExpression,
|
||||
AssignmentOperatorToken,
|
||||
CallLikeExpression,
|
||||
concatenate,
|
||||
canHaveSymbol, concatenate,
|
||||
createTextSpan,
|
||||
createTextSpanFromBounds,
|
||||
createTextSpanFromNode,
|
||||
@@ -245,7 +245,7 @@ function symbolMatchesSignature(s: Symbol, calledDeclaration: SignatureDeclarati
|
||||
return s === calledDeclaration.symbol
|
||||
|| s === calledDeclaration.symbol.parent
|
||||
|| isAssignmentExpression(calledDeclaration.parent)
|
||||
|| (!isCallLikeExpression(calledDeclaration.parent) && s === calledDeclaration.parent.symbol);
|
||||
|| (!isCallLikeExpression(calledDeclaration.parent) && s === tryCast(calledDeclaration.parent, canHaveSymbol)?.symbol);
|
||||
}
|
||||
|
||||
// If the current location we want to find its definition is in an object literal, try to get the contextual type for the
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
CallExpression,
|
||||
CancellationToken,
|
||||
canHaveModifiers,
|
||||
canHaveSymbol,
|
||||
cast,
|
||||
Debug,
|
||||
ExportAssignment,
|
||||
@@ -73,6 +74,7 @@ import {
|
||||
SymbolFlags,
|
||||
symbolName,
|
||||
SyntaxKind,
|
||||
tryCast,
|
||||
TypeChecker,
|
||||
ValidImportTypeNode,
|
||||
VariableDeclaration,
|
||||
@@ -683,10 +685,10 @@ function getExportEqualsLocalSymbol(importedSymbol: Symbol, checker: TypeChecker
|
||||
|
||||
const decl = Debug.checkDefined(importedSymbol.valueDeclaration);
|
||||
if (isExportAssignment(decl)) { // `export = class {}`
|
||||
return decl.expression.symbol;
|
||||
return tryCast(decl.expression, canHaveSymbol)?.symbol;
|
||||
}
|
||||
else if (isBinaryExpression(decl)) { // `module.exports = class {}`
|
||||
return decl.right.symbol;
|
||||
return tryCast(decl.right, canHaveSymbol)?.symbol;
|
||||
}
|
||||
else if (isSourceFile(decl)) { // json module
|
||||
return decl.symbol;
|
||||
|
||||
@@ -387,7 +387,7 @@ export function provideInlayHints(context: InlayHintsContext): InlayHint[] {
|
||||
const printer = createPrinter(options);
|
||||
|
||||
return usingSingleLineStringWriter(writer => {
|
||||
const typeNode = checker.typeToTypeNode(type, /*enclosingDeclaration*/ undefined, flags, writer);
|
||||
const typeNode = checker.typeToTypeNode(type, /*enclosingDeclaration*/ undefined, flags);
|
||||
Debug.assertIsDefined(typeNode, "should always get typenode");
|
||||
printer.writeNode(EmitHint.Unspecified, typeNode, /*sourceFile*/ file, writer);
|
||||
});
|
||||
|
||||
@@ -33,6 +33,7 @@ import {
|
||||
isStringLiteral,
|
||||
makeImport,
|
||||
ModifierFlags,
|
||||
ModuleBlock,
|
||||
NamespaceDeclaration,
|
||||
Node,
|
||||
NodeFlags,
|
||||
@@ -122,7 +123,7 @@ function getInfo(context: RefactorContext, considerPartialSpans = true): ExportI
|
||||
}
|
||||
|
||||
const checker = program.getTypeChecker();
|
||||
const exportingModuleSymbol = getExportingModuleSymbol(exportNode, checker);
|
||||
const exportingModuleSymbol = getExportingModuleSymbol(exportNode.parent, checker);
|
||||
const flags = getSyntacticModifierFlags(exportNode) || ((isExportAssignment(exportNode) && !exportNode.isExportEquals) ? ModifierFlags.ExportDefault : ModifierFlags.None);
|
||||
|
||||
const wasDefault = !!(flags & ModifierFlags.Default);
|
||||
@@ -319,8 +320,7 @@ function makeExportSpecifier(propertyName: string, name: string): ExportSpecifie
|
||||
return factory.createExportSpecifier(/*isTypeOnly*/ false, propertyName === name ? undefined : factory.createIdentifier(propertyName), factory.createIdentifier(name));
|
||||
}
|
||||
|
||||
function getExportingModuleSymbol(node: Node, checker: TypeChecker) {
|
||||
const parent = node.parent;
|
||||
function getExportingModuleSymbol(parent: SourceFile | ModuleBlock, checker: TypeChecker) {
|
||||
if (isSourceFile(parent)) {
|
||||
return parent.symbol;
|
||||
}
|
||||
|
||||
@@ -633,7 +633,7 @@ export function getRangeToExtract(sourceFile: SourceFile, span: TextSpan, invoke
|
||||
visit(nodeToCheck);
|
||||
|
||||
if (rangeFacts & RangeFacts.UsesThis) {
|
||||
const container = getThisContainer(nodeToCheck, /** includeArrowFunctions */ false);
|
||||
const container = getThisContainer(nodeToCheck, /** includeArrowFunctions */ false, /*includeClassComputedPropertyName*/ false);
|
||||
if (
|
||||
container.kind === SyntaxKind.FunctionDeclaration ||
|
||||
(container.kind === SyntaxKind.MethodDeclaration && container.parent.kind === SyntaxKind.ObjectLiteralExpression) ||
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
CallExpression,
|
||||
canHaveDecorators,
|
||||
canHaveModifiers,
|
||||
cast,
|
||||
canHaveSymbol, cast,
|
||||
ClassDeclaration,
|
||||
codefix,
|
||||
combinePaths,
|
||||
@@ -505,7 +505,7 @@ function addExports(sourceFile: SourceFile, toMove: readonly Statement[], needEx
|
||||
return flatMap(toMove, statement => {
|
||||
if (isTopLevelDeclarationStatement(statement) &&
|
||||
!isExported(sourceFile, statement, useEs6Exports) &&
|
||||
forEachTopLevelDeclaration(statement, d => needExport.has(Debug.checkDefined(d.symbol)))) {
|
||||
forEachTopLevelDeclaration(statement, d => needExport.has(Debug.checkDefined(tryCast(d, canHaveSymbol)?.symbol)))) {
|
||||
const exports = addExport(statement, useEs6Exports);
|
||||
if (exports) return exports;
|
||||
}
|
||||
|
||||
+18
-15
@@ -594,7 +594,7 @@ class TokenOrIdentifierObject implements Node {
|
||||
}
|
||||
|
||||
public getChildren(): Node[] {
|
||||
return this.kind === SyntaxKind.EndOfFileToken ? (this as EndOfFileToken).jsDoc || emptyArray : emptyArray;
|
||||
return this.kind === SyntaxKind.EndOfFileToken ? (this as Node as EndOfFileToken).jsDoc || emptyArray : emptyArray;
|
||||
}
|
||||
|
||||
public getFirstToken(): Node | undefined {
|
||||
@@ -733,13 +733,15 @@ class IdentifierObject extends TokenOrIdentifierObject implements Identifier {
|
||||
public kind: SyntaxKind.Identifier = SyntaxKind.Identifier;
|
||||
public escapedText!: __String;
|
||||
public autoGenerateFlags!: GeneratedIdentifierFlags;
|
||||
_primaryExpressionBrand: any;
|
||||
_memberExpressionBrand: any;
|
||||
_leftHandSideExpressionBrand: any;
|
||||
_updateExpressionBrand: any;
|
||||
_unaryExpressionBrand: any;
|
||||
_expressionBrand: any;
|
||||
_declarationBrand: any;
|
||||
declare _primaryExpressionBrand: any;
|
||||
declare _memberExpressionBrand: any;
|
||||
declare _leftHandSideExpressionBrand: any;
|
||||
declare _updateExpressionBrand: any;
|
||||
declare _unaryExpressionBrand: any;
|
||||
declare _expressionBrand: any;
|
||||
declare _declarationBrand: any;
|
||||
declare _jsdocContainerBrand: any;
|
||||
declare _flowContainerBrand: any;
|
||||
/** @internal */typeArguments!: NodeArray<TypeNode>;
|
||||
constructor(_kind: SyntaxKind.Identifier, pos: number, end: number) {
|
||||
super(pos, end);
|
||||
@@ -754,12 +756,12 @@ class PrivateIdentifierObject extends TokenOrIdentifierObject implements Private
|
||||
public kind: SyntaxKind.PrivateIdentifier = SyntaxKind.PrivateIdentifier;
|
||||
public escapedText!: __String;
|
||||
// public symbol!: Symbol;
|
||||
_primaryExpressionBrand: any;
|
||||
_memberExpressionBrand: any;
|
||||
_leftHandSideExpressionBrand: any;
|
||||
_updateExpressionBrand: any;
|
||||
_unaryExpressionBrand: any;
|
||||
_expressionBrand: any;
|
||||
declare _primaryExpressionBrand: any;
|
||||
declare _memberExpressionBrand: any;
|
||||
declare _leftHandSideExpressionBrand: any;
|
||||
declare _updateExpressionBrand: any;
|
||||
declare _unaryExpressionBrand: any;
|
||||
declare _expressionBrand: any;
|
||||
constructor(_kind: SyntaxKind.PrivateIdentifier, pos: number, end: number) {
|
||||
super(pos, end);
|
||||
}
|
||||
@@ -992,7 +994,8 @@ function findBaseOfDeclaration<T>(checker: TypeChecker, declaration: Declaration
|
||||
|
||||
class SourceFileObject extends NodeObject implements SourceFile {
|
||||
public kind: SyntaxKind.SourceFile = SyntaxKind.SourceFile;
|
||||
public _declarationBrand: any;
|
||||
declare _declarationBrand: any;
|
||||
declare _localsContainerBrand: any;
|
||||
public fileName!: string;
|
||||
public path!: Path;
|
||||
public resolvedPath!: Path;
|
||||
|
||||
@@ -3,6 +3,7 @@ import {
|
||||
BinaryExpression,
|
||||
CallLikeExpression,
|
||||
CancellationToken,
|
||||
canHaveSymbol,
|
||||
CheckFlags,
|
||||
contains,
|
||||
countWhere,
|
||||
@@ -77,6 +78,7 @@ import {
|
||||
TemplateExpression,
|
||||
TextSpan,
|
||||
TransientSymbol,
|
||||
tryCast,
|
||||
Type,
|
||||
TypeChecker,
|
||||
TypeParameter,
|
||||
@@ -431,7 +433,7 @@ function getContextualSignatureLocationInfo(startingToken: Node, sourceFile: Sou
|
||||
// The type of a function type node has a symbol at that node, but it's better to use the symbol for a parameter or type alias.
|
||||
function chooseBetterSymbol(s: Symbol): Symbol {
|
||||
return s.name === InternalSymbolName.Type
|
||||
? firstDefined(s.declarations, d => isFunctionTypeNode(d) ? d.parent.symbol : undefined) || s
|
||||
? firstDefined(s.declarations, d => isFunctionTypeNode(d) ? tryCast(d.parent, canHaveSymbol)?.symbol : undefined) || s
|
||||
: s;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,8 @@ import {
|
||||
isBlock,
|
||||
isCallExpression,
|
||||
isExportAssignment,
|
||||
isFunctionDeclaration,
|
||||
isFunctionExpression,
|
||||
isFunctionLike,
|
||||
isIdentifier,
|
||||
isPropertyAccessExpression,
|
||||
@@ -276,7 +278,7 @@ function getKeyFromNode(exp: FunctionLikeDeclaration) {
|
||||
}
|
||||
|
||||
function canBeConvertedToClass(node: Node, checker: TypeChecker): boolean {
|
||||
if (node.kind === SyntaxKind.FunctionExpression) {
|
||||
if (isFunctionExpression(node)) {
|
||||
if (isVariableDeclaration(node.parent) && node.symbol.members?.size) {
|
||||
return true;
|
||||
}
|
||||
@@ -285,7 +287,7 @@ function canBeConvertedToClass(node: Node, checker: TypeChecker): boolean {
|
||||
return !!(symbol && (symbol.exports?.size || symbol.members?.size));
|
||||
}
|
||||
|
||||
if (node.kind === SyntaxKind.FunctionDeclaration) {
|
||||
if (isFunctionDeclaration(node)) {
|
||||
return !!node.symbol.members?.size;
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,6 @@ import {
|
||||
isFunctionBlock,
|
||||
isFunctionExpression,
|
||||
isFunctionLike,
|
||||
isFunctionLikeKind,
|
||||
isIdentifier,
|
||||
isInExpressionContext,
|
||||
isJsxOpeningLikeElement,
|
||||
@@ -59,6 +58,7 @@ import {
|
||||
isObjectBindingPattern,
|
||||
isTaggedTemplateExpression,
|
||||
isThisInTypeQuery,
|
||||
isTypeAliasDeclaration,
|
||||
isVarConst,
|
||||
JSDocTagInfo,
|
||||
JsxOpeningLikeElement,
|
||||
@@ -493,19 +493,19 @@ export function getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker: Typ
|
||||
const declaration = decl.parent;
|
||||
|
||||
if (declaration) {
|
||||
if (isFunctionLikeKind(declaration.kind)) {
|
||||
if (isFunctionLike(declaration)) {
|
||||
addInPrefix();
|
||||
const signature = typeChecker.getSignatureFromDeclaration(declaration as SignatureDeclaration)!; // TODO: GH#18217
|
||||
const signature = typeChecker.getSignatureFromDeclaration(declaration)!; // TODO: GH#18217
|
||||
if (declaration.kind === SyntaxKind.ConstructSignature) {
|
||||
displayParts.push(keywordPart(SyntaxKind.NewKeyword));
|
||||
displayParts.push(spacePart());
|
||||
}
|
||||
else if (declaration.kind !== SyntaxKind.CallSignature && (declaration as SignatureDeclaration).name) {
|
||||
else if (declaration.kind !== SyntaxKind.CallSignature && declaration.name) {
|
||||
addFullSymbolName(declaration.symbol);
|
||||
}
|
||||
addRange(displayParts, signatureToDisplayParts(typeChecker, signature, sourceFile, TypeFormatFlags.WriteTypeArgumentsOfSignature));
|
||||
}
|
||||
else if (declaration.kind === SyntaxKind.TypeAliasDeclaration) {
|
||||
else if (isTypeAliasDeclaration(declaration)) {
|
||||
// Type alias type parameter
|
||||
// For example
|
||||
// type list<T> = T[]; // Both T will go through same code path
|
||||
|
||||
@@ -271,7 +271,6 @@ import {
|
||||
nodeIsMissing,
|
||||
nodeIsPresent,
|
||||
nodeIsSynthesized,
|
||||
noop,
|
||||
normalizePath,
|
||||
NoSubstitutionTemplateLiteral,
|
||||
notImplemented,
|
||||
@@ -2721,10 +2720,6 @@ function getDisplayPartWriter(): DisplayPartsSymbolWriter {
|
||||
increaseIndent: () => { indent++; },
|
||||
decreaseIndent: () => { indent--; },
|
||||
clear: resetWriter,
|
||||
trackSymbol: () => false,
|
||||
reportInaccessibleThisError: noop,
|
||||
reportInaccessibleUniqueSymbolError: noop,
|
||||
reportPrivateInBaseOfClassExpression: noop,
|
||||
};
|
||||
|
||||
function writeIndent() {
|
||||
|
||||
Reference in New Issue
Block a user