Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions internal/checker/emitresolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -1078,6 +1078,19 @@ func (r *emitResolver) CreateLateBoundIndexSignatures(emitContext *printer.EmitC
return result
}

func (r *emitResolver) TrackExistingEntityName(emitContext *printer.EmitContext, node *ast.Node, enclosingDeclaration *ast.Node, flags nodebuilder.Flags, internalFlags nodebuilder.InternalFlags, tracker nodebuilder.SymbolTracker) *ast.Node {
original := emitContext.ParseNode(node)
if original == nil {
return node
}

r.checkerMu.Lock()
defer r.checkerMu.Unlock()

requestNodeBuilder := NewNodeBuilder(r.checker, emitContext) // TODO: cache per-context
return requestNodeBuilder.TrackExistingEntityName(original, enclosingDeclaration, flags, internalFlags, tracker)
}

func (r *emitResolver) GetEffectiveDeclarationFlags(node *ast.Node, flags ast.ModifierFlags) ast.ModifierFlags {
// node = emitContext.ParseNode(node)
r.checkerMu.Lock()
Expand Down
6 changes: 6 additions & 0 deletions internal/checker/nodebuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,12 @@ func (b *NodeBuilder) TypeParameterToDeclaration(parameter *Type, enclosingDecla
return b.exitContext(b.impl.typeParameterToDeclaration(parameter))
}

// TrackExistingEntityName tracks an existing entity name and returns a potentially renamed version.
func (b *NodeBuilder) TrackExistingEntityName(node *ast.Node, enclosingDeclaration *ast.Node, flags nodebuilder.Flags, internalFlags nodebuilder.InternalFlags, tracker nodebuilder.SymbolTracker) *ast.Node {
b.enterContext(enclosingDeclaration, flags, internalFlags, tracker)
return b.exitContext(b.impl.trackExistingEntityName(node))
}

// TypePredicateToTypePredicateNode implements NodeBuilderInterface.
func (b *NodeBuilder) TypePredicateToTypePredicateNode(predicate *TypePredicate, enclosingDeclaration *ast.Node, flags nodebuilder.Flags, internalFlags nodebuilder.InternalFlags, tracker nodebuilder.SymbolTracker) *ast.Node {
b.enterContext(enclosingDeclaration, flags, internalFlags, tracker)
Expand Down
23 changes: 23 additions & 0 deletions internal/checker/nodebuilderimpl.go
Original file line number Diff line number Diff line change
Expand Up @@ -1346,6 +1346,29 @@ func (b *nodeBuilderImpl) typeParameterToName(typeParameter *Type) *ast.Identifi
return result.AsIdentifier()
}

func (b *nodeBuilderImpl) trackExistingEntityName(node *ast.Node) *ast.Node {
if node == nil || !ast.IsIdentifier(node) {
return node
}

// Get the symbol for this identifier
symbol := b.ch.getSymbolOfNode(node)
if symbol == nil {
return node
}

// If it's a type parameter, use typeParameterToName to get a potentially renamed version
if symbol.Flags&ast.SymbolFlagsTypeParameter != 0 {
typeParam := b.ch.getDeclaredTypeOfSymbol(symbol)
if typeParam != nil {
return b.typeParameterToName(typeParam).AsNode()
}
}

// For non-type-parameter identifiers, return a clone
return node.Clone(b.f)
}

func (b *nodeBuilderImpl) isMappedTypeHomomorphic(mapped *Type) bool {
return b.ch.getHomomorphicTypeVariable(mapped) != nil
}
Expand Down
1 change: 1 addition & 0 deletions internal/printer/emitresolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,5 @@ type EmitResolver interface {
CreateLiteralConstValue(emitContext *EmitContext, node *ast.Node, tracker nodebuilder.SymbolTracker) *ast.Node
CreateTypeOfExpression(emitContext *EmitContext, expression *ast.Node, enclosingDeclaration *ast.Node, flags nodebuilder.Flags, internalFlags nodebuilder.InternalFlags, tracker nodebuilder.SymbolTracker) *ast.Node
CreateLateBoundIndexSignatures(emitContext *EmitContext, container *ast.Node, enclosingDeclaration *ast.Node, flags nodebuilder.Flags, internalFlags nodebuilder.InternalFlags, tracker nodebuilder.SymbolTracker) []*ast.Node
TrackExistingEntityName(emitContext *EmitContext, node *ast.Node, enclosingDeclaration *ast.Node, flags nodebuilder.Flags, internalFlags nodebuilder.InternalFlags, tracker nodebuilder.SymbolTracker) *ast.Node
}
27 changes: 25 additions & 2 deletions internal/transformers/declarations/transform.go
Original file line number Diff line number Diff line change
Expand Up @@ -634,16 +634,39 @@ func (tx *DeclarationTransformer) transformExpressionWithTypeArguments(input *as
}

func (tx *DeclarationTransformer) transformTypeParameterDeclaration(input *ast.TypeParameterDeclaration) *ast.Node {
// Track the type parameter name to handle shadowing
tpName := tx.resolver.TrackExistingEntityName(
tx.EmitContext(),
input.Name(),
tx.enclosingDeclaration,
declarationEmitNodeBuilderFlags,
declarationEmitInternalNodeBuilderFlags,
tx.tracker,
)

if isPrivateMethodTypeParameter(tx.host, input) && (input.DefaultType != nil || input.Constraint != nil) {
return tx.Factory().UpdateTypeParameterDeclaration(
input,
input.Modifiers(),
input.Name(),
tpName,
nil,
nil,
)
}
return tx.Visitor().VisitEachChild(input.AsNode())

// Visit children to transform constraint and default type
modifiers := tx.Visitor().VisitModifiers(input.Modifiers())
constraint := tx.Visitor().VisitNode(input.Constraint)
defaultType := tx.Visitor().VisitNode(input.DefaultType)

// Update the type parameter declaration with the potentially renamed name
return tx.Factory().UpdateTypeParameterDeclaration(
input,
modifiers,
tpName,
constraint,
defaultType,
)
}

func (tx *DeclarationTransformer) transformVariableDeclaration(input *ast.VariableDeclaration) *ast.Node {
Expand Down