Skip to content

Commit d9c9c9d

Browse files
authored
Harden node builder APIs to no longer return undefined for a node when NodeBuilderFlags.IgnoreErrors is provided (#38273)
1 parent aa37b28 commit d9c9c9d

10 files changed

+63
-38
lines changed

src/compiler/checker.ts

+7-3
Original file line numberDiff line numberDiff line change
@@ -4212,8 +4212,12 @@ namespace ts {
42124212
context.flags &= ~NodeBuilderFlags.InTypeAlias;
42134213

42144214
if (!type) {
4215-
context.encounteredError = true;
4216-
return undefined!; // TODO: GH#18217
4215+
if (!(context.flags & NodeBuilderFlags.AllowEmptyUnionOrIntersection)) {
4216+
context.encounteredError = true;
4217+
return undefined!; // TODO: GH#18217
4218+
}
4219+
context.approximateLength += 3;
4220+
return createKeywordTypeNode(SyntaxKind.AnyKeyword);
42174221
}
42184222

42194223
if (!(context.flags & NodeBuilderFlags.NoTypeReduction)) {
@@ -5933,7 +5937,7 @@ namespace ts {
59335937
function serializeSymbolWorker(symbol: Symbol, isPrivate: boolean, propertyAsAlias: boolean) {
59345938
const symbolName = unescapeLeadingUnderscores(symbol.escapedName);
59355939
const isDefault = symbol.escapedName === InternalSymbolName.Default;
5936-
if (isStringANonContextualKeyword(symbolName) && !isDefault) {
5940+
if (!(context.flags & NodeBuilderFlags.AllowAnonymousIdentifier) && isStringANonContextualKeyword(symbolName) && !isDefault) {
59375941
// Oh no. We cannot use this symbol's name as it's name... It's likely some jsdoc had an invalid name like `export` or `default` :(
59385942
context.encounteredError = true;
59395943
// TODO: Issue error via symbol tracker?

src/compiler/types.ts

+11-11
Original file line numberDiff line numberDiff line change
@@ -3437,24 +3437,24 @@ namespace ts {
34373437

34383438
// TODO: GH#18217 `xToDeclaration` calls are frequently asserted as defined.
34393439
/** Note that the resulting nodes cannot be checked. */
3440-
typeToTypeNode(type: Type, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): TypeNode | undefined;
3441-
/* @internal */ typeToTypeNode(type: Type, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker): TypeNode | undefined; // eslint-disable-line @typescript-eslint/unified-signatures
3440+
typeToTypeNode(type: Type, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): TypeNode | undefined;
3441+
/* @internal */ typeToTypeNode(type: Type, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined, tracker?: SymbolTracker): TypeNode | undefined; // eslint-disable-line @typescript-eslint/unified-signatures
34423442
/** Note that the resulting nodes cannot be checked. */
3443-
signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): SignatureDeclaration & {typeArguments?: NodeArray<TypeNode>} | undefined;
3444-
/* @internal */ signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker): SignatureDeclaration & {typeArguments?: NodeArray<TypeNode>} | undefined; // eslint-disable-line @typescript-eslint/unified-signatures
3443+
signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): SignatureDeclaration & {typeArguments?: NodeArray<TypeNode>} | undefined;
3444+
/* @internal */ signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined, tracker?: SymbolTracker): SignatureDeclaration & {typeArguments?: NodeArray<TypeNode>} | undefined; // eslint-disable-line @typescript-eslint/unified-signatures
34453445
/** Note that the resulting nodes cannot be checked. */
3446-
indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): IndexSignatureDeclaration | undefined;
3447-
/* @internal */ indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker): IndexSignatureDeclaration | undefined; // eslint-disable-line @typescript-eslint/unified-signatures
3446+
indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): IndexSignatureDeclaration | undefined;
3447+
/* @internal */ indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined, tracker?: SymbolTracker): IndexSignatureDeclaration | undefined; // eslint-disable-line @typescript-eslint/unified-signatures
34483448
/** Note that the resulting nodes cannot be checked. */
3449-
symbolToEntityName(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): EntityName | undefined;
3449+
symbolToEntityName(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): EntityName | undefined;
34503450
/** Note that the resulting nodes cannot be checked. */
3451-
symbolToExpression(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): Expression | undefined;
3451+
symbolToExpression(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): Expression | undefined;
34523452
/** Note that the resulting nodes cannot be checked. */
3453-
symbolToTypeParameterDeclarations(symbol: Symbol, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): NodeArray<TypeParameterDeclaration> | undefined;
3453+
symbolToTypeParameterDeclarations(symbol: Symbol, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): NodeArray<TypeParameterDeclaration> | undefined;
34543454
/** Note that the resulting nodes cannot be checked. */
3455-
symbolToParameterDeclaration(symbol: Symbol, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): ParameterDeclaration | undefined;
3455+
symbolToParameterDeclaration(symbol: Symbol, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): ParameterDeclaration | undefined;
34563456
/** Note that the resulting nodes cannot be checked. */
3457-
typeParameterToDeclaration(parameter: TypeParameter, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): TypeParameterDeclaration | undefined;
3457+
typeParameterToDeclaration(parameter: TypeParameter, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): TypeParameterDeclaration | undefined;
34583458

34593459
getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[];
34603460
getSymbolAtLocation(node: Node): Symbol | undefined;

src/services/codefixes/convertToAsyncFunction.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ namespace ts.codefix {
282282
varDeclIdentifier = getSynthesizedDeepClone(possibleNameForVarDecl.identifier);
283283
const typeArray: Type[] = possibleNameForVarDecl.types;
284284
const unionType = transformer.checker.getUnionType(typeArray, UnionReduction.Subtype);
285-
const unionTypeNode = transformer.isInJSFile ? undefined : transformer.checker.typeToTypeNode(unionType);
285+
const unionTypeNode = transformer.isInJSFile ? undefined : transformer.checker.typeToTypeNode(unionType, /*enclosingDeclaration*/ undefined, /*flags*/ undefined);
286286
const varDecl = [createVariableDeclaration(varDeclIdentifier, unionTypeNode)];
287287
varDeclList = createVariableStatement(/*modifiers*/ undefined, createVariableDeclarationList(varDecl, NodeFlags.Let));
288288
}

src/services/codefixes/fixAddMissingMember.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -230,11 +230,11 @@ namespace ts.codefix {
230230
const binaryExpression = token.parent.parent as BinaryExpression;
231231
const otherExpression = token.parent === binaryExpression.left ? binaryExpression.right : binaryExpression.left;
232232
const widenedType = checker.getWidenedType(checker.getBaseTypeOfLiteralType(checker.getTypeAtLocation(otherExpression)));
233-
typeNode = checker.typeToTypeNode(widenedType, classDeclaration);
233+
typeNode = checker.typeToTypeNode(widenedType, classDeclaration, /*flags*/ undefined);
234234
}
235235
else {
236236
const contextualType = checker.getContextualType(token.parent as Expression);
237-
typeNode = contextualType ? checker.typeToTypeNode(contextualType) : undefined;
237+
typeNode = contextualType ? checker.typeToTypeNode(contextualType, /*enclosingDeclaration*/ undefined, /*flags*/ undefined) : undefined;
238238
}
239239
return typeNode || createKeywordTypeNode(SyntaxKind.AnyKeyword);
240240
}

src/services/codefixes/fixJSDocTypes.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ namespace ts.codefix {
4040
});
4141

4242
function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, oldTypeNode: TypeNode, newType: Type, checker: TypeChecker): void {
43-
changes.replaceNode(sourceFile, oldTypeNode, checker.typeToTypeNode(newType, /*enclosingDeclaration*/ oldTypeNode)!); // TODO: GH#18217
43+
changes.replaceNode(sourceFile, oldTypeNode, checker.typeToTypeNode(newType, /*enclosingDeclaration*/ oldTypeNode, /*flags*/ undefined)!); // TODO: GH#18217
4444
}
4545

4646
function getInfo(sourceFile: SourceFile, pos: number, checker: TypeChecker): { readonly typeNode: TypeNode, readonly type: Type } | undefined {

src/services/signatureHelp.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -580,7 +580,7 @@ namespace ts.SignatureHelp {
580580
const printer = createPrinter({ removeComments: true });
581581
const typeParameterParts = mapToDisplayParts(writer => {
582582
if (candidateSignature.typeParameters && candidateSignature.typeParameters.length) {
583-
const args = createNodeArray(candidateSignature.typeParameters.map(p => checker.typeParameterToDeclaration(p, enclosingDeclaration)!));
583+
const args = createNodeArray(candidateSignature.typeParameters.map(p => checker.typeParameterToDeclaration(p, enclosingDeclaration, signatureHelpNodeBuilderFlags)!));
584584
printer.writeList(ListFormat.TypeParameters, args, sourceFile, writer);
585585
}
586586
});
@@ -599,7 +599,7 @@ namespace ts.SignatureHelp {
599599

600600
function createSignatureHelpParameterForTypeParameter(typeParameter: TypeParameter, checker: TypeChecker, enclosingDeclaration: Node, sourceFile: SourceFile, printer: Printer): SignatureHelpParameter {
601601
const displayParts = mapToDisplayParts(writer => {
602-
const param = checker.typeParameterToDeclaration(typeParameter, enclosingDeclaration)!;
602+
const param = checker.typeParameterToDeclaration(typeParameter, enclosingDeclaration, signatureHelpNodeBuilderFlags)!;
603603
printer.writeNode(EmitHint.Unspecified, param, sourceFile, writer);
604604
});
605605
return { name: typeParameter.symbol.name, documentation: typeParameter.symbol.getDocumentationComment(checker), displayParts, isOptional: false };

src/services/symbolDisplay.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
/* @internal */
22
namespace ts.SymbolDisplay {
3+
const symbolDisplayNodeBuilderFlags = NodeBuilderFlags.OmitParameterModifiers | NodeBuilderFlags.IgnoreErrors | NodeBuilderFlags.UseAliasDefinedOutsideCurrentScope;
4+
35
// TODO(drosen): use contextual SemanticMeaning.
46
export function getSymbolKind(typeChecker: TypeChecker, symbol: Symbol, location: Node): ScriptElementKind {
57
const result = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(typeChecker, symbol, location);
@@ -471,7 +473,7 @@ namespace ts.SymbolDisplay {
471473
// If the type is type parameter, format it specially
472474
if (type.symbol && type.symbol.flags & SymbolFlags.TypeParameter) {
473475
const typeParameterParts = mapToDisplayParts(writer => {
474-
const param = typeChecker.typeParameterToDeclaration(type as TypeParameter, enclosingDeclaration)!;
476+
const param = typeChecker.typeParameterToDeclaration(type as TypeParameter, enclosingDeclaration, symbolDisplayNodeBuilderFlags)!;
475477
getPrinter().writeNode(EmitHint.Unspecified, param, getSourceFileOfNode(getParseTreeNode(enclosingDeclaration)), writer);
476478
});
477479
addRange(displayParts, typeParameterParts);
@@ -631,7 +633,7 @@ namespace ts.SymbolDisplay {
631633

632634
function writeTypeParametersOfSymbol(symbol: Symbol, enclosingDeclaration: Node | undefined) {
633635
const typeParameterParts = mapToDisplayParts(writer => {
634-
const params = typeChecker.symbolToTypeParameterDeclarations(symbol, enclosingDeclaration);
636+
const params = typeChecker.symbolToTypeParameterDeclarations(symbol, enclosingDeclaration, symbolDisplayNodeBuilderFlags);
635637
getPrinter().writeList(ListFormat.TypeParameters, params, getSourceFileOfNode(getParseTreeNode(enclosingDeclaration)), writer);
636638
});
637639
addRange(displayParts, typeParameterParts);

tests/baselines/reference/api/tsserverlibrary.d.ts

+8-8
Original file line numberDiff line numberDiff line change
@@ -2040,23 +2040,23 @@ declare namespace ts {
20402040
getNonNullableType(type: Type): Type;
20412041
getTypeArguments(type: TypeReference): readonly Type[];
20422042
/** Note that the resulting nodes cannot be checked. */
2043-
typeToTypeNode(type: Type, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): TypeNode | undefined;
2043+
typeToTypeNode(type: Type, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): TypeNode | undefined;
20442044
/** Note that the resulting nodes cannot be checked. */
2045-
signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): (SignatureDeclaration & {
2045+
signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): (SignatureDeclaration & {
20462046
typeArguments?: NodeArray<TypeNode>;
20472047
}) | undefined;
20482048
/** Note that the resulting nodes cannot be checked. */
2049-
indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): IndexSignatureDeclaration | undefined;
2049+
indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): IndexSignatureDeclaration | undefined;
20502050
/** Note that the resulting nodes cannot be checked. */
2051-
symbolToEntityName(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): EntityName | undefined;
2051+
symbolToEntityName(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): EntityName | undefined;
20522052
/** Note that the resulting nodes cannot be checked. */
2053-
symbolToExpression(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): Expression | undefined;
2053+
symbolToExpression(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): Expression | undefined;
20542054
/** Note that the resulting nodes cannot be checked. */
2055-
symbolToTypeParameterDeclarations(symbol: Symbol, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): NodeArray<TypeParameterDeclaration> | undefined;
2055+
symbolToTypeParameterDeclarations(symbol: Symbol, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): NodeArray<TypeParameterDeclaration> | undefined;
20562056
/** Note that the resulting nodes cannot be checked. */
2057-
symbolToParameterDeclaration(symbol: Symbol, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): ParameterDeclaration | undefined;
2057+
symbolToParameterDeclaration(symbol: Symbol, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): ParameterDeclaration | undefined;
20582058
/** Note that the resulting nodes cannot be checked. */
2059-
typeParameterToDeclaration(parameter: TypeParameter, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): TypeParameterDeclaration | undefined;
2059+
typeParameterToDeclaration(parameter: TypeParameter, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): TypeParameterDeclaration | undefined;
20602060
getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[];
20612061
getSymbolAtLocation(node: Node): Symbol | undefined;
20622062
getSymbolsOfParameterPropertyDeclaration(parameter: ParameterDeclaration, parameterName: string): Symbol[];

tests/baselines/reference/api/typescript.d.ts

+8-8
Original file line numberDiff line numberDiff line change
@@ -2040,23 +2040,23 @@ declare namespace ts {
20402040
getNonNullableType(type: Type): Type;
20412041
getTypeArguments(type: TypeReference): readonly Type[];
20422042
/** Note that the resulting nodes cannot be checked. */
2043-
typeToTypeNode(type: Type, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): TypeNode | undefined;
2043+
typeToTypeNode(type: Type, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): TypeNode | undefined;
20442044
/** Note that the resulting nodes cannot be checked. */
2045-
signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): (SignatureDeclaration & {
2045+
signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): (SignatureDeclaration & {
20462046
typeArguments?: NodeArray<TypeNode>;
20472047
}) | undefined;
20482048
/** Note that the resulting nodes cannot be checked. */
2049-
indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): IndexSignatureDeclaration | undefined;
2049+
indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): IndexSignatureDeclaration | undefined;
20502050
/** Note that the resulting nodes cannot be checked. */
2051-
symbolToEntityName(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): EntityName | undefined;
2051+
symbolToEntityName(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): EntityName | undefined;
20522052
/** Note that the resulting nodes cannot be checked. */
2053-
symbolToExpression(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): Expression | undefined;
2053+
symbolToExpression(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): Expression | undefined;
20542054
/** Note that the resulting nodes cannot be checked. */
2055-
symbolToTypeParameterDeclarations(symbol: Symbol, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): NodeArray<TypeParameterDeclaration> | undefined;
2055+
symbolToTypeParameterDeclarations(symbol: Symbol, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): NodeArray<TypeParameterDeclaration> | undefined;
20562056
/** Note that the resulting nodes cannot be checked. */
2057-
symbolToParameterDeclaration(symbol: Symbol, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): ParameterDeclaration | undefined;
2057+
symbolToParameterDeclaration(symbol: Symbol, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): ParameterDeclaration | undefined;
20582058
/** Note that the resulting nodes cannot be checked. */
2059-
typeParameterToDeclaration(parameter: TypeParameter, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): TypeParameterDeclaration | undefined;
2059+
typeParameterToDeclaration(parameter: TypeParameter, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): TypeParameterDeclaration | undefined;
20602060
getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[];
20612061
getSymbolAtLocation(node: Node): Symbol | undefined;
20622062
getSymbolsOfParameterPropertyDeclaration(parameter: ParameterDeclaration, parameterName: string): Symbol[];

0 commit comments

Comments
 (0)