Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit6149b41

Browse files
authored
Generate names for type parameter declarations in inferred types (microsoft#23902)
* Generate names for type parameter declarations in inferred types* Fix lint* Merge functions, make overload private* Handle some edge cases better (nodes in differing files than current emit)* Account for transformed nodes
1 parent1b796ed commit6149b41

12 files changed

+192
-27
lines changed

‎src/compiler/checker.ts

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2746,7 +2746,7 @@ namespace ts {
27462746
* @param shouldComputeAliasToMakeVisible a boolean value to indicate whether to return aliases to be mark visible in case the symbol is accessible
27472747
*/
27482748
function isSymbolAccessible(symbol: Symbol, enclosingDeclaration: Node, meaning: SymbolFlags, shouldComputeAliasesToMakeVisible: boolean): SymbolAccessibilityResult {
2749-
if (symbol && enclosingDeclaration && !(symbol.flags & SymbolFlags.TypeParameter)) {
2749+
if (symbol && enclosingDeclaration) {
27502750
const initialSymbol = symbol;
27512751
let meaningToLook = meaning;
27522752
while (symbol) {
@@ -3118,7 +3118,15 @@ namespace ts {
31183118
}
31193119
if (type.flags & TypeFlags.TypeParameter || objectFlags & ObjectFlags.ClassOrInterface) {
31203120
if (type.flags & TypeFlags.TypeParameter && contains(context.inferTypeParameters, type)) {
3121-
return createInferTypeNode(createTypeParameterDeclaration(getNameOfSymbolAsWritten(type.symbol)));
3121+
return createInferTypeNode(typeParameterToDeclarationWithConstraint(type as TypeParameter, context, /*constraintNode*/ undefined));
3122+
}
3123+
if (context.flags & NodeBuilderFlags.GenerateNamesForShadowedTypeParams &&
3124+
type.flags & TypeFlags.TypeParameter &&
3125+
length(type.symbol.declarations) &&
3126+
isTypeParameterDeclaration(type.symbol.declarations[0]) &&
3127+
typeParameterShadowsNameInScope(type, context) &&
3128+
!isTypeSymbolAccessible(type.symbol, context.enclosingDeclaration)) {
3129+
return createTypeReferenceNode(getGeneratedNameForNode((type.symbol.declarations[0] as TypeParameterDeclaration).name, GeneratedIdentifierFlags.Optimistic | GeneratedIdentifierFlags.ReservedInNestedScopes), /*typeArguments*/ undefined);
31223130
}
31233131
const name = type.symbol ? symbolToName(type.symbol, context, SymbolFlags.Type, /*expectsIdentifier*/ false) : createIdentifier("?");
31243132
// Ignore constraint/default when creating a usage (as opposed to declaration) of a type parameter.
@@ -3563,10 +3571,21 @@ namespace ts {
35633571
return createSignatureDeclaration(kind, typeParameters, parameters, returnTypeNode, typeArguments);
35643572
}
35653573

3566-
function typeParameterToDeclarationWithConstraint(type: TypeParameter, context: NodeBuilderContext, constraintNode: TypeNode): TypeParameterDeclaration {
3574+
function typeParameterShadowsNameInScope(type: TypeParameter, context: NodeBuilderContext) {
3575+
return !!resolveName(context.enclosingDeclaration, type.symbol.escapedName, SymbolFlags.Type, /*nameNotFoundArg*/ undefined, type.symbol.escapedName, /*isUse*/ false);
3576+
}
3577+
3578+
function typeParameterToDeclarationWithConstraint(type: TypeParameter, context: NodeBuilderContext, constraintNode: TypeNode | undefined): TypeParameterDeclaration {
35673579
const savedContextFlags = context.flags;
35683580
context.flags &= ~NodeBuilderFlags.WriteTypeParametersInQualifiedName; // Avoids potential infinite loop when building for a claimspace with a generic
3569-
const name = symbolToName(type.symbol, context, SymbolFlags.Type, /*expectsIdentifier*/ true);
3581+
const shouldUseGeneratedName =
3582+
context.flags & NodeBuilderFlags.GenerateNamesForShadowedTypeParams &&
3583+
type.symbol.declarations[0] &&
3584+
isTypeParameterDeclaration(type.symbol.declarations[0]) &&
3585+
typeParameterShadowsNameInScope(type, context);
3586+
const name = shouldUseGeneratedName
3587+
? getGeneratedNameForNode((type.symbol.declarations[0] as TypeParameterDeclaration).name, GeneratedIdentifierFlags.Optimistic | GeneratedIdentifierFlags.ReservedInNestedScopes)
3588+
: symbolToName(type.symbol, context, SymbolFlags.Type, /*expectsIdentifier*/ true);
35703589
const defaultParameter = getDefaultFromTypeParameter(type);
35713590
const defaultParameterNode = defaultParameter && typeToTypeNodeHelper(defaultParameter, context);
35723591
context.flags = savedContextFlags;
@@ -3799,6 +3818,7 @@ namespace ts {
37993818
if (index === 0) {
38003819
context.flags ^= NodeBuilderFlags.InInitialEntityName;
38013820
}
3821+
38023822
const identifier = setEmitFlags(createIdentifier(symbolName, typeParameterNodes), EmitFlags.NoAsciiEscaping);
38033823
identifier.symbol = symbol;
38043824

‎src/compiler/emitter.ts

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1132,6 +1132,7 @@ namespace ts {
11321132
}
11331133

11341134
functionemitMethodSignature(node:MethodSignature){
1135+
pushNameGenerationScope(node);
11351136
emitDecorators(node,node.decorators);
11361137
emitModifiers(node,node.modifiers);
11371138
emit(node.name);
@@ -1140,6 +1141,7 @@ namespace ts {
11401141
emitParameters(node,node.parameters);
11411142
emitTypeAnnotation(node.type);
11421143
writeSemicolon();
1144+
popNameGenerationScope(node);
11431145
}
11441146

11451147
functionemitMethodDeclaration(node:MethodDeclaration){
@@ -1167,15 +1169,18 @@ namespace ts {
11671169
}
11681170

11691171
functionemitCallSignature(node:CallSignatureDeclaration){
1172+
pushNameGenerationScope(node);
11701173
emitDecorators(node,node.decorators);
11711174
emitModifiers(node,node.modifiers);
11721175
emitTypeParameters(node,node.typeParameters);
11731176
emitParameters(node,node.parameters);
11741177
emitTypeAnnotation(node.type);
11751178
writeSemicolon();
1179+
popNameGenerationScope(node);
11761180
}
11771181

11781182
functionemitConstructSignature(node:ConstructSignatureDeclaration){
1183+
pushNameGenerationScope(node);
11791184
emitDecorators(node,node.decorators);
11801185
emitModifiers(node,node.modifiers);
11811186
writeKeyword("new");
@@ -1184,6 +1189,7 @@ namespace ts {
11841189
emitParameters(node,node.parameters);
11851190
emitTypeAnnotation(node.type);
11861191
writeSemicolon();
1192+
popNameGenerationScope(node);
11871193
}
11881194

11891195
functionemitIndexSignature(node:IndexSignatureDeclaration){
@@ -1216,12 +1222,14 @@ namespace ts {
12161222
}
12171223

12181224
functionemitFunctionType(node:FunctionTypeNode){
1225+
pushNameGenerationScope(node);
12191226
emitTypeParameters(node,node.typeParameters);
12201227
emitParametersForArrow(node,node.parameters);
12211228
writeSpace();
12221229
writePunctuation("=>");
12231230
writeSpace();
12241231
emit(node.type);
1232+
popNameGenerationScope(node);
12251233
}
12261234

12271235
functionemitJSDocFunctionType(node:JSDocFunctionType){
@@ -1248,6 +1256,7 @@ namespace ts {
12481256
}
12491257

12501258
functionemitConstructorType(node:ConstructorTypeNode){
1259+
pushNameGenerationScope(node);
12511260
writeKeyword("new");
12521261
writeSpace();
12531262
emitTypeParameters(node,node.typeParameters);
@@ -1256,6 +1265,7 @@ namespace ts {
12561265
writePunctuation("=>");
12571266
writeSpace();
12581267
emit(node.type);
1268+
popNameGenerationScope(node);
12591269
}
12601270

12611271
functionemitTypeQuery(node:TypeQueryNode){
@@ -3241,7 +3251,7 @@ namespace ts {
32413251
if(isGeneratedIdentifier(node)){
32423252
returngenerateName(node);
32433253
}
3244-
elseif(isIdentifier(node)&&(nodeIsSynthesized(node)||!node.parent)){
3254+
elseif(isIdentifier(node)&&(nodeIsSynthesized(node)||!node.parent||!currentSourceFile||(node.parent&&currentSourceFile&&getSourceFileOfNode(node)!==getOriginalNode(currentSourceFile)))){
32453255
returnidText(node);
32463256
}
32473257
elseif(node.kind===SyntaxKind.StringLiteral&&(<StringLiteral>node).textSourceNode){
@@ -3415,7 +3425,7 @@ namespace ts {
34153425
if((name.autoGenerateFlags&GeneratedIdentifierFlags.KindMask)===GeneratedIdentifierFlags.Node){
34163426
// Node names generate unique names based on their original node
34173427
// and are cached based on that node's id.
3418-
returngenerateNameCached(getNodeForGeneratedName(name));
3428+
returngenerateNameCached(getNodeForGeneratedName(name),name.autoGenerateFlags);
34193429
}
34203430
else{
34213431
// Auto, Loop, and Unique names are cached based on their unique
@@ -3425,9 +3435,9 @@ namespace ts {
34253435
}
34263436
}
34273437

3428-
functiongenerateNameCached(node:Node){
3438+
functiongenerateNameCached(node:Node,flags?:GeneratedIdentifierFlags){
34293439
constnodeId=getNodeId(node);
3430-
returnnodeIdToGeneratedName[nodeId]||(nodeIdToGeneratedName[nodeId]=generateNameForNode(node));
3440+
returnnodeIdToGeneratedName[nodeId]||(nodeIdToGeneratedName[nodeId]=generateNameForNode(node,flags));
34313441
}
34323442

34333443
/**
@@ -3444,7 +3454,7 @@ namespace ts {
34443454
* Returns a value indicating whether a name is unique globally or within the current file.
34453455
*/
34463456
functionisFileLevelUniqueName(name:string){
3447-
returnts.isFileLevelUniqueName(currentSourceFile,name,hasGlobalName);
3457+
returncurrentSourceFile ?ts.isFileLevelUniqueName(currentSourceFile,name,hasGlobalName) :true;
34483458
}
34493459

34503460
/**
@@ -3504,10 +3514,15 @@ namespace ts {
35043514
* makeUniqueName are guaranteed to never conflict.
35053515
* If `optimistic` is set, the first instance will use 'baseName' verbatim instead of 'baseName_1'
35063516
*/
3507-
functionmakeUniqueName(baseName:string,checkFn:(name:string)=>boolean=isUniqueName,optimistic?:boolean):string{
3517+
functionmakeUniqueName(baseName:string,checkFn:(name:string)=>boolean=isUniqueName,optimistic?:boolean,scoped?:boolean):string{
35083518
if(optimistic){
35093519
if(checkFn(baseName)){
3510-
generatedNames.set(baseName,true);
3520+
if(scoped){
3521+
reserveNameInNestedScopes(baseName);
3522+
}
3523+
else{
3524+
generatedNames.set(baseName,true);
3525+
}
35113526
returnbaseName;
35123527
}
35133528
}
@@ -3519,7 +3534,12 @@ namespace ts {
35193534
while(true){
35203535
constgeneratedName=baseName+i;
35213536
if(checkFn(generatedName)){
3522-
generatedNames.set(generatedName,true);
3537+
if(scoped){
3538+
reserveNameInNestedScopes(generatedName);
3539+
}
3540+
else{
3541+
generatedNames.set(generatedName,true);
3542+
}
35233543
returngeneratedName;
35243544
}
35253545
i++;
@@ -3573,10 +3593,15 @@ namespace ts {
35733593
/**
35743594
* Generates a unique name from a node.
35753595
*/
3576-
functiongenerateNameForNode(node:Node):string{
3596+
functiongenerateNameForNode(node:Node,flags?:GeneratedIdentifierFlags):string{
35773597
switch(node.kind){
35783598
caseSyntaxKind.Identifier:
3579-
returnmakeUniqueName(getTextOfNode(node));
3599+
returnmakeUniqueName(
3600+
getTextOfNode(node),
3601+
isUniqueName,
3602+
!!(flags&GeneratedIdentifierFlags.Optimistic),
3603+
!!(flags&GeneratedIdentifierFlags.ReservedInNestedScopes)
3604+
);
35803605
caseSyntaxKind.ModuleDeclaration:
35813606
caseSyntaxKind.EnumDeclaration:
35823607
returngenerateNameForModuleOrEnum(<ModuleDeclaration|EnumDeclaration>node);
@@ -3611,7 +3636,8 @@ namespace ts {
36113636
returnmakeUniqueName(
36123637
idText(name),
36133638
(name.autoGenerateFlags&GeneratedIdentifierFlags.FileLevel) ?isFileLevelUniqueName :isUniqueName,
3614-
!!(name.autoGenerateFlags&GeneratedIdentifierFlags.Optimistic)
3639+
!!(name.autoGenerateFlags&GeneratedIdentifierFlags.Optimistic),
3640+
!!(name.autoGenerateFlags&GeneratedIdentifierFlags.ReservedInNestedScopes)
36153641
);
36163642
}
36173643

@@ -3631,7 +3657,7 @@ namespace ts {
36313657
// if "node" is a different generated name (having a different
36323658
// "autoGenerateId"), use it and stop traversing.
36333659
if(isIdentifier(node)
3634-
&&node.autoGenerateFlags===GeneratedIdentifierFlags.Node
3660+
&&!!(node.autoGenerateFlags&GeneratedIdentifierFlags.Node)
36353661
&&node.autoGenerateId!==autoGenerateId){
36363662
break;
36373663
}

‎src/compiler/factory.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -192,9 +192,11 @@ namespace ts {
192192
}
193193

194194
/** Create a unique name generated for a node. */
195-
exportfunctiongetGeneratedNameForNode(node:Node):Identifier{
196-
constname=createIdentifier("");
197-
name.autoGenerateFlags=GeneratedIdentifierFlags.Node;
195+
exportfunctiongetGeneratedNameForNode(node:Node):Identifier;
196+
/*@internal */exportfunctiongetGeneratedNameForNode(node:Node,flags:GeneratedIdentifierFlags):Identifier;// tslint:disable-line unified-signatures
197+
exportfunctiongetGeneratedNameForNode(node:Node,flags?:GeneratedIdentifierFlags):Identifier{
198+
constname=createIdentifier(isIdentifier(node) ?idText(node) :"");
199+
name.autoGenerateFlags=GeneratedIdentifierFlags.Node|flags;
198200
name.autoGenerateId=nextAutoGenerateId;
199201
name.original=node;
200202
nextAutoGenerateId++;
@@ -4246,6 +4248,7 @@ namespace ts {
42464248
switch(member.kind){
42474249
caseSyntaxKind.TypeQuery:
42484250
caseSyntaxKind.TypeOperator:
4251+
caseSyntaxKind.InferType:
42494252
returncreateParenthesizedType(member);
42504253
}
42514254
returnparenthesizeElementTypeMember(member);

‎src/compiler/transformers/declarations.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,13 @@ namespace ts {
99
returnresult.diagnostics;
1010
}
1111

12-
constdeclarationEmitNodeBuilderFlags=NodeBuilderFlags.MultilineObjectLiterals|TypeFormatFlags.WriteClassExpressionAsTypeLiteral|NodeBuilderFlags.UseTypeOfFunction|NodeBuilderFlags.UseStructuralFallback|NodeBuilderFlags.AllowEmptyTuple;
12+
constdeclarationEmitNodeBuilderFlags=
13+
NodeBuilderFlags.MultilineObjectLiterals|
14+
TypeFormatFlags.WriteClassExpressionAsTypeLiteral|
15+
NodeBuilderFlags.UseTypeOfFunction|
16+
NodeBuilderFlags.UseStructuralFallback|
17+
NodeBuilderFlags.AllowEmptyTuple|
18+
NodeBuilderFlags.GenerateNamesForShadowedTypeParams;
1319

1420
/**
1521
* Transforms a ts file into a .d.ts file
@@ -95,6 +101,7 @@ namespace ts {
95101
}
96102

97103
functiontrackSymbol(symbol:Symbol,enclosingDeclaration?:Node,meaning?:SymbolFlags){
104+
if(symbol.flags&SymbolFlags.TypeParameter)return;
98105
handleSymbolAccessibilityError(resolver.isSymbolAccessible(symbol,enclosingDeclaration,meaning,/*shouldComputeAliasesToMakeVisible*/true));
99106
recordTypeReferenceDirectivesIfNecessary(resolver.getTypeReferenceDirectivesForSymbol(symbol,meaning));
100107
}

‎src/compiler/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3074,7 +3074,7 @@ namespace ts {
30743074
// Options
30753075
NoTruncation=1<<0,// Don't truncate result
30763076
WriteArrayAsGenericType=1<<1,// Write Array<T> instead T[]
3077-
//empty space
3077+
GenerateNamesForShadowedTypeParams=1<<2,//When a type parameter T is shadowing another T, generate a name for it so it can still be referenced
30783078
UseStructuralFallback=1<<3,// When an alias cannot be named by its symbol, rather than report an error, fallback to a structural printout if possible
30793079
// empty space
30803080
WriteTypeArgumentsOfSignature=1<<5,// Write the type arguments instead of type parameters of the signature

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1883,6 +1883,7 @@ declare namespace ts {
18831883
None=0,
18841884
NoTruncation=1,
18851885
WriteArrayAsGenericType=2,
1886+
GenerateNamesForShadowedTypeParams=4,
18861887
UseStructuralFallback=8,
18871888
WriteTypeArgumentsOfSignature=32,
18881889
UseFullyQualifiedType=64,

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1883,6 +1883,7 @@ declare namespace ts {
18831883
None=0,
18841884
NoTruncation=1,
18851885
WriteArrayAsGenericType=2,
1886+
GenerateNamesForShadowedTypeParams=4,
18861887
UseStructuralFallback=8,
18871888
WriteTypeArgumentsOfSignature=32,
18881889
UseFullyQualifiedType=64,

‎tests/baselines/reference/conditionalTypes1.types

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -927,32 +927,32 @@ type T52 = IsNever<any>; // false
927927
>IsNever : IsNever<T>
928928

929929
function f22<T>(x: T extends (infer U)[] ? U[] : never) {
930-
>f22 : <T>(x: T extends infer U[] ? U[] : never) => void
930+
>f22 : <T>(x: T extends(infer U)[] ? U[] : never) => void
931931
>T : T
932-
>x : T extends infer U[] ? U[] : never
932+
>x : T extends(infer U)[] ? U[] : never
933933
>T : T
934934
>U : U
935935
>U : U
936936

937937
let e = x[0]; // {}
938938
>e : {}
939939
>x[0] : {}
940-
>x : T extends infer U[] ? U[] : never
940+
>x : T extends(infer U)[] ? U[] : never
941941
>0 : 0
942942
}
943943

944944
function f23<T extends string[]>(x: T extends (infer U)[] ? U[] : never) {
945-
>f23 : <T extends string[]>(x: T extends infer U[] ? U[] : never) => void
945+
>f23 : <T extends string[]>(x: T extends(infer U)[] ? U[] : never) => void
946946
>T : T
947-
>x : T extends infer U[] ? U[] : never
947+
>x : T extends(infer U)[] ? U[] : never
948948
>T : T
949949
>U : U
950950
>U : U
951951

952952
let e = x[0]; // string
953953
>e : string
954954
>x[0] : string
955-
>x : T extends infer U[] ? U[] : never
955+
>x : T extends(infer U)[] ? U[] : never
956956
>0 : 0
957957
}
958958

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//// [declarationEmitNestedGenerics.ts]
2+
functionf<T>(p: T){
3+
letg:<T>(x:T)=>typeofp=nullasany;
4+
returng;
5+
}
6+
7+
functiong<T>(x: T){
8+
lety:typeofxextends(inferT)[] ?T :typeofx=nullasany;
9+
returny;
10+
}
11+
12+
//// [declarationEmitNestedGenerics.js]
13+
functionf(p){
14+
varg=null;
15+
returng;
16+
}
17+
functiong(x){
18+
vary=null;
19+
returny;
20+
}
21+
22+
23+
//// [declarationEmitNestedGenerics.d.ts]
24+
declarefunctionf<T>(p:T):<T_1>(x:T_1)=>T;
25+
declarefunctiong<T>(x:T):Textends(inferT_1)[] ?T_1 :T;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp