@@ -2993,9 +2993,6 @@ namespace ts {
2993
2993
}
2994
2994
2995
2995
function typeToString(type: Type, enclosingDeclaration?: Node, flags: TypeFormatFlags = TypeFormatFlags.AllowUniqueESSymbolType | TypeFormatFlags.UseAliasDefinedOutsideCurrentScope, writer: EmitTextWriter = createTextWriter("")): string {
2996
- if (writer.maximumApproximateLength === undefined) {
2997
- writer.maximumApproximateLength = defaultMaximumTruncationLength;
2998
- }
2999
2996
const noTruncation = compilerOptions.noErrorTruncation || flags & TypeFormatFlags.NoTruncation;
3000
2997
const typeNode = nodeBuilder.typeToTypeNode(type, enclosingDeclaration, toNodeBuilderFlags(flags) | NodeBuilderFlags.IgnoreErrors | (noTruncation ? NodeBuilderFlags.NoTruncation : 0), writer);
3001
2998
if (typeNode === undefined) return Debug.fail("should always get typenode");
@@ -3005,7 +3002,7 @@ namespace ts {
3005
3002
printer.writeNode(EmitHint.Unspecified, typeNode, /*sourceFile*/ sourceFile, writer);
3006
3003
const result = writer.getText();
3007
3004
3008
- const maxLength = noTruncation ? undefined : writer.maximumApproximateLength ;
3005
+ const maxLength = noTruncation ? undefined : defaultMaximumTruncationLength * 2 ;
3009
3006
if (maxLength && result && result.length >= maxLength) {
3010
3007
return result.substr(0, maxLength - "...".length) + "...";
3011
3008
}
@@ -3051,6 +3048,11 @@ namespace ts {
3051
3048
return context.encounteredError ? undefined : resultingNode;
3052
3049
}
3053
3050
3051
+ function checkTruncationLength(context: NodeBuilderContext): boolean {
3052
+ if (context.truncating) return context.truncating;
3053
+ return context.truncating = !(context.flags & NodeBuilderFlags.NoTruncation) && context.approximateLength > defaultMaximumTruncationLength;
3054
+ }
3055
+
3054
3056
function typeToTypeNodeHelper(type: Type, context: NodeBuilderContext): TypeNode {
3055
3057
if (cancellationToken && cancellationToken.throwIfCancellationRequested) {
3056
3058
cancellationToken.throwIfCancellationRequested();
@@ -3063,7 +3065,7 @@ namespace ts {
3063
3065
return undefined!; // TODO: GH#18217
3064
3066
}
3065
3067
3066
- if (type.flags & TypeFlags.Any || (!(context.flags & NodeBuilderFlags.NoTruncation) && context.approximateLength > (context.tracker.maximumApproximateLength || 2000)) ) {
3068
+ if (type.flags & TypeFlags.Any) {
3067
3069
context.approximateLength += 3;
3068
3070
return createKeywordTypeNode(SyntaxKind.AnyKeyword);
3069
3071
}
@@ -3189,10 +3191,9 @@ namespace ts {
3189
3191
}
3190
3192
if (type.flags & (TypeFlags.Union | TypeFlags.Intersection)) {
3191
3193
const types = type.flags & TypeFlags.Union ? formatUnionTypes((<UnionType>type).types) : (<IntersectionType>type).types;
3192
- const typeNodes = mapToTypeNodes(types, context);
3194
+ const typeNodes = mapToTypeNodes(types, context, /*isBareList*/ true );
3193
3195
if (typeNodes && typeNodes.length > 0) {
3194
3196
const unionOrIntersectionTypeNode = createUnionOrIntersectionTypeNode(type.flags & TypeFlags.Union ? SyntaxKind.UnionType : SyntaxKind.IntersectionType, typeNodes);
3195
- context.approximateLength += (3 * (types.length - 1));
3196
3197
return unionOrIntersectionTypeNode;
3197
3198
}
3198
3199
else {
@@ -3471,6 +3472,9 @@ namespace ts {
3471
3472
}
3472
3473
3473
3474
function createTypeNodesFromResolvedType(resolvedType: ResolvedType): TypeElement[] | undefined {
3475
+ if (checkTruncationLength(context)) {
3476
+ return [createPropertySignature(/*modifiers*/ undefined, "...", /*questionToken*/ undefined, /*type*/ undefined, /*initializer*/ undefined)];
3477
+ }
3474
3478
const typeElements: TypeElement[] = [];
3475
3479
for (const signature of resolvedType.callSignatures) {
3476
3480
typeElements.push(<CallSignatureDeclaration>signatureToSignatureDeclarationHelper(signature, SyntaxKind.CallSignature, context));
@@ -3493,7 +3497,9 @@ namespace ts {
3493
3497
return typeElements;
3494
3498
}
3495
3499
3500
+ let i = 0;
3496
3501
for (const propertySymbol of properties) {
3502
+ i++;
3497
3503
if (context.flags & NodeBuilderFlags.WriteClassExpressionAsTypeLiteral) {
3498
3504
if (propertySymbol.flags & SymbolFlags.Prototype) {
3499
3505
continue;
@@ -3502,69 +3508,102 @@ namespace ts {
3502
3508
context.tracker.reportPrivateInBaseOfClassExpression(unescapeLeadingUnderscores(propertySymbol.escapedName));
3503
3509
}
3504
3510
}
3505
- const propertyType = getCheckFlags(propertySymbol) & CheckFlags.ReverseMapped && context.flags & NodeBuilderFlags.InReverseMappedType ?
3506
- anyType : getTypeOfSymbol(propertySymbol);
3507
- const saveEnclosingDeclaration = context.enclosingDeclaration;
3508
- context.enclosingDeclaration = undefined;
3509
- if (getCheckFlags(propertySymbol) & CheckFlags.Late) {
3510
- const decl = first(propertySymbol.declarations);
3511
- if (context.tracker.trackSymbol && hasLateBindableName(decl)) {
3512
- // get symbol of the first identifier of the entityName
3513
- const firstIdentifier = getFirstIdentifier(decl.name.expression);
3514
- const name = resolveName(firstIdentifier, firstIdentifier.escapedText, SymbolFlags.Value | SymbolFlags.ExportValue, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true);
3515
- if (name) {
3516
- context.tracker.trackSymbol(name, saveEnclosingDeclaration, SymbolFlags.Value);
3517
- }
3518
- }
3511
+ if (checkTruncationLength(context) && (i + 2 < properties.length - 1)) {
3512
+ typeElements.push(createPropertySignature(/*modifiers*/ undefined, `... ${properties.length - i} more ...`, /*questionToken*/ undefined, /*type*/ undefined, /*initializer*/ undefined))
3513
+ addPropertyToElementList(properties[properties.length - 1], context, typeElements);
3514
+ break;
3519
3515
}
3520
- const propertyName = symbolToName(propertySymbol, context, SymbolFlags.Value, /*expectsIdentifier*/ true);
3521
- context.approximateLength += (symbolName(propertySymbol).length + 1);
3522
- context.enclosingDeclaration = saveEnclosingDeclaration;
3523
- const optionalToken = propertySymbol.flags & SymbolFlags.Optional ? createToken(SyntaxKind.QuestionToken) : undefined;
3524
- if (propertySymbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && !getPropertiesOfObjectType(propertyType).length) {
3525
- const signatures = getSignaturesOfType(propertyType, SignatureKind.Call);
3526
- for (const signature of signatures) {
3527
- const methodDeclaration = <MethodSignature>signatureToSignatureDeclarationHelper(signature, SyntaxKind.MethodSignature, context);
3528
- methodDeclaration.name = propertyName;
3529
- methodDeclaration.questionToken = optionalToken;
3530
- if (propertySymbol.valueDeclaration) {
3531
- // Copy comments to node for declaration emit
3532
- setCommentRange(methodDeclaration, propertySymbol.valueDeclaration);
3533
- }
3534
- typeElements.push(methodDeclaration);
3535
- }
3516
+ addPropertyToElementList(propertySymbol, context, typeElements);
3517
+
3518
+ }
3519
+ return typeElements.length ? typeElements : undefined;
3520
+ }
3521
+ }
3522
+
3523
+ function addPropertyToElementList(propertySymbol: Symbol, context: NodeBuilderContext, typeElements: TypeElement[]) {
3524
+ const propertyType = getCheckFlags(propertySymbol) & CheckFlags.ReverseMapped && context.flags & NodeBuilderFlags.InReverseMappedType ?
3525
+ anyType : getTypeOfSymbol(propertySymbol);
3526
+ const saveEnclosingDeclaration = context.enclosingDeclaration;
3527
+ context.enclosingDeclaration = undefined;
3528
+ if (getCheckFlags(propertySymbol) & CheckFlags.Late) {
3529
+ const decl = first(propertySymbol.declarations);
3530
+ if (context.tracker.trackSymbol && hasLateBindableName(decl)) {
3531
+ // get symbol of the first identifier of the entityName
3532
+ const firstIdentifier = getFirstIdentifier(decl.name.expression);
3533
+ const name = resolveName(firstIdentifier, firstIdentifier.escapedText, SymbolFlags.Value | SymbolFlags.ExportValue, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true);
3534
+ if (name) {
3535
+ context.tracker.trackSymbol(name, saveEnclosingDeclaration, SymbolFlags.Value);
3536
3536
}
3537
- else {
3538
- const savedFlags = context.flags;
3539
- context.flags |= !!(getCheckFlags(propertySymbol) & CheckFlags.ReverseMapped) ? NodeBuilderFlags.InReverseMappedType : 0;
3540
- const propertyTypeNode = propertyType ? typeToTypeNodeHelper(propertyType, context) : createKeywordTypeNode(SyntaxKind.AnyKeyword);
3541
- context.flags = savedFlags;
3542
-
3543
- const modifiers = isReadonlySymbol(propertySymbol) ? [createToken(SyntaxKind.ReadonlyKeyword)] : undefined;
3544
- if (modifiers) {
3545
- context.approximateLength += 9;
3546
- }
3547
- const propertySignature = createPropertySignature(
3548
- modifiers,
3549
- propertyName,
3550
- optionalToken,
3551
- propertyTypeNode,
3552
- /*initializer*/ undefined);
3553
- if (propertySymbol.valueDeclaration) {
3554
- // Copy comments to node for declaration emit
3555
- setCommentRange(propertySignature, propertySymbol.valueDeclaration);
3556
- }
3557
- typeElements.push(propertySignature);
3537
+ }
3538
+ }
3539
+ const propertyName = symbolToName(propertySymbol, context, SymbolFlags.Value, /*expectsIdentifier*/ true);
3540
+ context.approximateLength += (symbolName(propertySymbol).length + 1);
3541
+ context.enclosingDeclaration = saveEnclosingDeclaration;
3542
+ const optionalToken = propertySymbol.flags & SymbolFlags.Optional ? createToken(SyntaxKind.QuestionToken) : undefined;
3543
+ if (propertySymbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && !getPropertiesOfObjectType(propertyType).length) {
3544
+ const signatures = getSignaturesOfType(propertyType, SignatureKind.Call);
3545
+ for (const signature of signatures) {
3546
+ const methodDeclaration = <MethodSignature>signatureToSignatureDeclarationHelper(signature, SyntaxKind.MethodSignature, context);
3547
+ methodDeclaration.name = propertyName;
3548
+ methodDeclaration.questionToken = optionalToken;
3549
+ if (propertySymbol.valueDeclaration) {
3550
+ // Copy comments to node for declaration emit
3551
+ setCommentRange(methodDeclaration, propertySymbol.valueDeclaration);
3558
3552
}
3553
+ typeElements.push(methodDeclaration);
3559
3554
}
3560
- return typeElements.length ? typeElements : undefined;
3555
+ }
3556
+ else {
3557
+ const savedFlags = context.flags;
3558
+ context.flags |= !!(getCheckFlags(propertySymbol) & CheckFlags.ReverseMapped) ? NodeBuilderFlags.InReverseMappedType : 0;
3559
+ const propertyTypeNode = propertyType ? typeToTypeNodeHelper(propertyType, context) : createKeywordTypeNode(SyntaxKind.AnyKeyword);
3560
+ context.flags = savedFlags;
3561
+
3562
+ const modifiers = isReadonlySymbol(propertySymbol) ? [createToken(SyntaxKind.ReadonlyKeyword)] : undefined;
3563
+ if (modifiers) {
3564
+ context.approximateLength += 9;
3565
+ }
3566
+ const propertySignature = createPropertySignature(
3567
+ modifiers,
3568
+ propertyName,
3569
+ optionalToken,
3570
+ propertyTypeNode,
3571
+ /*initializer*/ undefined);
3572
+ if (propertySymbol.valueDeclaration) {
3573
+ // Copy comments to node for declaration emit
3574
+ setCommentRange(propertySignature, propertySymbol.valueDeclaration);
3575
+ }
3576
+ typeElements.push(propertySignature);
3561
3577
}
3562
3578
}
3563
3579
3564
- function mapToTypeNodes(types: ReadonlyArray<Type> | undefined, context: NodeBuilderContext): TypeNode[] | undefined {
3580
+ function mapToTypeNodes(types: ReadonlyArray<Type> | undefined, context: NodeBuilderContext, isBareList?: boolean ): TypeNode[] | undefined {
3565
3581
if (some(types)) {
3582
+ if (checkTruncationLength(context)) {
3583
+ if (!isBareList) {
3584
+ return [createTypeReferenceNode("...", /*typeArguments*/ undefined)];
3585
+ }
3586
+ else if (types.length > 2) {
3587
+ return [
3588
+ typeToTypeNodeHelper(types[0], context),
3589
+ createTypeReferenceNode(`... ${types.length - 2} more ...`, /*typeArguments*/ undefined),
3590
+ typeToTypeNodeHelper(types[types.length - 1], context)
3591
+ ];
3592
+ }
3593
+ }
3566
3594
const result = [];
3595
+ let i = 0;
3567
3596
for (const type of types) {
3597
+ i++;
3598
+ if (checkTruncationLength(context) && (i + 2 < types.length - 1)) {
3599
+ result.push(createTypeReferenceNode(`... ${types.length - i} more ...`, /*typeArguments*/ undefined));
3600
+ const typeNode = typeToTypeNodeHelper(types[types.length - 1], context);
3601
+ if (typeNode) {
3602
+ result.push(typeNode);
3603
+ }
3604
+ break;
3605
+ }
3606
+ context.approximateLength += 2; // Account for whitespace + separator
3568
3607
const typeNode = typeToTypeNodeHelper(type, context);
3569
3608
if (typeNode) {
3570
3609
result.push(typeNode);
@@ -4078,6 +4117,7 @@ namespace ts {
4078
4117
visitedSymbols: Map<true> | undefined;
4079
4118
inferTypeParameters: TypeParameter[] | undefined;
4080
4119
approximateLength: number;
4120
+ truncating?: boolean;
4081
4121
}
4082
4122
4083
4123
function isDefaultBindingContext(location: Node) {
0 commit comments