Skip to content
Open
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
10 changes: 2 additions & 8 deletions tsc/internal/checker/checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -884,8 +884,6 @@ type Checker struct {
isStringIndexSignatureOnlyType func(*Type) bool
markNodeAssignments func(*ast.Node) bool
compareTypesAssignable TypeComparer
emitResolver *EmitResolver
emitResolverOnce sync.Once
_jsxNamespace string
_jsxFactoryEntity *ast.Node
skipDirectInferenceNodes collections.Set[*ast.Node]
Expand Down Expand Up @@ -32285,12 +32283,8 @@ func (c *Checker) GetTypeAtLocation(node *ast.Node) *Type {
return c.getTypeOfNode(ast.GetReparsedNodeForNode(node))
}

func (c *Checker) GetEmitResolver() *EmitResolver {
c.emitResolverOnce.Do(func() {
c.emitResolver = newEmitResolver(c)
})

return c.emitResolver
func (c *Checker) NewEmitResolver() *EmitResolver {
return newEmitResolver(c)
}

func (c *Checker) GetAliasedSymbol(symbol *ast.Symbol) *ast.Symbol {
Expand Down
16 changes: 8 additions & 8 deletions tsc/internal/checker/emitresolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,7 @@ func (r *EmitResolver) IsExpandoFunctionDeclaration(node *ast.Node) bool {
}

func (r *EmitResolver) isSymbolAccessible(symbol *ast.Symbol, enclosingDeclaration *ast.Node, meaning ast.SymbolFlags, shouldComputeAliasToMarkVisible bool) printer.SymbolAccessibilityResult {
return r.checker.IsSymbolAccessible(symbol, enclosingDeclaration, meaning, shouldComputeAliasToMarkVisible)
return r.checker.isSymbolAccessibleWorkerWithResolver(symbol, enclosingDeclaration, meaning, shouldComputeAliasToMarkVisible, true /*allowModules*/, r)
}

func (r *EmitResolver) IsSymbolAccessible(symbol *ast.Symbol, enclosingDeclaration *ast.Node, meaning ast.SymbolFlags, shouldComputeAliasToMarkVisible bool) printer.SymbolAccessibilityResult {
Expand Down Expand Up @@ -955,7 +955,7 @@ func (r *EmitResolver) CreateReturnTypeOfSignatureDeclaration(emitContext *print

r.checkerMu.Lock()
defer r.checkerMu.Unlock()
requestNodeBuilder := NewNodeBuilder(r.checker, emitContext) // TODO: cache per-context
requestNodeBuilder := newNodeBuilder(r.checker, emitContext, r) // TODO: cache per-context
return requestNodeBuilder.SerializeReturnTypeForSignature(original, enclosingDeclaration, flags, internalFlags, tracker)
}

Expand All @@ -967,7 +967,7 @@ func (r *EmitResolver) CreateTypeParametersOfSignatureDeclaration(emitContext *p

r.checkerMu.Lock()
defer r.checkerMu.Unlock()
requestNodeBuilder := NewNodeBuilder(r.checker, emitContext) // TODO: cache per-context
requestNodeBuilder := newNodeBuilder(r.checker, emitContext, r) // TODO: cache per-context
return requestNodeBuilder.SerializeTypeParametersForSignature(original, enclosingDeclaration, flags, internalFlags, tracker)
}

Expand All @@ -979,7 +979,7 @@ func (r *EmitResolver) CreateTypeOfDeclaration(emitContext *printer.EmitContext,

r.checkerMu.Lock()
defer r.checkerMu.Unlock()
requestNodeBuilder := NewNodeBuilder(r.checker, emitContext) // TODO: cache per-context
requestNodeBuilder := newNodeBuilder(r.checker, emitContext, r) // TODO: cache per-context
// // Get type of the symbol if this is the valid symbol otherwise get type at location
symbol := r.checker.getSymbolOfDeclaration(declaration)
return requestNodeBuilder.SerializeTypeForDeclaration(declaration, symbol, enclosingDeclaration, flags|nodebuilder.FlagsMultilineObjectLiterals, internalFlags, tracker)
Expand All @@ -998,7 +998,7 @@ func (r *EmitResolver) CreateLiteralConstValue(emitContext *printer.EmitContext,
if t.flags&TypeFlagsEnumLike != 0 {
r.checkerMu.Lock()
defer r.checkerMu.Unlock()
requestNodeBuilder := NewNodeBuilder(r.checker, emitContext) // TODO: cache per-context
requestNodeBuilder := newNodeBuilder(r.checker, emitContext, r) // TODO: cache per-context
enumResult = requestNodeBuilder.SymbolToExpression(t.symbol, ast.SymbolFlagsValue, node, nodebuilder.FlagsNone, nodebuilder.InternalFlagsNone, tracker)
// What about regularTrueType/regularFalseType - since those aren't fresh, we never make initializers from them
// TODO: handle those if this function is ever used for more than initializers in declaration emit
Expand Down Expand Up @@ -1054,7 +1054,7 @@ func (r *EmitResolver) CreateTypeOfExpression(emitContext *printer.EmitContext,

r.checkerMu.Lock()
defer r.checkerMu.Unlock()
requestNodeBuilder := NewNodeBuilder(r.checker, emitContext) // TODO: cache per-context
requestNodeBuilder := newNodeBuilder(r.checker, emitContext, r) // TODO: cache per-context
return requestNodeBuilder.SerializeTypeForExpression(expression, enclosingDeclaration, flags|nodebuilder.FlagsMultilineObjectLiterals, internalFlags, tracker)
}

Expand All @@ -1072,7 +1072,7 @@ func (r *EmitResolver) CreateLateBoundIndexSignatures(emitContext *printer.EmitC
instanceInfos = r.checker.getIndexInfosOfIndexSymbol(instanceIndexSymbol, siblingSymbols)
}

requestNodeBuilder := NewNodeBuilder(r.checker, emitContext) // TODO: cache per-context
requestNodeBuilder := newNodeBuilder(r.checker, emitContext, r) // TODO: cache per-context

var result []*ast.Node
for i, infoList := range [][]*IndexInfo{staticInfos, instanceInfos} {
Expand Down Expand Up @@ -1281,7 +1281,7 @@ func (r *EmitResolver) TryJSTypeNodeToTypeNode(emitContext *printer.EmitContext,
r.checkerMu.Lock()
defer r.checkerMu.Unlock()

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

Expand Down
2 changes: 1 addition & 1 deletion tsc/internal/checker/exports.go
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ func (c *Checker) RequiresAddingImplicitUndefined(node *ast.Node) bool {
if symbol == nil {
return false
}
return c.GetEmitResolver().RequiresAddingImplicitUndefined(node, symbol, enclosingDeclaration)
return c.NewEmitResolver().RequiresAddingImplicitUndefined(node, symbol, enclosingDeclaration)
}

func (c *Checker) RemoveMissingOrUndefinedType(t *Type) *Type {
Expand Down
10 changes: 9 additions & 1 deletion tsc/internal/checker/nodebuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,15 @@ func NewNodeBuilder(ch *Checker, e *printer.EmitContext) *NodeBuilder {
}

func NewNodeBuilderEx(ch *Checker, e *printer.EmitContext, idToSymbol map[*ast.IdentifierNode]*ast.Symbol) *NodeBuilder {
impl := newNodeBuilderImpl(ch, e, idToSymbol)
return newNodeBuilderEx(ch, e, idToSymbol, ch.NewEmitResolver())
}

func newNodeBuilder(ch *Checker, e *printer.EmitContext, emitResolver *EmitResolver) *NodeBuilder {
return newNodeBuilderEx(ch, e, nil /*idToSymbol*/, emitResolver)
}

func newNodeBuilderEx(ch *Checker, e *printer.EmitContext, idToSymbol map[*ast.IdentifierNode]*ast.Symbol, emitResolver *EmitResolver) *NodeBuilder {
impl := newNodeBuilderImpl(ch, e, idToSymbol, emitResolver)
return &NodeBuilder{impl: impl, ctxStack: make([]*NodeBuilderContext, 0, 1), host: ch.program}
}

Expand Down
29 changes: 17 additions & 12 deletions tsc/internal/checker/nodebuilderimpl.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ type NodeBuilderImpl struct {
symbolLinks core.LinkStore[*ast.Symbol, NodeBuilderSymbolLinks]

// state
ctx *NodeBuilderContext
ctx *NodeBuilderContext
emitResolver *EmitResolver

// reusable visitor
cloneBindingNameVisitor *ast.NodeVisitor
Expand All @@ -116,15 +117,19 @@ const (

// Node builder utility functions

func newNodeBuilderImpl(ch *Checker, e *printer.EmitContext, idToSymbol map[*ast.IdentifierNode]*ast.Symbol) *NodeBuilderImpl {
func newNodeBuilderImpl(ch *Checker, e *printer.EmitContext, idToSymbol map[*ast.IdentifierNode]*ast.Symbol, emitResolver *EmitResolver) *NodeBuilderImpl {
if idToSymbol == nil {
idToSymbol = make(map[*ast.IdentifierNode]*ast.Symbol)
}
b := &NodeBuilderImpl{f: e.Factory.AsNodeFactory(), ch: ch, e: e, idToSymbol: idToSymbol, pc: pseudochecker.NewPseudoChecker(ch.strictNullChecks, ch.exactOptionalPropertyTypes)}
b := &NodeBuilderImpl{f: e.Factory.AsNodeFactory(), ch: ch, e: e, idToSymbol: idToSymbol, pc: pseudochecker.NewPseudoChecker(ch.strictNullChecks, ch.exactOptionalPropertyTypes), emitResolver: emitResolver}
b.cloneBindingNameVisitor = ast.NewNodeVisitor(b.cloneBindingName, b.f, ast.NodeVisitorHooks{})
return b
}

func (b *NodeBuilderImpl) isSymbolAccessible(symbol *ast.Symbol, enclosingDeclaration *ast.Node, meaning ast.SymbolFlags, allowModules bool) bool {
return b.ch.isSymbolAccessibleWorkerWithResolver(symbol, enclosingDeclaration, meaning, false /*shouldComputeAliasesToMakeVisible*/, allowModules, b.emitResolver).Accessibility == printer.SymbolAccessibilityAccessible
}

func (b *NodeBuilderImpl) saveRestoreFlags() func() {
flags := b.ctx.flags
internalFlags := b.ctx.internalFlags
Expand Down Expand Up @@ -448,7 +453,7 @@ func (b *NodeBuilderImpl) serializeTypeName(node *ast.Node, isTypeOf bool, typeA
resolvedSymbol = b.ch.resolveAlias(symbol)
}

if b.ch.IsSymbolAccessible(symbol, b.ctx.enclosingDeclaration, meaning, false).Accessibility != printer.SymbolAccessibilityAccessible {
if !b.isSymbolAccessible(symbol, b.ctx.enclosingDeclaration, meaning, true /*allowModules*/) {
return nil
}
return b.symbolToTypeNode(resolvedSymbol, meaning, typeArguments)
Expand Down Expand Up @@ -2081,7 +2086,7 @@ func (b *NodeBuilderImpl) isTriviallySerializableComputedName(e *ast.Node) bool
return false
}
// TODO: going through emit resolver here is weird. Relayer these APIs.
return b.ch.GetEmitResolver().isEntityNameVisible(e.Name().Expression(), b.ctx.enclosingDeclaration, false).Accessibility == printer.SymbolAccessibilityAccessible
return b.emitResolver.isEntityNameVisible(e.Name().Expression(), b.ctx.enclosingDeclaration, false).Accessibility == printer.SymbolAccessibilityAccessible
}

func (b *NodeBuilderImpl) indexInfoToObjectComputedNamesOrSignatureDeclaration(indexInfo *IndexInfo, typeNode *ast.TypeNode) []*ast.Node {
Expand Down Expand Up @@ -2213,7 +2218,7 @@ func (b *NodeBuilderImpl) serializeTypeForDeclaration(declaration *ast.Declarati
}

// !!! TODO: JSDoc, getEmitResolver call is unfortunate layering for the helper - hoist it into checker
requiresAddingUndefined := declaration != nil && (ast.IsParameterDeclaration(declaration) || ast.IsPropertySignatureDeclaration(declaration) || ast.IsPropertyDeclaration(declaration)) && b.ch.GetEmitResolver().requiresAddingImplicitUndefined(declaration, symbol, b.ctx.enclosingDeclaration)
requiresAddingUndefined := declaration != nil && (ast.IsParameterDeclaration(declaration) || ast.IsPropertySignatureDeclaration(declaration) || ast.IsPropertyDeclaration(declaration)) && b.emitResolver.requiresAddingImplicitUndefined(declaration, symbol, b.ctx.enclosingDeclaration)
addUndefinedForParameter := requiresAddingUndefined && (ast.IsParameterDeclaration(declaration) /*|| ast.IsJSDocParameterTag(declaration)*/)
if addUndefinedForParameter {
t = b.ch.getOptionalType(t, false)
Expand Down Expand Up @@ -2470,7 +2475,7 @@ func (b *NodeBuilderImpl) getPropertyNameNodeForSymbolFromNameType(symbol *ast.S
enumSymbol = nameType.symbol
}
if enumEnclosingDeclaration != nil &&
b.ch.IsSymbolAccessibleByFlags(enumSymbol, enumEnclosingDeclaration, ast.SymbolFlagsValue) {
b.isSymbolAccessible(enumSymbol, enumEnclosingDeclaration, ast.SymbolFlagsValue, false /*allowModules*/) {
saveEnclosingDeclaration := b.ctx.enclosingDeclaration
b.ctx.enclosingDeclaration = enumEnclosingDeclaration
result := b.f.NewComputedPropertyName(b.symbolToExpression(nameType.symbol, ast.SymbolFlagsValue))
Expand Down Expand Up @@ -2807,7 +2812,7 @@ func (b *NodeBuilderImpl) shouldWriteTypeOfFunctionSymbol(symbol *ast.Symbol, ty
}
// typeof is allowed only for static/non local functions
return (b.ctx.flags&nodebuilder.FlagsUseTypeOfFunction != 0 || b.ctx.visitedTypes.Has(typeId)) && // it is type of the symbol uses itself recursively
(b.ctx.flags&nodebuilder.FlagsUseStructuralFallback == 0 || b.ch.IsValueSymbolAccessible(symbol, b.ctx.enclosingDeclaration)), symbol // And the build is going to succeed without visibility error or there is no structural fallback allowed
(b.ctx.flags&nodebuilder.FlagsUseStructuralFallback == 0 || b.isSymbolAccessible(symbol, b.ctx.enclosingDeclaration, ast.SymbolFlagsValue, true /*allowModules*/)), symbol // And the build is going to succeed without visibility error or there is no structural fallback allowed
}
return false, symbol
}
Expand All @@ -2820,7 +2825,7 @@ func (b *NodeBuilderImpl) shouldEmitTypeOfSymbol(forceExpansion bool, forceClass
if forceExpansion {
return false, symbol
}
nonFunctionResult := symbol.Flags&ast.SymbolFlagsClass != 0 && !forceClassExpansion && b.ch.getBaseTypeVariableOfClass(symbol) == nil && !(symbol.ValueDeclaration != nil && ast.IsClassLike(symbol.ValueDeclaration) && b.ctx.flags&nodebuilder.FlagsWriteClassExpressionAsTypeLiteral != 0 && (!ast.IsClassDeclaration(symbol.ValueDeclaration) || b.ch.IsSymbolAccessible(symbol, b.ctx.enclosingDeclaration, isInstanceType, false /*shouldComputeAliasesToMakeVisible*/).Accessibility != printer.SymbolAccessibilityAccessible)) || symbol.Flags&(ast.SymbolFlagsEnum|ast.SymbolFlagsValueModule) != 0
nonFunctionResult := symbol.Flags&ast.SymbolFlagsClass != 0 && !forceClassExpansion && b.ch.getBaseTypeVariableOfClass(symbol) == nil && !(symbol.ValueDeclaration != nil && ast.IsClassLike(symbol.ValueDeclaration) && b.ctx.flags&nodebuilder.FlagsWriteClassExpressionAsTypeLiteral != 0 && (!ast.IsClassDeclaration(symbol.ValueDeclaration) || !b.isSymbolAccessible(symbol, b.ctx.enclosingDeclaration, isInstanceType, true /*allowModules*/))) || symbol.Flags&(ast.SymbolFlagsEnum|ast.SymbolFlagsValueModule) != 0
if nonFunctionResult {
return true, symbol
}
Expand Down Expand Up @@ -3062,7 +3067,7 @@ func (b *NodeBuilderImpl) typeReferenceToTypeNode(t *Type) *ast.TypeNode {
b.ctx.encounteredError = true
return nil
// TODO: GH#18217
} else if b.ctx.flags&nodebuilder.FlagsWriteClassExpressionAsTypeLiteral != 0 && t.symbol.ValueDeclaration != nil && ast.IsClassLike(t.symbol.ValueDeclaration) && !b.ch.IsValueSymbolAccessible(t.symbol, b.ctx.enclosingDeclaration) {
} else if b.ctx.flags&nodebuilder.FlagsWriteClassExpressionAsTypeLiteral != 0 && t.symbol.ValueDeclaration != nil && ast.IsClassLike(t.symbol.ValueDeclaration) && !b.isSymbolAccessible(t.symbol, b.ctx.enclosingDeclaration, ast.SymbolFlagsValue, true /*allowModules*/) {
return b.createAnonymousTypeNode(t)
} else {
outerTypeParameters := t.Target().AsInterfaceType().OuterTypeParameters()
Expand Down Expand Up @@ -3333,7 +3338,7 @@ func (b *NodeBuilderImpl) typeToTypeNode(t *Type) *ast.TypeNode {
}
if t.flags&TypeFlagsUniqueESSymbol != 0 {
if b.ctx.flags&nodebuilder.FlagsAllowUniqueESSymbolType == 0 {
if b.ch.IsValueSymbolAccessible(t.symbol, b.ctx.enclosingDeclaration) {
if b.isSymbolAccessible(t.symbol, b.ctx.enclosingDeclaration, ast.SymbolFlagsValue, true /*allowModules*/) {
b.ctx.approximateLength += 6
return b.symbolToTypeNode(t.symbol, ast.SymbolFlagsValue, nil)
}
Expand Down Expand Up @@ -3377,7 +3382,7 @@ func (b *NodeBuilderImpl) typeToTypeNode(t *Type) *ast.TypeNode {
return b.f.NewThisTypeNode()
}

if inTypeAlias == 0 && t.alias != nil && (b.ctx.flags&nodebuilder.FlagsUseAliasDefinedOutsideCurrentScope != 0 || b.ch.IsTypeSymbolAccessible(t.alias.Symbol(), b.ctx.enclosingDeclaration)) {
if inTypeAlias == 0 && t.alias != nil && (b.ctx.flags&nodebuilder.FlagsUseAliasDefinedOutsideCurrentScope != 0 || b.isSymbolAccessible(t.alias.Symbol(), b.ctx.enclosingDeclaration, ast.SymbolFlagsType, true /*allowModules*/)) {
// If we should expand this type alias, skip the alias and fall through to expand the underlying type
if !b.shouldExpandType(t, true /*isAlias*/) {
sym := t.alias.Symbol()
Expand Down
6 changes: 3 additions & 3 deletions tsc/internal/checker/nodecopy.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ func (b *NodeBuilderImpl) getModuleSpecifierOverride(parent *ast.Node, lit *ast.
meaning = ast.SymbolFlagsValue
}
var parentSymbol *ast.Symbol
if nodeSymbol != nil && b.ch.IsSymbolAccessible(nodeSymbol, b.ctx.enclosingDeclaration, meaning, false).Accessibility == printer.SymbolAccessibilityAccessible {
if nodeSymbol != nil && b.isSymbolAccessible(nodeSymbol, b.ctx.enclosingDeclaration, meaning, true /*allowModules*/) {
parentSymbol = b.lookupSymbolChain(nodeSymbol, meaning, true)[0]
}
if parentSymbol != nil && IsExternalModuleSymbol(parentSymbol) {
Expand Down Expand Up @@ -330,7 +330,7 @@ func getExistingNodeTreeVisitor(b *NodeBuilderImpl, bound *recoveryBoundary) *as
if ast.IsThisIdentifier(leftmost) {
// `this` isn't a bindable identifier - skip resolution, find a relevant `this` symbol directly and avoid exhaustive scope traversal
sym = b.ch.getSymbolOfDeclaration(b.ch.getThisContainer(leftmost, false, false))
if b.ch.IsSymbolAccessible(sym, leftmost, meaning, false).Accessibility != printer.SymbolAccessibilityAccessible {
if !b.isSymbolAccessible(sym, leftmost, meaning, true /*allowModules*/) {
introducesError = true
b.ctx.tracker.ReportInaccessibleThisError()
}
Expand Down Expand Up @@ -371,7 +371,7 @@ func getExistingNodeTreeVisitor(b *NodeBuilderImpl, bound *recoveryBoundary) *as
}
}
if sym.Flags&ast.SymbolFlagsTypeParameter == 0 /* Type parameters are visible in the current context if they are are resolvable */ && !ast.IsDeclarationName(node) &&
b.ch.IsSymbolAccessible(sym, enclosingDeclaration, meaning, false).Accessibility != printer.SymbolAccessibilityAccessible {
!b.isSymbolAccessible(sym, enclosingDeclaration, meaning, true /*allowModules*/) {
b.ctx.tracker.ReportInferenceFallback(node)
introducesError = true
} else {
Expand Down
Loading
Loading