@@ -98,6 +98,9 @@ type NodeBuilderImpl struct {
9898
9999 // reusable visitor
100100 cloneBindingNameVisitor * ast.NodeVisitor
101+
102+ // symbols for synthesized identifiers, needed for e.g. inlay hints
103+ idToSymbol map [* ast.IdentifierNode ]* ast.Symbol
101104}
102105
103106const (
@@ -107,8 +110,11 @@ const (
107110
108111// Node builder utility functions
109112
110- func newNodeBuilderImpl (ch * Checker , e * printer.EmitContext ) * NodeBuilderImpl {
111- b := & NodeBuilderImpl {f : e .Factory .AsNodeFactory (), ch : ch , e : e }
113+ func newNodeBuilderImpl (ch * Checker , e * printer.EmitContext , idToSymbol map [* ast.IdentifierNode ]* ast.Symbol ) * NodeBuilderImpl {
114+ if idToSymbol == nil {
115+ idToSymbol = make (map [* ast.IdentifierNode ]* ast.Symbol )
116+ }
117+ b := & NodeBuilderImpl {f : e .Factory .AsNodeFactory (), ch : ch , e : e , idToSymbol : idToSymbol }
112118 b .cloneBindingNameVisitor = ast .NewNodeVisitor (b .cloneBindingName , b .f , ast.NodeVisitorHooks {})
113119 return b
114120}
@@ -482,7 +488,7 @@ func (b *NodeBuilderImpl) createEntityNameFromSymbolChain(chain []*ast.Symbol, i
482488 b .ctx .flags ^= nodebuilder .FlagsInInitialEntityName
483489 }
484490
485- identifier := b .f . NewIdentifier (symbolName )
491+ identifier := b .newIdentifier (symbolName , symbol )
486492 b .e .AddEmitFlags (identifier , printer .EFNoAsciiEscaping )
487493 // !!! TODO: smuggle type arguments out
488494 // if (typeParameterNodes) setIdentifierTypeArguments(identifier, factory.createNodeArray<TypeNode | TypeParameterDeclaration>(typeParameterNodes));
@@ -499,7 +505,7 @@ func (b *NodeBuilderImpl) createEntityNameFromSymbolChain(chain []*ast.Symbol, i
499505
500506// TODO: Audit usages of symbolToEntityNameNode - they should probably all be symbolToName
501507func (b * NodeBuilderImpl ) symbolToEntityNameNode (symbol * ast.Symbol ) * ast.EntityName {
502- identifier := b .f . NewIdentifier (symbol .Name )
508+ identifier := b .newIdentifier (symbol .Name , symbol )
503509 if symbol .Parent != nil {
504510 return b .f .NewQualifiedName (b .symbolToEntityNameNode (symbol .Parent ), identifier )
505511 }
@@ -701,7 +707,7 @@ func (b *NodeBuilderImpl) createAccessFromSymbolChain(chain []*ast.Symbol, index
701707 )
702708 }
703709
704- identifier := b .f . NewIdentifier (symbolName )
710+ identifier := b .newIdentifier (symbolName , symbol )
705711 b .e .AddEmitFlags (identifier , printer .EFNoAsciiEscaping )
706712 // !!! TODO: smuggle type arguments out
707713 // if (typeParameterNodes) setIdentifierTypeArguments(identifier, factory.createNodeArray<TypeNode | TypeParameterDeclaration>(typeParameterNodes));
@@ -740,7 +746,7 @@ func (b *NodeBuilderImpl) createExpressionFromSymbolChain(chain []*ast.Symbol, i
740746 }
741747
742748 if index == 0 || canUsePropertyAccess (symbolName ) {
743- identifier := b .f . NewIdentifier (symbolName )
749+ identifier := b .newIdentifier (symbolName , symbol )
744750 b .e .AddEmitFlags (identifier , printer .EFNoAsciiEscaping )
745751 // !!! TODO: smuggle type arguments out
746752 // if (typeParameterNodes) setIdentifierTypeArguments(identifier, factory.createNodeArray<TypeNode | TypeParameterDeclaration>(typeParameterNodes));
@@ -764,7 +770,7 @@ func (b *NodeBuilderImpl) createExpressionFromSymbolChain(chain []*ast.Symbol, i
764770 expression = b .f .NewNumericLiteral (symbolName , ast .TokenFlagsNone )
765771 }
766772 if expression == nil {
767- expression = b .f . NewIdentifier (symbolName )
773+ expression = b .newIdentifier (symbolName , symbol )
768774 b .e .AddEmitFlags (expression , printer .EFNoAsciiEscaping )
769775 // !!! TODO: smuggle type arguments out
770776 // if (typeParameterNodes) setIdentifierTypeArguments(identifier, factory.createNodeArray<TypeNode | TypeParameterDeclaration>(typeParameterNodes));
@@ -1252,7 +1258,11 @@ func (b *NodeBuilderImpl) setTextRange(range_ *ast.Node, location *ast.Node) *as
12521258 return range_
12531259 }
12541260 if ! ast .NodeIsSynthesized (range_ ) || (range_ .Flags & ast .NodeFlagsSynthesized == 0 ) || b .ctx .enclosingFile == nil || b .ctx .enclosingFile != ast .GetSourceFileOfNode (b .e .MostOriginal (range_ )) {
1261+ original := range_
12551262 range_ = range_ .Clone (b .f ) // if `range` is synthesized or originates in another file, copy it so it definitely has synthetic positions
1263+ if symbol , ok := b .idToSymbol [original ]; ok {
1264+ b .idToSymbol [range_ ] = symbol
1265+ }
12561266 }
12571267 if range_ == location || location == nil {
12581268 return range_
@@ -1327,7 +1337,7 @@ func (b *NodeBuilderImpl) typeParameterToName(typeParameter *Type) *ast.Identifi
13271337 if text != rawText {
13281338 // !!! TODO: smuggle type arguments out
13291339 // const typeArguments = getIdentifierTypeArguments(result);
1330- result = b .f . NewIdentifier (text )
1340+ result = b .newIdentifier (text , typeParameter . symbol )
13311341 // setIdentifierTypeArguments(result, typeArguments);
13321342 }
13331343
@@ -1584,18 +1594,20 @@ func (b *NodeBuilderImpl) symbolToParameterDeclaration(parameterSymbol *ast.Symb
15841594
15851595func (b * NodeBuilderImpl ) parameterToParameterDeclarationName (parameterSymbol * ast.Symbol , parameterDeclaration * ast.Node ) * ast.Node {
15861596 if parameterDeclaration == nil || parameterDeclaration .Name () == nil {
1587- return b .f . NewIdentifier (parameterSymbol .Name )
1597+ return b .newIdentifier (parameterSymbol .Name , parameterSymbol )
15881598 }
15891599
15901600 name := parameterDeclaration .Name ()
15911601 switch name .Kind {
15921602 case ast .KindIdentifier :
15931603 cloned := b .f .DeepCloneNode (name )
15941604 b .e .SetEmitFlags (cloned , printer .EFNoAsciiEscaping )
1605+ b .idToSymbol [cloned ] = parameterSymbol
15951606 return cloned
15961607 case ast .KindQualifiedName :
15971608 cloned := b .f .DeepCloneNode (name .AsQualifiedName ().Right )
15981609 b .e .SetEmitFlags (cloned , printer .EFNoAsciiEscaping )
1610+ b .idToSymbol [cloned ] = parameterSymbol
15991611 return cloned
16001612 default :
16011613 return b .cloneBindingName (name )
@@ -1667,7 +1679,7 @@ func (b *NodeBuilderImpl) typePredicateToTypePredicateNodeHelper(typePredicate *
16671679 }
16681680 var parameterName * ast.Node
16691681 if typePredicate .kind == TypePredicateKindIdentifier || typePredicate .kind == TypePredicateKindAssertsIdentifier {
1670- parameterName = b .f . NewIdentifier (typePredicate .parameterName )
1682+ parameterName = b .newIdentifier (typePredicate .parameterName , nil /*symbol*/ )
16711683 b .e .SetEmitFlags (parameterName , printer .EFNoAsciiEscaping )
16721684 } else {
16731685 parameterName = b .f .NewThisTypeNode ()
@@ -1950,7 +1962,7 @@ func (b *NodeBuilderImpl) indexInfoToIndexSignatureDeclarationHelper(indexInfo *
19501962 name := getNameFromIndexInfo (indexInfo )
19511963 indexerTypeNode := b .typeToTypeNode (indexInfo .keyType )
19521964
1953- indexingParameter := b .f .NewParameterDeclaration (nil , nil , b .f . NewIdentifier (name ), nil , indexerTypeNode , nil )
1965+ indexingParameter := b .f .NewParameterDeclaration (nil , nil , b .newIdentifier (name , nil /*symbol*/ ), nil , indexerTypeNode , nil )
19541966 if typeNode == nil {
19551967 if indexInfo .valueType == nil {
19561968 typeNode = b .f .NewKeywordTypeNode (ast .KindAnyKeyword )
@@ -2082,10 +2094,10 @@ func (b *NodeBuilderImpl) trackComputedName(accessExpression *ast.Node, enclosin
20822094 }
20832095}
20842096
2085- func (b * NodeBuilderImpl ) createPropertyNameNodeForIdentifierOrLiteral (name string , singleQuote bool , stringNamed bool , isMethod bool ) * ast.Node {
2097+ func (b * NodeBuilderImpl ) createPropertyNameNodeForIdentifierOrLiteral (name string , singleQuote bool , stringNamed bool , isMethod bool , symbol * ast. Symbol ) * ast.Node {
20862098 isMethodNamedNew := isMethod && name == "new"
20872099 if ! isMethodNamedNew && scanner .IsIdentifierText (name , core .LanguageVariantStandard ) {
2088- return b .f . NewIdentifier (name )
2100+ return b .newIdentifier (name , symbol )
20892101 }
20902102 if ! stringNamed && ! isMethodNamedNew && isNumericLiteralName (name ) && jsnum .FromString (name ) >= 0 {
20912103 return b .f .NewNumericLiteral (name , ast .TokenFlagsNone )
@@ -2133,7 +2145,7 @@ func (b *NodeBuilderImpl) getPropertyNameNodeForSymbol(symbol *ast.Symbol) *ast.
21332145 name = "__#private" + name
21342146 }
21352147
2136- return b .createPropertyNameNodeForIdentifierOrLiteral (name , singleQuote , stringNamed , isMethod )
2148+ return b .createPropertyNameNodeForIdentifierOrLiteral (name , singleQuote , stringNamed , isMethod , symbol )
21372149}
21382150
21392151// See getNameForSymbolFromNameType for a stringy equivalent
@@ -2160,7 +2172,7 @@ func (b *NodeBuilderImpl) getPropertyNameNodeForSymbolFromNameType(symbol *ast.S
21602172 if isNumericLiteralName (name ) && name [0 ] == '-' {
21612173 return b .f .NewComputedPropertyName (b .f .NewPrefixUnaryExpression (ast .KindMinusToken , b .f .NewNumericLiteral (name [1 :], ast .TokenFlagsNone )))
21622174 }
2163- return b .createPropertyNameNodeForIdentifierOrLiteral (name , singleQuote , stringNamed , isMethod )
2175+ return b .createPropertyNameNodeForIdentifierOrLiteral (name , singleQuote , stringNamed , isMethod , symbol )
21642176 }
21652177 if nameType .flags & TypeFlagsUniqueESSymbol != 0 {
21662178 return b .f .NewComputedPropertyName (b .symbolToExpression (nameType .AsUniqueESSymbolType ().symbol , ast .SymbolFlagsValue ))
@@ -2596,7 +2608,10 @@ func (b *NodeBuilderImpl) typeReferenceToTypeNode(t *Type) *ast.TypeNode {
25962608 if t .Target () == b .ch .globalArrayType || t .Target () == b .ch .globalReadonlyArrayType {
25972609 if b .ctx .flags & nodebuilder .FlagsWriteArrayAsGenericType != 0 {
25982610 typeArgumentNode := b .typeToTypeNode (typeArguments [0 ])
2599- return b .f .NewTypeReferenceNode (b .f .NewIdentifier (core .IfElse (t .Target () == b .ch .globalArrayType , "Array" , "ReadonlyArray" )), b .f .NewNodeList ([]* ast.TypeNode {typeArgumentNode }))
2611+ return b .f .NewTypeReferenceNode (
2612+ b .newIdentifier (core .IfElse (t .Target () == b .ch .globalArrayType , "Array" , "ReadonlyArray" ), t .Target ().symbol ),
2613+ b .f .NewNodeList ([]* ast.TypeNode {typeArgumentNode }),
2614+ )
26002615 }
26012616 elementType := b .typeToTypeNode (typeArguments [0 ])
26022617 arrayType := b .f .NewArrayTypeNode (elementType )
@@ -2622,7 +2637,12 @@ func (b *NodeBuilderImpl) typeReferenceToTypeNode(t *Type) *ast.TypeNode {
26222637 labeledElementDeclaration := t .Target ().AsTupleType ().elementInfos [i ].labeledDeclaration
26232638
26242639 if labeledElementDeclaration != nil {
2625- tupleConstituentNodes .Nodes [i ] = b .f .NewNamedTupleMember (core .IfElse (flags & ElementFlagsVariable != 0 , b .f .NewToken (ast .KindDotDotDotToken ), nil ), b .f .NewIdentifier (b .ch .getTupleElementLabel (t .Target ().AsTupleType ().elementInfos [i ], nil , i )), core .IfElse (flags & ElementFlagsOptional != 0 , b .f .NewToken (ast .KindQuestionToken ), nil ), core .IfElse (flags & ElementFlagsRest != 0 , b .f .NewArrayTypeNode (tupleConstituentNodes .Nodes [i ]), tupleConstituentNodes .Nodes [i ]))
2640+ tupleConstituentNodes .Nodes [i ] = b .f .NewNamedTupleMember (
2641+ core .IfElse (flags & ElementFlagsVariable != 0 , b .f .NewToken (ast .KindDotDotDotToken ), nil ),
2642+ b .newIdentifier (b .ch .getTupleElementLabel (t .Target ().AsTupleType ().elementInfos [i ], nil , i ), nil /*symbol*/ ),
2643+ core .IfElse (flags & ElementFlagsOptional != 0 , b .f .NewToken (ast .KindQuestionToken ), nil ),
2644+ core .IfElse (flags & ElementFlagsRest != 0 , b .f .NewArrayTypeNode (tupleConstituentNodes .Nodes [i ]), tupleConstituentNodes .Nodes [i ]),
2645+ )
26262646 } else {
26272647 switch {
26282648 case flags & ElementFlagsVariable != 0 :
@@ -2997,7 +3017,7 @@ func (b *NodeBuilderImpl) typeToTypeNode(t *Type) *ast.TypeNode {
29973017 if b .ctx .flags & nodebuilder .FlagsGenerateNamesForShadowedTypeParams != 0 && t .flags & TypeFlagsTypeParameter != 0 {
29983018 name := b .typeParameterToName (t )
29993019 b .ctx .approximateLength += len (name .Text )
3000- return b .f .NewTypeReferenceNode (b .f . NewIdentifier (name .Text ), nil /*typeArguments*/ )
3020+ return b .f .NewTypeReferenceNode (b .newIdentifier (name .Text , t . symbol ), nil /*typeArguments*/ )
30013021 }
30023022 // Ignore constraint/default when creating a usage (as opposed to declaration) of a type parameter.
30033023 if t .symbol != nil {
@@ -3009,7 +3029,7 @@ func (b *NodeBuilderImpl) typeToTypeNode(t *Type) *ast.TypeNode {
30093029 } else {
30103030 name = "?"
30113031 }
3012- return b .f .NewTypeReferenceNode (b .f . NewIdentifier (name ), nil /*typeArguments*/ )
3032+ return b .f .NewTypeReferenceNode (b .newIdentifier (name , nil /*symbol*/ ), nil /*typeArguments*/ )
30133033 }
30143034 if t .flags & TypeFlagsUnion != 0 && t .AsUnionType ().origin != nil {
30153035 t = t .AsUnionType ().origin
@@ -3113,3 +3133,11 @@ func (b *NodeBuilderImpl) newStringLiteralEx(text string, isSingleQuote bool) *a
31133133func (t * TypeAlias ) ToTypeReferenceNode (b * NodeBuilderImpl ) * ast.Node {
31143134 return b .f .NewTypeReferenceNode (b .symbolToEntityNameNode (t .Symbol ()), b .mapToTypeNodes (t .TypeArguments (), false /*isBareList*/ ))
31153135}
3136+
3137+ func (b * NodeBuilderImpl ) newIdentifier (text string , symbol * ast.Symbol ) * ast.Node {
3138+ id := b .f .NewIdentifier (text )
3139+ if symbol != nil {
3140+ b .idToSymbol [id ] = symbol
3141+ }
3142+ return id
3143+ }
0 commit comments