Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
6f8b70e
Wire up type printing to use node builder, port most type printback l…
weswigham Feb 11, 2025
5190004
Pull in a chunk of declaration emit integrations from older work
weswigham Apr 16, 2025
3dac2d2
Last half of the declaration transform and emit resolver, bar !!!d fe…
weswigham Apr 18, 2025
b1c7164
Add missing name check, fix some NPEs, swap symbolToString from stub …
weswigham Apr 18, 2025
10500fd
Port old, inefficient symbol accesibility checking methods
weswigham Apr 18, 2025
76528fa
Nodebuilder symbol chain lookup logic & symbol manufacturing logic, s…
weswigham Apr 21, 2025
b60f514
Last of the core norebuilder functionality
weswigham Apr 22, 2025
c92cf8e
Fix inverted typeof usage condition
weswigham Apr 22, 2025
bcf20a7
Add some missing map initialization checks
weswigham Apr 22, 2025
99c5b27
Bugfixes aplenty
weswigham Apr 22, 2025
2050781
Fix all the panics and deadlocks exposed by the test suite, implement…
weswigham Apr 23, 2025
1d83436
Fix whitespace differentials, type arg list printback in diags, overl…
weswigham Apr 23, 2025
1e5b5a5
Fix declaration emit for const refs to enums
weswigham Apr 23, 2025
6fc5379
Use more strada-accurate baseline type printing to correct unique sym…
weswigham Apr 23, 2025
867d830
Fix some symbol chain printback issues
weswigham Apr 23, 2025
c9ec9c4
Replacement for collectLinkedAliases thats noCheck compatible by default
weswigham Apr 24, 2025
eebc5da
Partial specifier generation implementation, still missing the meat a…
weswigham Apr 26, 2025
d744420
specifier generation basically completely ported, sans host functiona…
weswigham Apr 26, 2025
30ffd41
Implement/stub missing emithost functionality for specifier generation
weswigham Apr 26, 2025
99c1066
set Checker Host member, is now minimally a ModuleSpecifierGeneration…
weswigham Apr 26, 2025
2d566b1
namespace keyword over module in declaration emit, fix double indent …
weswigham Apr 28, 2025
f0bb1cc
Merge branch 'main' into nodebuilder
weswigham Apr 28, 2025
d6972ae
Remove vestigial parameter modifier masking, elide empty heritage cla…
weswigham Apr 28, 2025
7f79751
Enable declaration maps
weswigham Apr 28, 2025
443938a
Collect and sort results of export table traversals throughout symbol…
weswigham May 1, 2025
79deafd
Merge branch 'main' into nodebuilder
weswigham May 1, 2025
78adb94
Apparently go fmt and dprint differ in how they format comments!
weswigham May 1, 2025
7f9051e
Stop triple-negating negative numeric literals
weswigham May 1, 2025
6a3e11c
Fix some discrepencies and make error.txt baselines include declarati…
weswigham May 1, 2025
f5f299b
Add missing default typeformatflags to typeToString
weswigham May 1, 2025
c44123b
Fix mapped type +-
weswigham May 1, 2025
5660f03
Add missing EFNoAsciiEscaping flag on string literal type printback
weswigham May 1, 2025
ffa0b5c
Fix transposition of token
weswigham May 1, 2025
bc86f35
Add JS support to declaration transformer (currently untested in base…
weswigham May 1, 2025
e16f105
Merge branch 'main' into nodebuilder
weswigham May 5, 2025
c66110f
Merge branch 'main' into nodebuilder
weswigham May 15, 2025
2698d45
Requested specifier generation refactor
weswigham May 15, 2025
7d7c6d5
Review feedback round one
weswigham May 15, 2025
2555e62
Fix panic from JS changes
weswigham May 15, 2025
9b7d234
Actually remove the new-dead code
weswigham May 15, 2025
20b3740
Merge branch 'main' into nodebuilder
weswigham May 19, 2025
168d6e3
PR feedback
weswigham May 19, 2025
170fd3e
Rename layers as requested
weswigham May 19, 2025
9cdcd5e
Remove another dead func
weswigham May 19, 2025
20e0afd
Remove currently not require nodebuilder interface
weswigham May 20, 2025
f4187e0
Merge branch 'main' into nodebuilder
weswigham May 23, 2025
7cf1bcb
Remove dprint ignores
weswigham May 23, 2025
62d9f86
Port bugfix
weswigham May 23, 2025
3eb30af
Remove zero value inits
weswigham May 23, 2025
a331cae
Remove extra layer of nilability
weswigham May 23, 2025
9add880
Convert to method
weswigham May 23, 2025
c847e89
Move location of declaration emit transform package
weswigham May 23, 2025
160fc5f
Merge branch 'main' into nodebuilder
weswigham May 28, 2025
121309b
Merge branch 'main' into nodebuilder
weswigham May 28, 2025
34874a1
Swap closure name convention
weswigham May 29, 2025
f8c7f17
Move StripQuotes/UnquoteString to stringutil, refine UnquoteString to…
weswigham May 29, 2025
cc13059
Prefer string concat to fmt
weswigham May 29, 2025
301f845
Merge branch 'main' into nodebuilder
weswigham May 29, 2025
8fce47e
Blind accept baselines
weswigham May 29, 2025
d0ecc91
Futz with emitResolver locks
weswigham May 29, 2025
ee871a7
Move emitHost checker access into mutex-locked emitResolver methods
weswigham May 29, 2025
52b0720
One more missing lock
weswigham May 29, 2025
07d86c1
Fix accidentally inverted condition that somehow causes a data race
weswigham May 29, 2025
15580ba
Accept baselines improved by previous fix
weswigham May 29, 2025
bde9d88
I have removed these before, how do they keep sneaking back in?
weswigham May 29, 2025
9fb1ac8
Merge branch 'main' into nodebuilder
weswigham May 29, 2025
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
Prev Previous commit
Next Next commit
Fix whitespace differentials, type arg list printback in diags, overl…
…oad printback
  • Loading branch information
weswigham committed Apr 23, 2025
commit 1d83436a24122f8ff89083e876f5c764e0970474
5 changes: 3 additions & 2 deletions internal/checker/checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -824,6 +824,7 @@ type Checker struct {
markNodeAssignments func(*ast.Node) bool
emitResolver *emitResolver
emitResolverOnce sync.Once
diagnosticConstructionContext *printer.EmitContext
nodeBuilder NodeBuilderInterface
_jsxNamespace string
_jsxFactoryEntity *ast.Node
Expand Down Expand Up @@ -1032,8 +1033,8 @@ func NewChecker(program Program) *Checker {
c.getGlobalClassAccessorDecoratorTargetType = c.getGlobalTypeResolver("ClassAccessorDecoratorTarget", 2 /*arity*/, true /*reportErrors*/)
c.getGlobalClassAccessorDecoratorResultType = c.getGlobalTypeResolver("ClassAccessorDecoratorResult", 2 /*arity*/, true /*reportErrors*/)
c.getGlobalClassFieldDecoratorContextType = c.getGlobalTypeResolver("ClassFieldDecoratorContext", 2 /*arity*/, true /*reportErrors*/)
diagnosticConstructionContext := printer.NewEmitContext()
c.nodeBuilder = NewNodeBuilderAPI(c, diagnosticConstructionContext)
c.diagnosticConstructionContext = printer.NewEmitContext()
c.nodeBuilder = NewNodeBuilderAPI(c, c.diagnosticConstructionContext)
c.initializeClosures()
c.initializeIterationResolvers()
c.initializeChecker()
Expand Down
83 changes: 67 additions & 16 deletions internal/checker/nodebuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ type NodeBuilderContext struct {
typeParameterNames map[TypeId]*ast.Identifier
typeParameterNamesByText map[string]struct{}
typeParameterNamesByTextNextNameCount map[string]int
typeParameterSymbolList map[int]struct{}
typeParameterSymbolList map[ast.SymbolId]struct{}
}

type NodeBuilder struct {
Expand Down Expand Up @@ -375,8 +375,7 @@ func (b *NodeBuilder) symbolToName(symbol *ast.Symbol, meaning ast.SymbolFlags,
}

func (b *NodeBuilder) createEntityNameFromSymbolChain(chain []*ast.Symbol, index int) *ast.Node {
// !!! TODO: smuggle type arguments out
// typeParameterNodes := lookupTypeParameterNodes(chain, index, context);
// typeParameterNodes := b.lookupTypeParameterNodes(chain, index)
symbol := chain[index]

if index == 0 {
Expand Down Expand Up @@ -421,9 +420,12 @@ func (b *NodeBuilder) symbolToTypeNode(symbol *ast.Symbol, mask ast.SymbolFlags,
// module is root, must use `ImportTypeNode`
var nonRootParts *ast.Node
if len(chain) > 1 {
nonRootParts = b.createAccessFromSymbolChain(chain, len(chain)-1, 1)
nonRootParts = b.createAccessFromSymbolChain(chain, len(chain)-1, 1, typeArguments)
}
typeParameterNodes := typeArguments
if typeParameterNodes == nil {
typeParameterNodes = b.lookupTypeParameterNodes(chain, 0)
}
typeParameterNodes := typeArguments /*|| lookupTypeParameterNodes(chain, 0, context);*/ // !!! TODO: type argument smuggling
contextFile := ast.GetSourceFileOfNode(b.e.MostOriginal(b.ctx.enclosingDeclaration)) // TODO: Just use b.ctx.enclosingFile ? Or is the delayed lookup important for context moves?
targetFile := getSourceFileOfModule(chain[0])
var specifier string
Expand Down Expand Up @@ -497,18 +499,19 @@ func (b *NodeBuilder) symbolToTypeNode(symbol *ast.Symbol, mask ast.SymbolFlags,

}

entityName := b.createAccessFromSymbolChain(chain, len(chain)-1, 0)
entityName := b.createAccessFromSymbolChain(chain, len(chain)-1, 0, typeArguments)
if ast.IsIndexedAccessTypeNode(entityName) {
return entityName // Indexed accesses can never be `typeof`
}
if isTypeOf {
return b.f.NewTypeQueryNode(entityName, nil)
}
// !!! TODO: smuggle type arguments out
// Move type arguments from last identifier on chain to type reference
// const lastId = isIdentifier(entityName) ? entityName : entityName.right;
// const lastTypeArgs = getIdentifierTypeArguments(lastId);
// setIdentifierTypeArguments(lastId, /*typeArguments*/ undefined);
return b.f.NewTypeReferenceNode(entityName, nil)
return b.f.NewTypeReferenceNode(entityName, typeArguments)
}

func getTopmostIndexedAccessType(node *ast.IndexedAccessTypeNode) *ast.IndexedAccessTypeNode {
Expand All @@ -518,9 +521,12 @@ func getTopmostIndexedAccessType(node *ast.IndexedAccessTypeNode) *ast.IndexedAc
return node
}

func (b *NodeBuilder) createAccessFromSymbolChain(chain []*ast.Symbol, index int, stopper int) *ast.Node {
func (b *NodeBuilder) createAccessFromSymbolChain(chain []*ast.Symbol, index int, stopper int, overrideTypeArguments *ast.NodeList) *ast.Node {
// !!! TODO: smuggle type arguments out
// const typeParameterNodes = index === (chain.length - 1) ? overrideTypeArguments : lookupTypeParameterNodes(chain, index, context);
typeParameterNodes := overrideTypeArguments
if index != (len(chain) - 1) {
typeParameterNodes = b.lookupTypeParameterNodes(chain, index)
}
symbol := chain[index]
var parent *ast.Symbol
if index > 0 {
Expand Down Expand Up @@ -557,7 +563,7 @@ func (b *NodeBuilder) createAccessFromSymbolChain(chain []*ast.Symbol, index int
}
}
if name != nil && ast.IsComputedPropertyName(name) && ast.IsEntityName(name.AsComputedPropertyName().Expression) {
lhs := b.createAccessFromSymbolChain(chain, index-1, stopper)
lhs := b.createAccessFromSymbolChain(chain, index-1, stopper, overrideTypeArguments)
if ast.IsEntityName(lhs) {
return b.f.NewIndexedAccessTypeNode(
b.f.NewParenthesizedTypeNode(b.f.NewTypeQueryNode(lhs, nil)),
Expand All @@ -573,15 +579,15 @@ func (b *NodeBuilder) createAccessFromSymbolChain(chain []*ast.Symbol, index int
b.ch.getMembersOfSymbol(parent) != nil && b.ch.getMembersOfSymbol(parent)[symbol.Name] != nil &&
b.ch.getSymbolIfSameReference(b.ch.getMembersOfSymbol(parent)[symbol.Name], symbol) != nil {
// Should use an indexed access
lhs := b.createAccessFromSymbolChain(chain, index-1, stopper)
lhs := b.createAccessFromSymbolChain(chain, index-1, stopper, overrideTypeArguments)
if ast.IsIndexedAccessTypeNode(lhs) {
return b.f.NewIndexedAccessTypeNode(
lhs,
b.f.NewLiteralTypeNode(b.f.NewStringLiteral(symbolName)),
)
}
return b.f.NewIndexedAccessTypeNode(
b.f.NewTypeReferenceNode(lhs /*!!! todo: type args*/, nil),
b.f.NewTypeReferenceNode(lhs, typeParameterNodes),
b.f.NewLiteralTypeNode(b.f.NewStringLiteral(symbolName)),
)
}
Expand All @@ -593,7 +599,7 @@ func (b *NodeBuilder) createAccessFromSymbolChain(chain []*ast.Symbol, index int
// identifier.symbol = symbol;

if index > stopper {
lhs := b.createAccessFromSymbolChain(chain, index-1, stopper)
lhs := b.createAccessFromSymbolChain(chain, index-1, stopper, overrideTypeArguments)
if !ast.IsEntityName(lhs) {
panic("Impossible construct - an export of an indexed access cannot be reachable")
}
Expand All @@ -609,7 +615,6 @@ func (b *NodeBuilder) symbolToExpression(symbol *ast.Symbol, mask ast.SymbolFlag
}

func (b *NodeBuilder) createExpressionFromSymbolChain(chain []*ast.Symbol, index int) *ast.Expression {
// !!! TODO: smuggle type arguments out
// typeParameterNodes := b.lookupTypeParameterNodes(chain, index)
symbol := chain[index]

Expand Down Expand Up @@ -801,8 +806,54 @@ func (b *NodeBuilder) getNameOfSymbolAsWritten(symbol *ast.Symbol) string {
return symbol.Name
}

// The full set of type parameters for a generic class or interface type consists of its outer type parameters plus
// its locally declared type parameters.
func (b *NodeBuilder) getTypeParametersOfClassOrInterface(symbol *ast.Symbol) []*Type {
result := make([]*Type, 0)
result = append(result, b.ch.getOuterTypeParametersOfClassOrInterface(symbol)...)
result = append(result, b.ch.getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol)...)
return result
}

func (b *NodeBuilder) lookupTypeParameterNodes(chain []*ast.Symbol, index int) *ast.TypeParameterList {
return nil // !!! TODO: nested reference type parameter synthesis
// Debug.assert(chain && 0 <= index && index < chain.length); // !!!
symbol := chain[index]
symbolId := ast.GetSymbolId(symbol)
if !b.ctx.hasCreatedTypeParameterSymbolList {
b.ctx.hasCreatedTypeParameterSymbolList = true
b.ctx.typeParameterSymbolList = make(map[ast.SymbolId]struct{})
}
_, ok := b.ctx.typeParameterSymbolList[symbolId]
if ok {
return nil
}
b.ctx.typeParameterSymbolList[symbolId] = struct{}{}

if b.ctx.flags&nodebuilder.FlagsWriteTypeParametersInQualifiedName != 0 && index < (len(chain)-1) {
parentSymbol := symbol
nextSymbol := chain[index+1]

if nextSymbol.CheckFlags&ast.CheckFlagsInstantiated != 0 {
targetSymbol := parentSymbol
if parentSymbol.Flags&ast.SymbolFlagsAlias != 0 {
targetSymbol = b.ch.resolveAlias(parentSymbol)
}
params := b.getTypeParametersOfClassOrInterface(targetSymbol)
targetMapper := b.ch.valueSymbolLinks.Get(nextSymbol).mapper
if targetMapper != nil {
params = core.Map(params, targetMapper.Map)
}
return b.mapToTypeNodes(params)
} else {
typeParameterNodes := b.typeParametersToTypeParameterDeclarations(symbol)
if len(typeParameterNodes) > 0 {
return b.f.NewNodeList(typeParameterNodes)
}
return nil
}
}

return nil
}

// TODO: move `lookupSymbolChain` and co to `symbolaccessibility.go` (but getSpecifierForModuleSymbol uses much context which makes that hard?)
Expand Down Expand Up @@ -2203,7 +2254,7 @@ func (b *NodeBuilder) createTypeNodeFromObjectType(t *Type) *ast.TypeNode {
abstractSignatures := core.Filter(ctorSigs, func(signature *Signature) bool {
return signature.flags&SignatureFlagsAbstract != 0
})
if len(callSigs) > 0 {
if len(abstractSignatures) > 0 {
types := core.Map(abstractSignatures, func(s *Signature) *Type {
return b.ch.getOrCreateTypeFromSignature(s, nil)
})
Expand Down
28 changes: 14 additions & 14 deletions internal/checker/printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,22 @@ import (
)

// TODO: Memoize once per checker to retain threadsafety
func createPrinterWithDefaults() *printer.Printer {
return printer.NewPrinter(printer.PrinterOptions{}, printer.PrintHandlers{}, nil)
func createPrinterWithDefaults(emitContext *printer.EmitContext) *printer.Printer {
return printer.NewPrinter(printer.PrinterOptions{}, printer.PrintHandlers{}, emitContext)
}

func createPrinterWithRemoveComments() *printer.Printer {
return printer.NewPrinter(printer.PrinterOptions{RemoveComments: true}, printer.PrintHandlers{}, nil)
func createPrinterWithRemoveComments(emitContext *printer.EmitContext) *printer.Printer {
return printer.NewPrinter(printer.PrinterOptions{RemoveComments: true}, printer.PrintHandlers{}, emitContext)
}

func createPrinterWithRemoveCommentsOmitTrailingSemicolon() *printer.Printer {
func createPrinterWithRemoveCommentsOmitTrailingSemicolon(emitContext *printer.EmitContext) *printer.Printer {
// TODO: OmitTrailingSemicolon support
return printer.NewPrinter(printer.PrinterOptions{RemoveComments: true}, printer.PrintHandlers{}, nil)
return printer.NewPrinter(printer.PrinterOptions{RemoveComments: true}, printer.PrintHandlers{}, emitContext)
}

func createPrinterWithRemoveCommentsNeverAsciiEscape() *printer.Printer {
func createPrinterWithRemoveCommentsNeverAsciiEscape(emitContext *printer.EmitContext) *printer.Printer {
// TODO: NeverAsciiEscape support
return printer.NewPrinter(printer.PrinterOptions{RemoveComments: true}, printer.PrintHandlers{}, nil)
return printer.NewPrinter(printer.PrinterOptions{RemoveComments: true}, printer.PrintHandlers{}, emitContext)
}

func getTrailingSemicolonDeferringWriter(writer printer.EmitTextWriter) printer.EmitTextWriter {
Expand Down Expand Up @@ -60,9 +60,9 @@ func (c *Checker) typeToStringEx(type_ *Type, enclosingDeclaration *ast.Node, fl
// Otherwise, we always strip comments out.
var printer *printer.Printer
if type_ == c.unresolvedType {
printer = createPrinterWithDefaults()
printer = createPrinterWithDefaults(c.diagnosticConstructionContext)
} else {
printer = createPrinterWithRemoveComments()
printer = createPrinterWithRemoveComments(c.diagnosticConstructionContext)
}
var sourceFile *ast.SourceFile
if enclosingDeclaration != nil {
Expand Down Expand Up @@ -126,9 +126,9 @@ func (c *Checker) symbolToStringEx(symbol *ast.Symbol, enclosingDeclaration *ast
}
var printer_ *printer.Printer
if enclosingDeclaration != nil && enclosingDeclaration.Kind == ast.KindSourceFile {
printer_ = createPrinterWithRemoveCommentsNeverAsciiEscape()
printer_ = createPrinterWithRemoveCommentsNeverAsciiEscape(c.diagnosticConstructionContext)
} else {
printer_ = createPrinterWithRemoveComments()
printer_ = createPrinterWithRemoveComments(c.diagnosticConstructionContext)
}

var builder func(symbol *ast.Symbol, meaning ast.SymbolFlags, enclosingDeclaration *ast.Node, flags nodebuilder.Flags, internalFlags nodebuilder.InternalFlags, tracker nodebuilder.SymbolTracker) *ast.Node
Expand Down Expand Up @@ -166,7 +166,7 @@ func (c *Checker) signatureToStringEx(signature *Signature, enclosingDeclaration
}
combinedFlags := toNodeBuilderFlags(flags) | nodebuilder.FlagsIgnoreErrors | nodebuilder.FlagsWriteTypeParametersInQualifiedName
sig := c.nodeBuilder.signatureToSignatureDeclaration(signature, sigOutput, enclosingDeclaration, combinedFlags, nodebuilder.InternalFlagsNone, nil)
printer_ := createPrinterWithRemoveCommentsOmitTrailingSemicolon()
printer_ := createPrinterWithRemoveCommentsOmitTrailingSemicolon(c.diagnosticConstructionContext)
var sourceFile *ast.SourceFile
if enclosingDeclaration != nil {
sourceFile = ast.GetSourceFileOfNode(enclosingDeclaration)
Expand All @@ -193,7 +193,7 @@ func (c *Checker) typePredicateToStringEx(typePredicate *TypePredicate, enclosin
}
combinedFlags := toNodeBuilderFlags(flags) | nodebuilder.FlagsIgnoreErrors | nodebuilder.FlagsWriteTypeParametersInQualifiedName
predicate := c.nodeBuilder.typePredicateToTypePredicateNode(typePredicate, enclosingDeclaration, combinedFlags, nodebuilder.InternalFlagsNone, nil) // TODO: GH#18217
printer_ := createPrinterWithRemoveComments()
printer_ := createPrinterWithRemoveComments(c.diagnosticConstructionContext)
var sourceFile *ast.SourceFile
if enclosingDeclaration != nil {
sourceFile = ast.GetSourceFileOfNode(enclosingDeclaration)
Expand Down