Files
kjol/tools/tsgo/internal/ast/symbol.go
2026-07-09 16:50:43 -04:00

104 lines
4.5 KiB
Go

package ast
import (
"strings"
"sync/atomic"
)
// Symbol
type Symbol struct {
Flags SymbolFlags
CheckFlags CheckFlags // Non-zero only in transient symbols created by Checker
Name string
Declarations []*Node
ValueDeclaration *Node
Members SymbolTable
Exports SymbolTable
id atomic.Uint64
Parent *Symbol
ExportSymbol *Symbol
}
func (s *Symbol) IsExternalModule() bool {
return s.Flags&SymbolFlagsModule != 0 && len(s.Name) > 0 && s.Name[0] == '"'
}
func (s *Symbol) IsStatic() bool {
if s.ValueDeclaration == nil {
return false
}
modifierFlags := s.ValueDeclaration.ModifierFlags()
return modifierFlags&ModifierFlagsStatic != 0
}
// See comment on `declareModuleMember` in `binder.go`.
func (s *Symbol) CombinedLocalAndExportSymbolFlags() SymbolFlags {
if s.ExportSymbol != nil {
return s.Flags | s.ExportSymbol.Flags
}
return s.Flags
}
// SymbolTable
type SymbolTable map[string]*Symbol
const InternalSymbolNamePrefix = "\xFE" // Invalid UTF8 sequence, will never occur as IdentifierName
const (
InternalSymbolNameCall = InternalSymbolNamePrefix + "call" // Call signatures
InternalSymbolNameConstructor = InternalSymbolNamePrefix + "constructor" // Constructor implementations
InternalSymbolNameNew = InternalSymbolNamePrefix + "new" // Constructor signatures
InternalSymbolNameIndex = InternalSymbolNamePrefix + "index" // Index signatures
InternalSymbolNameExportStar = InternalSymbolNamePrefix + "export" // Module export * declarations
InternalSymbolNameGlobal = InternalSymbolNamePrefix + "global" // Global self-reference
InternalSymbolNameMissing = InternalSymbolNamePrefix + "missing" // Indicates missing symbol
InternalSymbolNameType = InternalSymbolNamePrefix + "type" // Anonymous type literal symbol
InternalSymbolNameObject = InternalSymbolNamePrefix + "object" // Anonymous object literal declaration
InternalSymbolNameJSXAttributes = InternalSymbolNamePrefix + "jsxAttributes" // Anonymous JSX attributes object literal declaration
InternalSymbolNameClass = InternalSymbolNamePrefix + "class" // Unnamed class expression
InternalSymbolNameFunction = InternalSymbolNamePrefix + "function" // Unnamed function expression
InternalSymbolNameComputed = InternalSymbolNamePrefix + "computed" // Computed property name declaration with dynamic name
InternalSymbolNameAssignmentDeclaration = InternalSymbolNamePrefix + "assignment" // Assignment declarations
InternalSymbolNameInstantiationExpression = InternalSymbolNamePrefix + "instantiationExpression" // Instantiation expressions
InternalSymbolNameImportAttributes = InternalSymbolNamePrefix + "importAttributes"
InternalSymbolNameExportEquals = "export=" // Export assignment symbol
InternalSymbolNameDefault = "default" // Default export symbol (technically not wholly internal, but included here for usability)
InternalSymbolNameThis = "this"
InternalSymbolNameModuleExports = "module.exports"
)
func SymbolName(symbol *Symbol) string {
if symbol.ValueDeclaration != nil && IsPrivateIdentifierClassElementDeclaration(symbol.ValueDeclaration) {
return symbol.ValueDeclaration.Name().Text()
}
return symbol.Name
}
// EscapeAllInternalSymbolNames replaces internal symbol name markers ("\xFE") with "__".
func EscapeAllInternalSymbolNames(name string) string {
return strings.ReplaceAll(name, InternalSymbolNamePrefix, "__")
}
func EscapeInternalSymbolName(name string) string {
if rest, ok := strings.CutPrefix(name, InternalSymbolNamePrefix); ok {
return "__" + rest
}
return name
}
// EscapeSymbolName converts a binder symbol name into its escaped "__String"
// form. Internal names (prefixed with the "\xFE" sentinel) become "__"-prefixed,
// and user names that already begin with "__" gain an extra leading underscore
// so they can be distinguished from internal names.
func EscapeSymbolName(name string) string {
if rest, ok := strings.CutPrefix(name, InternalSymbolNamePrefix); ok {
return "__" + rest
}
if len(name) >= 2 && name[0] == '_' && name[1] == '_' {
return "_" + name
}
return name
}