remove unused packages

This commit is contained in:
Egor Aristov 2025-10-15 17:28:42 +03:00
parent 0cea2e734b
commit 78201db012
Signed by: egor3f
GPG Key ID: 40482A264AAEC85F
22 changed files with 0 additions and 54504 deletions

View File

@ -1,8 +1,3 @@
/**
* @kittenipc:api
*/

File diff suppressed because it is too large Load Diff

View File

@ -1,103 +0,0 @@
package checker_test
import (
"testing"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/ast"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/bundled"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/checker"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/compiler"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/core"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/repo"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/tsoptions"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/tspath"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/vfs/osvfs"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/vfs/vfstest"
"gotest.tools/v3/assert"
)
func TestGetSymbolAtLocation(t *testing.T) {
t.Parallel()
content := `interface Foo {
bar: string;
}
declare const foo: Foo;
foo.bar;`
fs := vfstest.FromMap(map[string]string{
"/foo.ts": content,
"/tsconfig.json": `
{
"compilerOptions": {},
"files": ["foo.ts"]
}
`,
}, false /*useCaseSensitiveFileNames*/)
fs = bundled.WrapFS(fs)
cd := "/"
host := compiler.NewCompilerHost(cd, fs, bundled.LibPath(), nil, nil)
parsed, errors := tsoptions.GetParsedCommandLineOfConfigFile("/tsconfig.json", &core.CompilerOptions{}, host, nil)
assert.Equal(t, len(errors), 0, "Expected no errors in parsed command line")
p := compiler.NewProgram(compiler.ProgramOptions{
Config: parsed,
Host: host,
})
p.BindSourceFiles()
c, done := p.GetTypeChecker(t.Context())
defer done()
file := p.GetSourceFile("/foo.ts")
interfaceId := file.Statements.Nodes[0].Name()
varId := file.Statements.Nodes[1].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0].Name()
propAccess := file.Statements.Nodes[2].AsExpressionStatement().Expression
nodes := []*ast.Node{interfaceId, varId, propAccess}
for _, node := range nodes {
symbol := c.GetSymbolAtLocation(node)
if symbol == nil {
t.Fatalf("Expected symbol to be non-nil")
}
}
}
func TestCheckSrcCompiler(t *testing.T) {
t.Parallel()
repo.SkipIfNoTypeScriptSubmodule(t)
fs := osvfs.FS()
fs = bundled.WrapFS(fs)
rootPath := tspath.CombinePaths(tspath.NormalizeSlashes(repo.TypeScriptSubmodulePath), "src", "compiler")
host := compiler.NewCompilerHost(rootPath, fs, bundled.LibPath(), nil, nil)
parsed, errors := tsoptions.GetParsedCommandLineOfConfigFile(tspath.CombinePaths(rootPath, "tsconfig.json"), &core.CompilerOptions{}, host, nil)
assert.Equal(t, len(errors), 0, "Expected no errors in parsed command line")
p := compiler.NewProgram(compiler.ProgramOptions{
Config: parsed,
Host: host,
})
p.CheckSourceFiles(t.Context(), nil)
}
func BenchmarkNewChecker(b *testing.B) {
repo.SkipIfNoTypeScriptSubmodule(b)
fs := osvfs.FS()
fs = bundled.WrapFS(fs)
rootPath := tspath.CombinePaths(tspath.NormalizeSlashes(repo.TypeScriptSubmodulePath), "src", "compiler")
host := compiler.NewCompilerHost(rootPath, fs, bundled.LibPath(), nil, nil)
parsed, errors := tsoptions.GetParsedCommandLineOfConfigFile(tspath.CombinePaths(rootPath, "tsconfig.json"), &core.CompilerOptions{}, host, nil)
assert.Equal(b, len(errors), 0, "Expected no errors in parsed command line")
p := compiler.NewProgram(compiler.ProgramOptions{
Config: parsed,
Host: host,
})
b.ReportAllocs()
for b.Loop() {
checker.NewChecker(p)
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,172 +0,0 @@
package checker
import (
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/ast"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/core"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/diagnostics"
)
func (c *Checker) GetStringType() *Type {
return c.stringType
}
func (c *Checker) GetUnknownSymbol() *ast.Symbol {
return c.unknownSymbol
}
func (c *Checker) GetUnionType(types []*Type) *Type {
return c.getUnionType(types)
}
func (c *Checker) GetGlobalSymbol(name string, meaning ast.SymbolFlags, diagnostic *diagnostics.Message) *ast.Symbol {
return c.getGlobalSymbol(name, meaning, diagnostic)
}
func (c *Checker) GetMergedSymbol(symbol *ast.Symbol) *ast.Symbol {
return c.getMergedSymbol(symbol)
}
func (c *Checker) TryFindAmbientModule(moduleName string) *ast.Symbol {
return c.tryFindAmbientModule(moduleName, true /* withAugmentations */)
}
func (c *Checker) GetImmediateAliasedSymbol(symbol *ast.Symbol) *ast.Symbol {
return c.getImmediateAliasedSymbol(symbol)
}
func (c *Checker) GetTypeOnlyAliasDeclaration(symbol *ast.Symbol) *ast.Node {
return c.getTypeOnlyAliasDeclaration(symbol)
}
func (c *Checker) ResolveExternalModuleName(moduleSpecifier *ast.Node) *ast.Symbol {
return c.resolveExternalModuleName(moduleSpecifier, moduleSpecifier, true /*ignoreErrors*/)
}
func (c *Checker) ResolveExternalModuleSymbol(moduleSymbol *ast.Symbol) *ast.Symbol {
return c.resolveExternalModuleSymbol(moduleSymbol, false /*dontResolveAlias*/)
}
func (c *Checker) GetTypeFromTypeNode(node *ast.Node) *Type {
return c.getTypeFromTypeNode(node)
}
func (c *Checker) IsArrayLikeType(t *Type) bool {
return c.isArrayLikeType(t)
}
func (c *Checker) GetPropertiesOfType(t *Type) []*ast.Symbol {
return c.getPropertiesOfType(t)
}
func (c *Checker) GetPropertyOfType(t *Type, name string) *ast.Symbol {
return c.getPropertyOfType(t, name)
}
func (c *Checker) TypeHasCallOrConstructSignatures(t *Type) bool {
return c.typeHasCallOrConstructSignatures(t)
}
// Checks if a property can be accessed in a location.
// The location is given by the `node` parameter.
// The node does not need to be a property access.
// @param node location where to check property accessibility
// @param isSuper whether to consider this a `super` property access, e.g. `super.foo`.
// @param isWrite whether this is a write access, e.g. `++foo.x`.
// @param containingType type where the property comes from.
// @param property property symbol.
func (c *Checker) IsPropertyAccessible(node *ast.Node, isSuper bool, isWrite bool, containingType *Type, property *ast.Symbol) bool {
return c.isPropertyAccessible(node, isSuper, isWrite, containingType, property)
}
func (c *Checker) GetTypeOfPropertyOfContextualType(t *Type, name string) *Type {
return c.getTypeOfPropertyOfContextualType(t, name)
}
func GetDeclarationModifierFlagsFromSymbol(s *ast.Symbol) ast.ModifierFlags {
return getDeclarationModifierFlagsFromSymbol(s)
}
func (c *Checker) WasCanceled() bool {
return c.wasCanceled
}
func (c *Checker) GetSignaturesOfType(t *Type, kind SignatureKind) []*Signature {
return c.getSignaturesOfType(t, kind)
}
func (c *Checker) GetDeclaredTypeOfSymbol(symbol *ast.Symbol) *Type {
return c.getDeclaredTypeOfSymbol(symbol)
}
func (c *Checker) GetTypeOfSymbol(symbol *ast.Symbol) *Type {
return c.getTypeOfSymbol(symbol)
}
func (c *Checker) GetConstraintOfTypeParameter(typeParameter *Type) *Type {
return c.getConstraintOfTypeParameter(typeParameter)
}
func (c *Checker) GetResolutionModeOverride(node *ast.ImportAttributes, reportErrors bool) core.ResolutionMode {
return c.getResolutionModeOverride(node, reportErrors)
}
func (c *Checker) GetEffectiveDeclarationFlags(n *ast.Node, flagsToCheck ast.ModifierFlags) ast.ModifierFlags {
return c.getEffectiveDeclarationFlags(n, flagsToCheck)
}
func (c *Checker) GetBaseConstraintOfType(t *Type) *Type {
return c.getBaseConstraintOfType(t)
}
func (c *Checker) GetTypePredicateOfSignature(sig *Signature) *TypePredicate {
return c.getTypePredicateOfSignature(sig)
}
func IsTupleType(t *Type) bool {
return isTupleType(t)
}
func (c *Checker) GetReturnTypeOfSignature(sig *Signature) *Type {
return c.getReturnTypeOfSignature(sig)
}
func (c *Checker) HasEffectiveRestParameter(signature *Signature) bool {
return c.hasEffectiveRestParameter(signature)
}
func (c *Checker) GetLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol *ast.Symbol) []*Type {
return c.getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol)
}
func (c *Checker) GetContextualTypeForObjectLiteralElement(element *ast.Node, contextFlags ContextFlags) *Type {
return c.getContextualTypeForObjectLiteralElement(element, contextFlags)
}
func (c *Checker) TypePredicateToString(t *TypePredicate) string {
return c.typePredicateToString(t)
}
func (c *Checker) GetExpandedParameters(signature *Signature, skipUnionExpanding bool) [][]*ast.Symbol {
return c.getExpandedParameters(signature, skipUnionExpanding)
}
func (c *Checker) GetResolvedSignature(node *ast.Node) *Signature {
return c.getResolvedSignature(node, nil, CheckModeNormal)
}
// Return the type of the given property in the given type, or nil if no such property exists
func (c *Checker) GetTypeOfPropertyOfType(t *Type, name string) *Type {
return c.getTypeOfPropertyOfType(t, name)
}
func (c *Checker) GetContextualTypeForArgumentAtIndex(node *ast.Node, argIndex int) *Type {
return c.getContextualTypeForArgumentAtIndex(node, argIndex)
}
func (c *Checker) GetIndexSignaturesAtLocation(node *ast.Node) []*ast.Node {
return c.getIndexSignaturesAtLocation(node)
}
func (c *Checker) GetResolvedSymbol(node *ast.Node) *ast.Symbol {
return c.getResolvedSymbol(node)
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,97 +0,0 @@
package checker
import (
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/ast"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/collections"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/diagnostics"
)
func (c *Checker) checkUnmatchedJSDocParameters(node *ast.Node) {
var jsdocParameters []*ast.Node
for _, tag := range getAllJSDocTags(node) {
if tag.Kind == ast.KindJSDocParameterTag {
name := tag.AsJSDocParameterOrPropertyTag().Name()
if ast.IsIdentifier(name) && len(name.Text()) == 0 {
continue
}
jsdocParameters = append(jsdocParameters, tag)
}
}
if len(jsdocParameters) == 0 {
return
}
isJs := ast.IsInJSFile(node)
parameters := collections.Set[string]{}
excludedParameters := collections.Set[int]{}
for i, param := range node.Parameters() {
name := param.AsParameterDeclaration().Name()
if ast.IsIdentifier(name) {
parameters.Add(name.Text())
}
if ast.IsBindingPattern(name) {
excludedParameters.Add(i)
}
}
if c.containsArgumentsReference(node) {
if isJs {
lastJSDocParamIndex := len(jsdocParameters) - 1
lastJSDocParam := jsdocParameters[lastJSDocParamIndex].AsJSDocParameterOrPropertyTag()
if lastJSDocParam == nil || !ast.IsIdentifier(lastJSDocParam.Name()) {
return
}
if excludedParameters.Has(lastJSDocParamIndex) || parameters.Has(lastJSDocParam.Name().Text()) {
return
}
if lastJSDocParam.TypeExpression == nil || lastJSDocParam.TypeExpression.Type() == nil {
return
}
if c.isArrayType(c.getTypeFromTypeNode(lastJSDocParam.TypeExpression.Type())) {
return
}
c.error(lastJSDocParam.Name(), diagnostics.JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_It_would_match_arguments_if_it_had_an_array_type, lastJSDocParam.Name().Text())
}
} else {
for index, tag := range jsdocParameters {
name := tag.AsJSDocParameterOrPropertyTag().Name()
isNameFirst := tag.AsJSDocParameterOrPropertyTag().IsNameFirst
if excludedParameters.Has(index) || (ast.IsIdentifier(name) && parameters.Has(name.Text())) {
continue
}
if ast.IsQualifiedName(name) {
if isJs {
c.error(name, diagnostics.Qualified_name_0_is_not_allowed_without_a_leading_param_object_1,
entityNameToString(name),
entityNameToString(name.AsQualifiedName().Left),
)
}
} else {
if !isNameFirst {
c.errorOrSuggestion(isJs, name,
diagnostics.JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name,
name.Text(),
)
}
}
}
}
}
func getAllJSDocTags(node *ast.Node) []*ast.Node {
if node == nil {
return nil
}
jsdocs := node.JSDoc(nil)
if len(jsdocs) == 0 {
return nil
}
lastJSDoc := jsdocs[len(jsdocs)-1].AsJSDoc()
if lastJSDoc.Tags == nil {
return nil
}
return lastJSDoc.Tags.Nodes
}

File diff suppressed because it is too large Load Diff

View File

@ -1,294 +0,0 @@
package checker
import "efprojects.com/kitten-ipc/kitcom/internal/tsgo/core"
// TypeMapperKind
type TypeMapperKind int32
const (
TypeMapperKindUnknown TypeMapperKind = iota
TypeMapperKindSimple
TypeMapperKindArray
TypeMapperKindMerged
)
// TypeMapper
type TypeMapper struct {
data TypeMapperData
}
func (m *TypeMapper) Map(t *Type) *Type { return m.data.Map(t) }
func (m *TypeMapper) Kind() TypeMapperKind { return m.data.Kind() }
// TypeMapperData
type TypeMapperData interface {
Map(t *Type) *Type
Kind() TypeMapperKind
}
// Factory functions
func newTypeMapper(sources []*Type, targets []*Type) *TypeMapper {
if len(sources) == 1 {
return newSimpleTypeMapper(sources[0], targets[0])
}
return newArrayTypeMapper(sources, targets)
}
func (c *Checker) combineTypeMappers(m1 *TypeMapper, m2 *TypeMapper) *TypeMapper {
if m1 != nil {
return newCompositeTypeMapper(c, m1, m2)
}
return m2
}
func mergeTypeMappers(m1 *TypeMapper, m2 *TypeMapper) *TypeMapper {
if m1 != nil {
return newMergedTypeMapper(m1, m2)
}
return m2
}
func prependTypeMapping(source *Type, target *Type, mapper *TypeMapper) *TypeMapper {
if mapper == nil {
return newSimpleTypeMapper(source, target)
}
return newMergedTypeMapper(newSimpleTypeMapper(source, target), mapper)
}
func appendTypeMapping(mapper *TypeMapper, source *Type, target *Type) *TypeMapper {
if mapper == nil {
return newSimpleTypeMapper(source, target)
}
return newMergedTypeMapper(mapper, newSimpleTypeMapper(source, target))
}
// Maps forward-references to later types parameters to the empty object type.
// This is used during inference when instantiating type parameter defaults.
func (c *Checker) newBackreferenceMapper(context *InferenceContext, index int) *TypeMapper {
forwardInferences := context.inferences[index:]
typeParameters := core.Map(forwardInferences, func(i *InferenceInfo) *Type {
return i.typeParameter
})
return newArrayToSingleTypeMapper(typeParameters, c.unknownType)
}
// TypeMapperBase
type TypeMapperBase struct {
TypeMapper
}
func (m *TypeMapperBase) Map(t *Type) *Type { return t }
func (m *TypeMapperBase) Kind() TypeMapperKind { return TypeMapperKindUnknown }
// SimpleTypeMapper
type SimpleTypeMapper struct {
TypeMapperBase
source *Type
target *Type
}
func newSimpleTypeMapper(source *Type, target *Type) *TypeMapper {
m := &SimpleTypeMapper{}
m.data = m
m.source = source
m.target = target
return &m.TypeMapper
}
func (m *SimpleTypeMapper) Map(t *Type) *Type {
if t == m.source {
return m.target
}
return t
}
func (m *SimpleTypeMapper) Kind() TypeMapperKind {
return TypeMapperKindSimple
}
// ArrayTypeMapper
type ArrayTypeMapper struct {
TypeMapperBase
sources []*Type
targets []*Type
}
func newArrayTypeMapper(sources []*Type, targets []*Type) *TypeMapper {
m := &ArrayTypeMapper{}
m.data = m
m.sources = sources
m.targets = targets
return &m.TypeMapper
}
func (m *ArrayTypeMapper) Map(t *Type) *Type {
for i, s := range m.sources {
if t == s {
return m.targets[i]
}
}
return t
}
func (m *ArrayTypeMapper) Kind() TypeMapperKind {
return TypeMapperKindArray
}
// ArrayToSingleTypeMapper
type ArrayToSingleTypeMapper struct {
TypeMapperBase
sources []*Type
target *Type
}
func newArrayToSingleTypeMapper(sources []*Type, target *Type) *TypeMapper {
m := &ArrayToSingleTypeMapper{}
m.data = m
m.sources = sources
m.target = target
return &m.TypeMapper
}
func (m *ArrayToSingleTypeMapper) Map(t *Type) *Type {
for _, s := range m.sources {
if t == s {
return m.target
}
}
return t
}
// DeferredTypeMapper
type DeferredTypeMapper struct {
TypeMapperBase
sources []*Type
targets []func() *Type
}
func newDeferredTypeMapper(sources []*Type, targets []func() *Type) *TypeMapper {
m := &DeferredTypeMapper{}
m.data = m
m.sources = sources
m.targets = targets
return &m.TypeMapper
}
func (m *DeferredTypeMapper) Map(t *Type) *Type {
for i, s := range m.sources {
if t == s {
return m.targets[i]()
}
}
return t
}
// FunctionTypeMapper
type FunctionTypeMapper struct {
TypeMapperBase
fn func(*Type) *Type
}
func newFunctionTypeMapper(fn func(*Type) *Type) *TypeMapper {
m := &FunctionTypeMapper{}
m.data = m
m.fn = fn
return &m.TypeMapper
}
func (m *FunctionTypeMapper) Map(t *Type) *Type {
return m.fn(t)
}
// MergedTypeMapper
type MergedTypeMapper struct {
TypeMapperBase
m1 *TypeMapper
m2 *TypeMapper
}
func newMergedTypeMapper(m1 *TypeMapper, m2 *TypeMapper) *TypeMapper {
m := &MergedTypeMapper{}
m.data = m
m.m1 = m1
m.m2 = m2
return &m.TypeMapper
}
func (m *MergedTypeMapper) Map(t *Type) *Type {
return m.m2.Map(m.m1.Map(t))
}
func (m *MergedTypeMapper) Kind() TypeMapperKind {
return TypeMapperKindMerged
}
// CompositeTypeMapper
type CompositeTypeMapper struct {
TypeMapperBase
c *Checker
m1 *TypeMapper
m2 *TypeMapper
}
func newCompositeTypeMapper(c *Checker, m1 *TypeMapper, m2 *TypeMapper) *TypeMapper {
m := &CompositeTypeMapper{}
m.data = m
m.c = c
m.m1 = m1
m.m2 = m2
return &m.TypeMapper
}
func (m *CompositeTypeMapper) Map(t *Type) *Type {
t1 := m.m1.Map(t)
if t1 != t {
return m.c.instantiateType(t1, m.m2)
}
return m.m2.Map(t)
}
// InferenceTypeMapper
type InferenceTypeMapper struct {
TypeMapperBase
c *Checker
n *InferenceContext
fixing bool
}
func (c *Checker) newInferenceTypeMapper(n *InferenceContext, fixing bool) *TypeMapper {
m := &InferenceTypeMapper{}
m.data = m
m.c = c
m.n = n
m.fixing = fixing
return &m.TypeMapper
}
func (m *InferenceTypeMapper) Map(t *Type) *Type {
for i, inference := range m.n.inferences {
if t == inference.typeParameter {
if m.fixing && !inference.isFixed {
// Before we commit to a particular inference (and thus lock out any further inferences),
// we infer from any intra-expression inference sites we have collected.
m.c.inferFromIntraExpressionSites(m.n)
clearCachedInferences(m.n.inferences)
inference.isFixed = true
}
return m.c.getInferredType(m.n, i)
}
}
return t
}

View File

@ -1,186 +0,0 @@
package checker
import (
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/ast"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/nodebuilder"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/printer"
)
type NodeBuilder struct {
ctxStack []*NodeBuilderContext
basicHost Host
impl *nodeBuilderImpl
}
// EmitContext implements NodeBuilderInterface.
func (b *NodeBuilder) EmitContext() *printer.EmitContext {
return b.impl.e
}
func (b *NodeBuilder) enterContext(enclosingDeclaration *ast.Node, flags nodebuilder.Flags, internalFlags nodebuilder.InternalFlags, tracker nodebuilder.SymbolTracker) {
b.ctxStack = append(b.ctxStack, b.impl.ctx)
b.impl.ctx = &NodeBuilderContext{
tracker: tracker,
flags: flags,
internalFlags: internalFlags,
enclosingDeclaration: enclosingDeclaration,
enclosingFile: ast.GetSourceFileOfNode(enclosingDeclaration),
inferTypeParameters: make([]*Type, 0),
symbolDepth: make(map[CompositeSymbolIdentity]int),
trackedSymbols: make([]*TrackedSymbolArgs, 0),
reverseMappedStack: make([]*ast.Symbol, 0),
enclosingSymbolTypes: make(map[ast.SymbolId]*Type),
remappedSymbolReferences: make(map[ast.SymbolId]*ast.Symbol),
}
// TODO: always provide this; see https://github.com/microsoft/typescript-go/pull/1588#pullrequestreview-3125218673
var moduleResolverHost Host
if tracker != nil {
moduleResolverHost = tracker.GetModuleSpecifierGenerationHost()
} else if internalFlags&nodebuilder.InternalFlagsDoNotIncludeSymbolChain != 0 {
moduleResolverHost = b.basicHost
}
tracker = NewSymbolTrackerImpl(b.impl.ctx, tracker, moduleResolverHost)
b.impl.ctx.tracker = tracker
}
func (b *NodeBuilder) popContext() {
stackSize := len(b.ctxStack)
if stackSize == 0 {
b.impl.ctx = nil
} else {
b.impl.ctx = b.ctxStack[stackSize-1]
b.ctxStack = b.ctxStack[:stackSize-1]
}
}
func (b *NodeBuilder) exitContext(result *ast.Node) *ast.Node {
b.exitContextCheck()
defer b.popContext()
if b.impl.ctx.encounteredError {
return nil
}
return result
}
func (b *NodeBuilder) exitContextSlice(result []*ast.Node) []*ast.Node {
b.exitContextCheck()
defer b.popContext()
if b.impl.ctx.encounteredError {
return nil
}
return result
}
func (b *NodeBuilder) exitContextCheck() {
if b.impl.ctx.truncating && b.impl.ctx.flags&nodebuilder.FlagsNoTruncation != 0 {
b.impl.ctx.tracker.ReportTruncationError()
}
}
// IndexInfoToIndexSignatureDeclaration implements NodeBuilderInterface.
func (b *NodeBuilder) IndexInfoToIndexSignatureDeclaration(info *IndexInfo, 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.indexInfoToIndexSignatureDeclarationHelper(info, nil))
}
// SerializeReturnTypeForSignature implements NodeBuilderInterface.
func (b *NodeBuilder) SerializeReturnTypeForSignature(signatureDeclaration *ast.Node, enclosingDeclaration *ast.Node, flags nodebuilder.Flags, internalFlags nodebuilder.InternalFlags, tracker nodebuilder.SymbolTracker) *ast.Node {
b.enterContext(enclosingDeclaration, flags, internalFlags, tracker)
signature := b.impl.ch.getSignatureFromDeclaration(signatureDeclaration)
symbol := b.impl.ch.getSymbolOfDeclaration(signatureDeclaration)
returnType, ok := b.impl.ctx.enclosingSymbolTypes[ast.GetSymbolId(symbol)]
if !ok || returnType == nil {
returnType = b.impl.ch.instantiateType(b.impl.ch.getReturnTypeOfSignature(signature), b.impl.ctx.mapper)
}
return b.exitContext(b.impl.serializeInferredReturnTypeForSignature(signature, returnType))
}
func (b *NodeBuilder) SerializeTypeParametersForSignature(signatureDeclaration *ast.Node, enclosingDeclaration *ast.Node, flags nodebuilder.Flags, internalFlags nodebuilder.InternalFlags, tracker nodebuilder.SymbolTracker) []*ast.Node {
b.enterContext(enclosingDeclaration, flags, internalFlags, tracker)
symbol := b.impl.ch.getSymbolOfDeclaration(signatureDeclaration)
typeParams := b.SymbolToTypeParameterDeclarations(symbol, enclosingDeclaration, flags, internalFlags, tracker)
return b.exitContextSlice(typeParams)
}
// SerializeTypeForDeclaration implements NodeBuilderInterface.
func (b *NodeBuilder) SerializeTypeForDeclaration(declaration *ast.Node, symbol *ast.Symbol, 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.serializeTypeForDeclaration(declaration, nil, symbol))
}
// SerializeTypeForExpression implements NodeBuilderInterface.
func (b *NodeBuilder) SerializeTypeForExpression(expr *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.serializeTypeForExpression(expr))
}
// SignatureToSignatureDeclaration implements NodeBuilderInterface.
func (b *NodeBuilder) SignatureToSignatureDeclaration(signature *Signature, kind ast.Kind, 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.signatureToSignatureDeclarationHelper(signature, kind, nil))
}
// SymbolTableToDeclarationStatements implements NodeBuilderInterface.
func (b *NodeBuilder) SymbolTableToDeclarationStatements(symbolTable *ast.SymbolTable, enclosingDeclaration *ast.Node, flags nodebuilder.Flags, internalFlags nodebuilder.InternalFlags, tracker nodebuilder.SymbolTracker) []*ast.Node {
b.enterContext(enclosingDeclaration, flags, internalFlags, tracker)
return b.exitContextSlice(b.impl.symbolTableToDeclarationStatements(symbolTable))
}
// SymbolToEntityName implements NodeBuilderInterface.
func (b *NodeBuilder) SymbolToEntityName(symbol *ast.Symbol, meaning ast.SymbolFlags, 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.symbolToName(symbol, meaning, false))
}
// SymbolToExpression implements NodeBuilderInterface.
func (b *NodeBuilder) SymbolToExpression(symbol *ast.Symbol, meaning ast.SymbolFlags, 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.symbolToExpression(symbol, meaning))
}
// SymbolToNode implements NodeBuilderInterface.
func (b *NodeBuilder) SymbolToNode(symbol *ast.Symbol, meaning ast.SymbolFlags, 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.symbolToNode(symbol, meaning))
}
// SymbolToParameterDeclaration implements NodeBuilderInterface.
func (b NodeBuilder) SymbolToParameterDeclaration(symbol *ast.Symbol, 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.symbolToParameterDeclaration(symbol, false))
}
// SymbolToTypeParameterDeclarations implements NodeBuilderInterface.
func (b *NodeBuilder) SymbolToTypeParameterDeclarations(symbol *ast.Symbol, enclosingDeclaration *ast.Node, flags nodebuilder.Flags, internalFlags nodebuilder.InternalFlags, tracker nodebuilder.SymbolTracker) []*ast.Node {
b.enterContext(enclosingDeclaration, flags, internalFlags, tracker)
return b.exitContextSlice(b.impl.symbolToTypeParameterDeclarations(symbol))
}
// TypeParameterToDeclaration implements NodeBuilderInterface.
func (b *NodeBuilder) TypeParameterToDeclaration(parameter *Type, 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.typeParameterToDeclaration(parameter))
}
// 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)
return b.exitContext(b.impl.typePredicateToTypePredicateNode(predicate))
}
// TypeToTypeNode implements NodeBuilderInterface.
func (b *NodeBuilder) TypeToTypeNode(typ *Type, 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.typeToTypeNode(typ))
}
// var _ NodeBuilderInterface = NewNodeBuilderAPI(nil, nil)
func NewNodeBuilder(ch *Checker, e *printer.EmitContext) *NodeBuilder {
impl := newNodeBuilderImpl(ch, e)
return &NodeBuilder{impl: impl, ctxStack: make([]*NodeBuilderContext, 0, 1), basicHost: ch.program}
}
func (c *Checker) getNodeBuilder() *NodeBuilder {
return NewNodeBuilder(c, printer.NewEmitContext())
}

File diff suppressed because it is too large Load Diff

View File

@ -1,246 +0,0 @@
package checker
import (
"maps"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/ast"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/core"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/debug"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/nodebuilder"
)
func cloneNodeBuilderContext(context *NodeBuilderContext) func() {
// Make type parameters created within this context not consume the name outside this context
// The symbol serializer ends up creating many sibling scopes that all need "separate" contexts when
// it comes to naming things - within a normal `typeToTypeNode` call, the node builder only ever descends
// through the type tree, so the only cases where we could have used distinct sibling scopes was when there
// were multiple generic overloads with similar generated type parameter names
// The effect:
// When we write out
// export const x: <T>(x: T) => T
// export const y: <T>(x: T) => T
// we write it out like that, rather than as
// export const x: <T>(x: T) => T
// export const y: <T_1>(x: T_1) => T_1
oldMustCreateTypeParameterSymbolList := context.hasCreatedTypeParameterSymbolList
oldMustCreateTypeParametersNamesLookups := context.hasCreatedTypeParametersNamesLookups
oldTypeParameterNames := context.typeParameterNames
oldTypeParameterNamesByText := context.typeParameterNamesByText
oldTypeParameterNamesByTextNextNameCount := context.typeParameterNamesByTextNextNameCount
oldTypeParameterSymbolList := context.typeParameterSymbolList
context.hasCreatedTypeParameterSymbolList = oldTypeParameterSymbolList != nil
context.hasCreatedTypeParametersNamesLookups = oldTypeParameterNames != nil
context.typeParameterNames = maps.Clone(context.typeParameterNames)
context.typeParameterNamesByText = maps.Clone(context.typeParameterNamesByText)
context.typeParameterNamesByTextNextNameCount = maps.Clone(context.typeParameterNamesByTextNextNameCount)
context.typeParameterSymbolList = maps.Clone(context.typeParameterSymbolList)
return func() {
context.typeParameterNames = oldTypeParameterNames
context.typeParameterNamesByText = oldTypeParameterNamesByText
context.typeParameterNamesByTextNextNameCount = oldTypeParameterNamesByTextNextNameCount
context.typeParameterSymbolList = oldTypeParameterSymbolList
context.hasCreatedTypeParameterSymbolList = oldMustCreateTypeParameterSymbolList
context.hasCreatedTypeParametersNamesLookups = oldMustCreateTypeParametersNamesLookups
}
}
type localsRecord struct {
name string
oldSymbol *ast.Symbol
}
func (b *nodeBuilderImpl) enterNewScope(declaration *ast.Node, expandedParams []*ast.Symbol, typeParameters []*Type, originalParameters []*ast.Symbol, mapper *TypeMapper) func() {
cleanupContext := cloneNodeBuilderContext(b.ctx)
// For regular function/method declarations, the enclosing declaration will already be signature.declaration,
// so this is a no-op, but for arrow functions and function expressions, the enclosing declaration will be
// the declaration that the arrow function / function expression is assigned to.
//
// If the parameters or return type include "typeof globalThis.paramName", using the wrong scope will lead
// us to believe that we can emit "typeof paramName" instead, even though that would refer to the parameter,
// not the global. Make sure we are in the right scope by changing the enclosingDeclaration to the function.
//
// We can't use the declaration directly; it may be in another file and so we may lose access to symbols
// accessible to the current enclosing declaration, or gain access to symbols not accessible to the current
// enclosing declaration. To keep this chain accurate, insert a fake scope into the chain which makes the
// function's parameters visible.
var cleanupParams func()
var cleanupTypeParams func()
oldEnclosingDecl := b.ctx.enclosingDeclaration
oldMapper := b.ctx.mapper
if mapper != nil {
b.ctx.mapper = mapper
}
if b.ctx.enclosingDeclaration != nil && declaration != nil {
// As a performance optimization, reuse the same fake scope within this chain.
// This is especially needed when we are working on an excessively deep type;
// if we don't do this, then we spend all of our time adding more and more
// scopes that need to be searched in isSymbolAccessible later. Since all we
// really want to do is to mark certain names as unavailable, we can just keep
// all of the names we're introducing in one large table and push/pop from it as
// needed; isSymbolAccessible will walk upward and find the closest "fake" scope,
// which will conveniently report on any and all faked scopes in the chain.
//
// It'd likely be better to store this somewhere else for isSymbolAccessible, but
// since that API _only_ uses the enclosing declaration (and its parents), this is
// seems like the best way to inject names into that search process.
//
// Note that we only check the most immediate enclosingDeclaration; the only place we
// could potentially add another fake scope into the chain is right here, so we don't
// traverse all ancestors.
pushFakeScope := func(kind string, addAll func(addSymbol func(name string, symbol *ast.Symbol))) func() {
// We only ever need to look two declarations upward.
debug.AssertIsDefined(b.ctx.enclosingDeclaration)
var existingFakeScope *ast.Node
if b.links.Has(b.ctx.enclosingDeclaration) {
links := b.links.Get(b.ctx.enclosingDeclaration)
if links.fakeScopeForSignatureDeclaration != nil && *links.fakeScopeForSignatureDeclaration == kind {
existingFakeScope = b.ctx.enclosingDeclaration
}
}
if existingFakeScope == nil && b.ctx.enclosingDeclaration.Parent != nil {
if b.links.Has(b.ctx.enclosingDeclaration.Parent) {
links := b.links.Get(b.ctx.enclosingDeclaration.Parent)
if links.fakeScopeForSignatureDeclaration != nil && *links.fakeScopeForSignatureDeclaration == kind {
existingFakeScope = b.ctx.enclosingDeclaration.Parent
}
}
}
debug.AssertOptionalNode(existingFakeScope, ast.IsBlock)
var locals ast.SymbolTable
if existingFakeScope != nil {
locals = existingFakeScope.Locals()
}
if locals == nil {
locals = make(ast.SymbolTable)
}
newLocals := []string{}
oldLocals := []localsRecord{}
addAll(func(name string, symbol *ast.Symbol) {
// Add cleanup information only if we don't own the fake scope
if existingFakeScope != nil {
oldSymbol, ok := locals[name]
if !ok || oldSymbol == nil {
newLocals = append(newLocals, name)
} else {
oldLocals = append(oldLocals, localsRecord{name, oldSymbol})
}
}
locals[name] = symbol
})
if existingFakeScope == nil {
// Use a Block for this; the type of the node doesn't matter so long as it
// has locals, and this is cheaper/easier than using a function-ish Node.
fakeScope := b.f.NewBlock(b.f.NewNodeList([]*ast.Node{}), false)
b.links.Get(fakeScope).fakeScopeForSignatureDeclaration = &kind
data := fakeScope.LocalsContainerData()
data.Locals = locals
fakeScope.Parent = b.ctx.enclosingDeclaration
b.ctx.enclosingDeclaration = fakeScope
return nil
} else {
// We did not create the current scope, so we have to clean it up
undo := func() {
for _, s := range newLocals {
delete(locals, s)
}
for _, s := range oldLocals {
locals[s.name] = s.oldSymbol
}
}
return undo
}
}
if expandedParams == nil || !core.Some(expandedParams, func(p *ast.Symbol) bool { return p != nil }) {
cleanupParams = nil
} else {
cleanupParams = pushFakeScope("params", func(add func(name string, symbol *ast.Symbol)) {
if expandedParams == nil {
return
}
for pIndex, param := range expandedParams {
var originalParam *ast.Symbol
if pIndex < len(originalParameters) {
originalParam = (originalParameters)[pIndex]
}
if originalParameters != nil && originalParam != param {
// Can't reference parameters that come from an expansion
add(param.Name, b.ch.unknownSymbol)
// Can't reference the original expanded parameter either
if originalParam != nil {
add(originalParam.Name, b.ch.unknownSymbol)
}
} else if !core.Some(param.Declarations, func(d *ast.Node) bool {
var bindElement func(e *ast.BindingElement)
var bindPattern func(e *ast.BindingPattern)
bindPatternWorker := func(p *ast.BindingPattern) {
for _, e := range p.Elements.Nodes {
switch e.Kind {
case ast.KindOmittedExpression:
return
case ast.KindBindingElement:
bindElement(e.AsBindingElement())
return
default:
panic("Unhandled binding element kind")
}
}
}
bindElementWorker := func(e *ast.BindingElement) {
if e.Name() != nil && ast.IsBindingPattern(e.Name()) {
bindPattern(e.Name().AsBindingPattern())
return
}
symbol := b.ch.getSymbolOfDeclaration(e.AsNode())
if symbol != nil { // omitted expressions are now parsed as nameless binding patterns and also have no symbol
add(symbol.Name, symbol)
}
}
bindElement = bindElementWorker
bindPattern = bindPatternWorker
if ast.IsParameter(d) && d.Name() != nil && ast.IsBindingPattern(d.Name()) {
bindPattern(d.Name().AsBindingPattern())
return true
}
return false
}) {
add(param.Name, param)
}
}
})
}
if b.ctx.flags&nodebuilder.FlagsGenerateNamesForShadowedTypeParams != 0 && typeParameters != nil && core.Some(typeParameters, func(p *Type) bool { return p != nil }) {
cleanupTypeParams = pushFakeScope("typeParams", func(add func(name string, symbol *ast.Symbol)) {
if typeParameters == nil {
return
}
for _, typeParam := range typeParameters {
if typeParam == nil {
continue
}
typeParamName := b.typeParameterToName(typeParam).Text
add(typeParamName, typeParam.symbol)
}
})
}
}
return func() {
if cleanupParams != nil {
cleanupParams()
}
if cleanupTypeParams != nil {
cleanupTypeParams()
}
cleanupContext()
b.ctx.enclosingDeclaration = oldEnclosingDecl
b.ctx.mapper = oldMapper
}
}

View File

@ -1,379 +0,0 @@
package checker
import (
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/ast"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/core"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/nodebuilder"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/printer"
)
// TODO: Memoize once per checker to retain threadsafety
func createPrinterWithDefaults(emitContext *printer.EmitContext) *printer.Printer {
return printer.NewPrinter(printer.PrinterOptions{}, printer.PrintHandlers{}, emitContext)
}
func createPrinterWithRemoveComments(emitContext *printer.EmitContext) *printer.Printer {
return printer.NewPrinter(printer.PrinterOptions{RemoveComments: true}, printer.PrintHandlers{}, emitContext)
}
func createPrinterWithRemoveCommentsOmitTrailingSemicolon(emitContext *printer.EmitContext) *printer.Printer {
// TODO: OmitTrailingSemicolon support
return printer.NewPrinter(printer.PrinterOptions{RemoveComments: true}, printer.PrintHandlers{}, emitContext)
}
func createPrinterWithRemoveCommentsNeverAsciiEscape(emitContext *printer.EmitContext) *printer.Printer {
return printer.NewPrinter(printer.PrinterOptions{
RemoveComments: true,
NeverAsciiEscape: true,
}, printer.PrintHandlers{}, emitContext)
}
type semicolonRemoverWriter struct {
hasPendingSemicolon bool
inner printer.EmitTextWriter
}
func (s *semicolonRemoverWriter) commitSemicolon() {
if s.hasPendingSemicolon {
s.inner.WriteTrailingSemicolon(";")
s.hasPendingSemicolon = false
}
}
func (s *semicolonRemoverWriter) Clear() {
s.inner.Clear()
}
func (s *semicolonRemoverWriter) DecreaseIndent() {
s.commitSemicolon()
s.inner.DecreaseIndent()
}
func (s *semicolonRemoverWriter) GetColumn() int {
return s.inner.GetColumn()
}
func (s *semicolonRemoverWriter) GetIndent() int {
return s.inner.GetIndent()
}
func (s *semicolonRemoverWriter) GetLine() int {
return s.inner.GetLine()
}
func (s *semicolonRemoverWriter) GetTextPos() int {
return s.inner.GetTextPos()
}
func (s *semicolonRemoverWriter) HasTrailingComment() bool {
return s.inner.HasTrailingComment()
}
func (s *semicolonRemoverWriter) HasTrailingWhitespace() bool {
return s.inner.HasTrailingWhitespace()
}
func (s *semicolonRemoverWriter) IncreaseIndent() {
s.commitSemicolon()
s.inner.IncreaseIndent()
}
func (s *semicolonRemoverWriter) IsAtStartOfLine() bool {
return s.inner.IsAtStartOfLine()
}
func (s *semicolonRemoverWriter) RawWrite(s1 string) {
s.commitSemicolon()
s.inner.RawWrite(s1)
}
func (s *semicolonRemoverWriter) String() string {
s.commitSemicolon()
return s.inner.String()
}
func (s *semicolonRemoverWriter) Write(s1 string) {
s.commitSemicolon()
s.inner.Write(s1)
}
func (s *semicolonRemoverWriter) WriteComment(text string) {
s.commitSemicolon()
s.inner.WriteComment(text)
}
func (s *semicolonRemoverWriter) WriteKeyword(text string) {
s.commitSemicolon()
s.inner.WriteKeyword(text)
}
func (s *semicolonRemoverWriter) WriteLine() {
s.commitSemicolon()
s.inner.WriteLine()
}
func (s *semicolonRemoverWriter) WriteLineForce(force bool) {
s.commitSemicolon()
s.inner.WriteLineForce(force)
}
func (s *semicolonRemoverWriter) WriteLiteral(s1 string) {
s.commitSemicolon()
s.inner.WriteLiteral(s1)
}
func (s *semicolonRemoverWriter) WriteOperator(text string) {
s.commitSemicolon()
s.inner.WriteOperator(text)
}
func (s *semicolonRemoverWriter) WriteParameter(text string) {
s.commitSemicolon()
s.inner.WriteParameter(text)
}
func (s *semicolonRemoverWriter) WriteProperty(text string) {
s.commitSemicolon()
s.inner.WriteProperty(text)
}
func (s *semicolonRemoverWriter) WritePunctuation(text string) {
s.commitSemicolon()
s.inner.WritePunctuation(text)
}
func (s *semicolonRemoverWriter) WriteSpace(text string) {
s.commitSemicolon()
s.inner.WriteSpace(text)
}
func (s *semicolonRemoverWriter) WriteStringLiteral(text string) {
s.commitSemicolon()
s.inner.WriteStringLiteral(text)
}
func (s *semicolonRemoverWriter) WriteSymbol(text string, symbol *ast.Symbol) {
s.commitSemicolon()
s.inner.WriteSymbol(text, symbol)
}
func (s *semicolonRemoverWriter) WriteTrailingSemicolon(text string) {
s.hasPendingSemicolon = true
}
func getTrailingSemicolonDeferringWriter(writer printer.EmitTextWriter) printer.EmitTextWriter {
return &semicolonRemoverWriter{false, writer}
}
func (c *Checker) TypeToString(t *Type) string {
return c.typeToString(t, nil)
}
func (c *Checker) typeToString(t *Type, enclosingDeclaration *ast.Node) string {
return c.typeToStringEx(t, enclosingDeclaration, TypeFormatFlagsAllowUniqueESSymbolType|TypeFormatFlagsUseAliasDefinedOutsideCurrentScope)
}
func toNodeBuilderFlags(flags TypeFormatFlags) nodebuilder.Flags {
return nodebuilder.Flags(flags & TypeFormatFlagsNodeBuilderFlagsMask)
}
func (c *Checker) TypeToStringEx(t *Type, enclosingDeclaration *ast.Node, flags TypeFormatFlags) string {
return c.typeToStringEx(t, enclosingDeclaration, flags)
}
func (c *Checker) typeToStringEx(t *Type, enclosingDeclaration *ast.Node, flags TypeFormatFlags) string {
writer := printer.NewTextWriter("")
noTruncation := (c.compilerOptions.NoErrorTruncation == core.TSTrue) || (flags&TypeFormatFlagsNoTruncation != 0)
combinedFlags := toNodeBuilderFlags(flags) | nodebuilder.FlagsIgnoreErrors
if noTruncation {
combinedFlags = combinedFlags | nodebuilder.FlagsNoTruncation
}
nodeBuilder := c.getNodeBuilder()
typeNode := nodeBuilder.TypeToTypeNode(t, enclosingDeclaration, combinedFlags, nodebuilder.InternalFlagsNone, nil)
if typeNode == nil {
panic("should always get typenode")
}
// The unresolved type gets a synthesized comment on `any` to hint to users that it's not a plain `any`.
// Otherwise, we always strip comments out.
var printer *printer.Printer
if t == c.unresolvedType {
printer = createPrinterWithDefaults(nodeBuilder.EmitContext())
} else {
printer = createPrinterWithRemoveComments(nodeBuilder.EmitContext())
}
var sourceFile *ast.SourceFile
if enclosingDeclaration != nil {
sourceFile = ast.GetSourceFileOfNode(enclosingDeclaration)
}
printer.Write(typeNode /*sourceFile*/, sourceFile, writer, nil)
result := writer.String()
maxLength := defaultMaximumTruncationLength * 2
if noTruncation {
maxLength = noTruncationMaximumTruncationLength * 2
}
if maxLength > 0 && result != "" && len(result) >= maxLength {
return result[0:maxLength-len("...")] + "..."
}
return result
}
func (c *Checker) SymbolToString(s *ast.Symbol) string {
return c.symbolToString(s)
}
func (c *Checker) symbolToString(symbol *ast.Symbol) string {
return c.symbolToStringEx(symbol, nil, ast.SymbolFlagsAll, SymbolFormatFlagsAllowAnyNodeKind)
}
func (c *Checker) SymbolToStringEx(symbol *ast.Symbol, enclosingDeclaration *ast.Node, meaning ast.SymbolFlags, flags SymbolFormatFlags) string {
return c.symbolToStringEx(symbol, enclosingDeclaration, meaning, flags)
}
func (c *Checker) symbolToStringEx(symbol *ast.Symbol, enclosingDeclaration *ast.Node, meaning ast.SymbolFlags, flags SymbolFormatFlags) string {
writer, putWriter := printer.GetSingleLineStringWriter()
defer putWriter()
nodeFlags := nodebuilder.FlagsIgnoreErrors
internalNodeFlags := nodebuilder.InternalFlagsNone
if flags&SymbolFormatFlagsUseOnlyExternalAliasing != 0 {
nodeFlags |= nodebuilder.FlagsUseOnlyExternalAliasing
}
if flags&SymbolFormatFlagsWriteTypeParametersOrArguments != 0 {
nodeFlags |= nodebuilder.FlagsWriteTypeParametersInQualifiedName
}
if flags&SymbolFormatFlagsUseAliasDefinedOutsideCurrentScope != 0 {
nodeFlags |= nodebuilder.FlagsUseAliasDefinedOutsideCurrentScope
}
if flags&SymbolFormatFlagsDoNotIncludeSymbolChain != 0 {
internalNodeFlags |= nodebuilder.InternalFlagsDoNotIncludeSymbolChain
}
if flags&SymbolFormatFlagsWriteComputedProps != 0 {
internalNodeFlags |= nodebuilder.InternalFlagsWriteComputedProps
}
nodeBuilder := c.getNodeBuilder()
var sourceFile *ast.SourceFile
if enclosingDeclaration != nil {
sourceFile = ast.GetSourceFileOfNode(enclosingDeclaration)
}
var printer_ *printer.Printer
// add neverAsciiEscape for GH#39027
if enclosingDeclaration != nil && enclosingDeclaration.Kind == ast.KindSourceFile {
printer_ = createPrinterWithRemoveCommentsNeverAsciiEscape(nodeBuilder.EmitContext())
} else {
printer_ = createPrinterWithRemoveComments(nodeBuilder.EmitContext())
}
var builder func(symbol *ast.Symbol, meaning ast.SymbolFlags, enclosingDeclaration *ast.Node, flags nodebuilder.Flags, internalFlags nodebuilder.InternalFlags, tracker nodebuilder.SymbolTracker) *ast.Node
if flags&SymbolFormatFlagsAllowAnyNodeKind != 0 {
builder = nodeBuilder.SymbolToNode
} else {
builder = nodeBuilder.SymbolToEntityName
}
entity := builder(symbol, meaning, enclosingDeclaration, nodeFlags, internalNodeFlags, nil) // TODO: GH#18217
printer_.Write(entity /*sourceFile*/, sourceFile, getTrailingSemicolonDeferringWriter(writer), nil) // TODO: GH#18217
return writer.String()
}
func (c *Checker) signatureToString(signature *Signature) string {
return c.signatureToStringEx(signature, nil, TypeFormatFlagsNone)
}
func (c *Checker) SignatureToStringEx(signature *Signature, enclosingDeclaration *ast.Node, flags TypeFormatFlags) string {
return c.signatureToStringEx(signature, enclosingDeclaration, flags)
}
func (c *Checker) signatureToStringEx(signature *Signature, enclosingDeclaration *ast.Node, flags TypeFormatFlags) string {
isConstructor := signature.flags&SignatureFlagsConstruct != 0 && flags&TypeFormatFlagsWriteCallStyleSignature == 0
var sigOutput ast.Kind
if flags&TypeFormatFlagsWriteArrowStyleSignature != 0 {
if isConstructor {
sigOutput = ast.KindConstructorType
} else {
sigOutput = ast.KindFunctionType
}
} else {
if isConstructor {
sigOutput = ast.KindConstructSignature
} else {
sigOutput = ast.KindCallSignature
}
}
writer, putWriter := printer.GetSingleLineStringWriter()
defer putWriter()
nodeBuilder := c.getNodeBuilder()
combinedFlags := toNodeBuilderFlags(flags) | nodebuilder.FlagsIgnoreErrors | nodebuilder.FlagsWriteTypeParametersInQualifiedName
sig := nodeBuilder.SignatureToSignatureDeclaration(signature, sigOutput, enclosingDeclaration, combinedFlags, nodebuilder.InternalFlagsNone, nil)
printer_ := createPrinterWithRemoveCommentsOmitTrailingSemicolon(nodeBuilder.EmitContext())
var sourceFile *ast.SourceFile
if enclosingDeclaration != nil {
sourceFile = ast.GetSourceFileOfNode(enclosingDeclaration)
}
printer_.Write(sig /*sourceFile*/, sourceFile, getTrailingSemicolonDeferringWriter(writer), nil) // TODO: GH#18217
return writer.String()
}
func (c *Checker) typePredicateToString(typePredicate *TypePredicate) string {
return c.typePredicateToStringEx(typePredicate, nil, TypeFormatFlagsUseAliasDefinedOutsideCurrentScope)
}
func (c *Checker) typePredicateToStringEx(typePredicate *TypePredicate, enclosingDeclaration *ast.Node, flags TypeFormatFlags) string {
writer, putWriter := printer.GetSingleLineStringWriter()
defer putWriter()
nodeBuilder := c.getNodeBuilder()
combinedFlags := toNodeBuilderFlags(flags) | nodebuilder.FlagsIgnoreErrors | nodebuilder.FlagsWriteTypeParametersInQualifiedName
predicate := nodeBuilder.TypePredicateToTypePredicateNode(typePredicate, enclosingDeclaration, combinedFlags, nodebuilder.InternalFlagsNone, nil) // TODO: GH#18217
printer_ := createPrinterWithRemoveComments(nodeBuilder.EmitContext())
var sourceFile *ast.SourceFile
if enclosingDeclaration != nil {
sourceFile = ast.GetSourceFileOfNode(enclosingDeclaration)
}
printer_.Write(predicate /*sourceFile*/, sourceFile, writer, nil)
return writer.String()
}
func (c *Checker) valueToString(value any) string {
return ValueToString(value)
}
func (c *Checker) formatUnionTypes(types []*Type) []*Type {
var result []*Type
var flags TypeFlags
for i := 0; i < len(types); i++ {
t := types[i]
flags |= t.flags
if t.flags&TypeFlagsNullable == 0 {
if t.flags&(TypeFlagsBooleanLiteral|TypeFlagsEnumLike) != 0 {
var baseType *Type
if t.flags&TypeFlagsBooleanLiteral != 0 {
baseType = c.booleanType
} else {
baseType = c.getBaseTypeOfEnumLikeType(t)
}
if baseType.flags&TypeFlagsUnion != 0 {
count := len(baseType.AsUnionType().types)
if i+count <= len(types) && c.getRegularTypeOfLiteralType(types[i+count-1]) == c.getRegularTypeOfLiteralType(baseType.AsUnionType().types[count-1]) {
result = append(result, baseType)
i += count - 1
continue
}
}
}
result = append(result, t)
}
}
if flags&TypeFlagsNull != 0 {
result = append(result, c.nullType)
}
if flags&TypeFlagsUndefined != 0 {
result = append(result, c.undefinedType)
}
return result
}
func (c *Checker) TypeToTypeNode(t *Type, enclosingDeclaration *ast.Node, flags nodebuilder.Flags) *ast.TypeNode {
nodeBuilder := c.getNodeBuilder()
return nodeBuilder.TypeToTypeNode(t, enclosingDeclaration, flags, nodebuilder.InternalFlagsNone, nil)
}

File diff suppressed because it is too large Load Diff

View File

@ -1,811 +0,0 @@
package checker
import (
"maps"
"slices"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/ast"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/collections"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/core"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/printer"
)
func (c *Checker) GetSymbolsInScope(location *ast.Node, meaning ast.SymbolFlags) []*ast.Symbol {
return c.getSymbolsInScope(location, meaning)
}
func (c *Checker) getSymbolsInScope(location *ast.Node, meaning ast.SymbolFlags) []*ast.Symbol {
if location.Flags&ast.NodeFlagsInWithStatement != 0 {
// We cannot answer semantic questions within a with block, do not proceed any further
return nil
}
symbols := make(ast.SymbolTable)
isStaticSymbol := false
// Copy the given symbol into symbol tables if the symbol has the given meaning
// and it doesn't already exists in the symbol table.
copySymbol := func(symbol *ast.Symbol, meaning ast.SymbolFlags) {
if GetCombinedLocalAndExportSymbolFlags(symbol)&meaning != 0 {
id := symbol.Name
// We will copy all symbol regardless of its reserved name because
// symbolsToArray will check whether the key is a reserved name and
// it will not copy symbol with reserved name to the array
if _, ok := symbols[id]; !ok {
symbols[id] = symbol
}
}
}
copySymbols := func(source ast.SymbolTable, meaning ast.SymbolFlags) {
if meaning != 0 {
for _, symbol := range source {
copySymbol(symbol, meaning)
}
}
}
copyLocallyVisibleExportSymbols := func(source ast.SymbolTable, meaning ast.SymbolFlags) {
if meaning != 0 {
for _, symbol := range source {
// Similar condition as in `resolveNameHelper`
if ast.GetDeclarationOfKind(symbol, ast.KindExportSpecifier) == nil &&
ast.GetDeclarationOfKind(symbol, ast.KindNamespaceExport) == nil &&
symbol.Name != ast.InternalSymbolNameDefault {
copySymbol(symbol, meaning)
}
}
}
}
populateSymbols := func() {
for location != nil {
if canHaveLocals(location) && location.Locals() != nil && !ast.IsGlobalSourceFile(location) {
copySymbols(location.Locals(), meaning)
}
switch location.Kind {
case ast.KindSourceFile:
if !ast.IsExternalModule(location.AsSourceFile()) {
break
}
fallthrough
case ast.KindModuleDeclaration:
copyLocallyVisibleExportSymbols(c.getSymbolOfDeclaration(location).Exports, meaning&ast.SymbolFlagsModuleMember)
case ast.KindEnumDeclaration:
copySymbols(c.getSymbolOfDeclaration(location).Exports, meaning&ast.SymbolFlagsEnumMember)
case ast.KindClassExpression:
className := location.AsClassExpression().Name()
if className != nil {
copySymbol(location.Symbol(), meaning)
}
// this fall-through is necessary because we would like to handle
// type parameter inside class expression similar to how we handle it in classDeclaration and interface Declaration.
fallthrough
case ast.KindClassDeclaration, ast.KindInterfaceDeclaration:
// If we didn't come from static member of class or interface,
// add the type parameters into the symbol table
// (type parameters of classDeclaration/classExpression and interface are in member property of the symbol.
// Note: that the memberFlags come from previous iteration.
if !isStaticSymbol {
copySymbols(c.getMembersOfSymbol(c.getSymbolOfDeclaration(location)), meaning&ast.SymbolFlagsType)
}
case ast.KindFunctionExpression:
funcName := location.Name()
if funcName != nil {
copySymbol(location.Symbol(), meaning)
}
}
if introducesArgumentsExoticObject(location) {
copySymbol(c.argumentsSymbol, meaning)
}
isStaticSymbol = ast.IsStatic(location)
location = location.Parent
}
copySymbols(c.globals, meaning)
}
populateSymbols()
delete(symbols, ast.InternalSymbolNameThis) // Not a symbol, a keyword
return symbolsToArray(symbols)
}
func (c *Checker) GetExportsOfModule(symbol *ast.Symbol) []*ast.Symbol {
return symbolsToArray(c.getExportsOfModule(symbol))
}
func (c *Checker) ForEachExportAndPropertyOfModule(moduleSymbol *ast.Symbol, cb func(*ast.Symbol, string)) {
for key, exportedSymbol := range c.getExportsOfModule(moduleSymbol) {
if !isReservedMemberName(key) {
cb(exportedSymbol, key)
}
}
exportEquals := c.resolveExternalModuleSymbol(moduleSymbol, false /*dontResolveAlias*/)
if exportEquals == moduleSymbol {
return
}
typeOfSymbol := c.getTypeOfSymbol(exportEquals)
if !c.shouldTreatPropertiesOfExternalModuleAsExports(typeOfSymbol) {
return
}
// forEachPropertyOfType
reducedType := c.getReducedApparentType(typeOfSymbol)
if reducedType.flags&TypeFlagsStructuredType == 0 {
return
}
for name, symbol := range c.resolveStructuredTypeMembers(reducedType).members {
if c.isNamedMember(symbol, name) {
cb(symbol, name)
}
}
}
func (c *Checker) IsValidPropertyAccess(node *ast.Node, propertyName string) bool {
return c.isValidPropertyAccess(node, propertyName)
}
func (c *Checker) isValidPropertyAccess(node *ast.Node, propertyName string) bool {
switch node.Kind {
case ast.KindPropertyAccessExpression:
return c.isValidPropertyAccessWithType(node, node.Expression().Kind == ast.KindSuperKeyword, propertyName, c.getWidenedType(c.checkExpression(node.Expression())))
case ast.KindQualifiedName:
return c.isValidPropertyAccessWithType(node, false /*isSuper*/, propertyName, c.getWidenedType(c.checkExpression(node.AsQualifiedName().Left)))
case ast.KindImportType:
return c.isValidPropertyAccessWithType(node, false /*isSuper*/, propertyName, c.getTypeFromTypeNode(node))
}
panic("Unexpected node kind in isValidPropertyAccess: " + node.Kind.String())
}
func (c *Checker) isValidPropertyAccessWithType(node *ast.Node, isSuper bool, propertyName string, t *Type) bool {
// Short-circuiting for improved performance.
if IsTypeAny(t) {
return true
}
prop := c.getPropertyOfType(t, propertyName)
return prop != nil && c.isPropertyAccessible(node, isSuper, false /*isWrite*/, t, prop)
}
// Checks if an existing property access is valid for completions purposes.
// node: a property access-like node where we want to check if we can access a property.
// This node does not need to be an access of the property we are checking.
// e.g. in completions, this node will often be an incomplete property access node, as in `foo.`.
// Besides providing a location (i.e. scope) used to check property accessibility, we use this node for
// computing whether this is a `super` property access.
// type: the type whose property we are checking.
// property: the accessed property's symbol.
func (c *Checker) IsValidPropertyAccessForCompletions(node *ast.Node, t *Type, property *ast.Symbol) bool {
return c.isPropertyAccessible(
node,
node.Kind == ast.KindPropertyAccessExpression && node.Expression().Kind == ast.KindSuperKeyword,
false, /*isWrite*/
t,
property,
)
// Previously we validated the 'this' type of methods but this adversely affected performance. See #31377 for more context.
}
func (c *Checker) GetAllPossiblePropertiesOfTypes(types []*Type) []*ast.Symbol {
unionType := c.getUnionType(types)
if unionType.flags&TypeFlagsUnion == 0 {
return c.getAugmentedPropertiesOfType(unionType)
}
props := make(ast.SymbolTable)
for _, memberType := range types {
augmentedProps := c.getAugmentedPropertiesOfType(memberType)
for _, p := range augmentedProps {
if _, ok := props[p.Name]; !ok {
prop := c.createUnionOrIntersectionProperty(unionType, p.Name, false /*skipObjectFunctionPropertyAugment*/)
// May be undefined if the property is private
if prop != nil {
props[p.Name] = prop
}
}
}
}
return slices.Collect(maps.Values(props))
}
func (c *Checker) IsUnknownSymbol(symbol *ast.Symbol) bool {
return symbol == c.unknownSymbol
}
func (c *Checker) IsUndefinedSymbol(symbol *ast.Symbol) bool {
return symbol == c.undefinedSymbol
}
func (c *Checker) IsArgumentsSymbol(symbol *ast.Symbol) bool {
return symbol == c.argumentsSymbol
}
// Originally from services.ts
func (c *Checker) GetNonOptionalType(t *Type) *Type {
return c.removeOptionalTypeMarker(t)
}
func (c *Checker) GetStringIndexType(t *Type) *Type {
return c.getIndexTypeOfType(t, c.stringType)
}
func (c *Checker) GetNumberIndexType(t *Type) *Type {
return c.getIndexTypeOfType(t, c.numberType)
}
func (c *Checker) GetCallSignatures(t *Type) []*Signature {
return c.getSignaturesOfType(t, SignatureKindCall)
}
func (c *Checker) GetConstructSignatures(t *Type) []*Signature {
return c.getSignaturesOfType(t, SignatureKindConstruct)
}
func (c *Checker) GetApparentProperties(t *Type) []*ast.Symbol {
return c.getAugmentedPropertiesOfType(t)
}
func (c *Checker) getAugmentedPropertiesOfType(t *Type) []*ast.Symbol {
t = c.getApparentType(t)
propsByName := createSymbolTable(c.getPropertiesOfType(t))
var functionType *Type
if len(c.getSignaturesOfType(t, SignatureKindCall)) > 0 {
functionType = c.globalCallableFunctionType
} else if len(c.getSignaturesOfType(t, SignatureKindConstruct)) > 0 {
functionType = c.globalNewableFunctionType
}
if propsByName == nil {
propsByName = make(ast.SymbolTable)
}
if functionType != nil {
for _, p := range c.getPropertiesOfType(functionType) {
if _, ok := propsByName[p.Name]; !ok {
propsByName[p.Name] = p
}
}
}
return c.getNamedMembers(propsByName)
}
func (c *Checker) TryGetMemberInModuleExportsAndProperties(memberName string, moduleSymbol *ast.Symbol) *ast.Symbol {
symbol := c.TryGetMemberInModuleExports(memberName, moduleSymbol)
if symbol != nil {
return symbol
}
exportEquals := c.resolveExternalModuleSymbol(moduleSymbol, false /*dontResolveAlias*/)
if exportEquals == moduleSymbol {
return nil
}
t := c.getTypeOfSymbol(exportEquals)
if c.shouldTreatPropertiesOfExternalModuleAsExports(t) {
return c.getPropertyOfType(t, memberName)
}
return nil
}
func (c *Checker) TryGetMemberInModuleExports(memberName string, moduleSymbol *ast.Symbol) *ast.Symbol {
symbolTable := c.getExportsOfModule(moduleSymbol)
return symbolTable[memberName]
}
func (c *Checker) shouldTreatPropertiesOfExternalModuleAsExports(resolvedExternalModuleType *Type) bool {
return resolvedExternalModuleType.flags&TypeFlagsPrimitive == 0 ||
resolvedExternalModuleType.objectFlags&ObjectFlagsClass != 0 ||
// `isArrayOrTupleLikeType` is too expensive to use in this auto-imports hot path.
c.isArrayType(resolvedExternalModuleType) ||
isTupleType(resolvedExternalModuleType)
}
func (c *Checker) GetContextualType(node *ast.Expression, contextFlags ContextFlags) *Type {
if contextFlags&ContextFlagsCompletions != 0 {
return runWithInferenceBlockedFromSourceNode(c, node, func() *Type { return c.getContextualType(node, contextFlags) })
}
return c.getContextualType(node, contextFlags)
}
func runWithInferenceBlockedFromSourceNode[T any](c *Checker, node *ast.Node, fn func() T) T {
containingCall := ast.FindAncestor(node, ast.IsCallLikeExpression)
if containingCall != nil {
toMarkSkip := node
for {
c.skipDirectInferenceNodes.Add(toMarkSkip)
toMarkSkip = toMarkSkip.Parent
if toMarkSkip == nil || toMarkSkip == containingCall {
break
}
}
}
c.isInferencePartiallyBlocked = true
result := runWithoutResolvedSignatureCaching(c, node, fn)
c.isInferencePartiallyBlocked = false
c.skipDirectInferenceNodes.Clear()
return result
}
func GetResolvedSignatureForSignatureHelp(node *ast.Node, argumentCount int, c *Checker) (*Signature, []*Signature) {
type result struct {
signature *Signature
candidates []*Signature
}
res := runWithoutResolvedSignatureCaching(c, node, func() result {
signature, candidates := c.getResolvedSignatureWorker(node, CheckModeIsForSignatureHelp, argumentCount)
return result{signature, candidates}
})
return res.signature, res.candidates
}
func runWithoutResolvedSignatureCaching[T any](c *Checker, node *ast.Node, fn func() T) T {
ancestorNode := ast.FindAncestor(node, ast.IsCallLikeOrFunctionLikeExpression)
if ancestorNode != nil {
cachedResolvedSignatures := make(map[*SignatureLinks]*Signature)
cachedTypes := make(map[*ValueSymbolLinks]*Type)
for ancestorNode != nil {
signatureLinks := c.signatureLinks.Get(ancestorNode)
cachedResolvedSignatures[signatureLinks] = signatureLinks.resolvedSignature
signatureLinks.resolvedSignature = nil
if ast.IsFunctionExpressionOrArrowFunction(ancestorNode) {
symbolLinks := c.valueSymbolLinks.Get(c.getSymbolOfDeclaration(ancestorNode))
resolvedType := symbolLinks.resolvedType
cachedTypes[symbolLinks] = resolvedType
symbolLinks.resolvedType = nil
}
ancestorNode = ast.FindAncestor(ancestorNode.Parent, ast.IsCallLikeOrFunctionLikeExpression)
}
result := fn()
for signatureLinks, resolvedSignature := range cachedResolvedSignatures {
signatureLinks.resolvedSignature = resolvedSignature
}
for symbolLinks, resolvedType := range cachedTypes {
symbolLinks.resolvedType = resolvedType
}
return result
}
return fn()
}
func (c *Checker) SkipAlias(symbol *ast.Symbol) *ast.Symbol {
if symbol.Flags&ast.SymbolFlagsAlias != 0 {
return c.GetAliasedSymbol(symbol)
}
return symbol
}
func (c *Checker) GetRootSymbols(symbol *ast.Symbol) []*ast.Symbol {
roots := c.getImmediateRootSymbols(symbol)
if len(roots) == 0 {
return []*ast.Symbol{symbol}
}
var result []*ast.Symbol
for _, root := range roots {
result = append(result, c.GetRootSymbols(root)...)
}
return result
}
func (c *Checker) getImmediateRootSymbols(symbol *ast.Symbol) []*ast.Symbol {
if symbol.CheckFlags&ast.CheckFlagsSynthetic != 0 {
return core.MapNonNil(
c.valueSymbolLinks.Get(symbol).containingType.Types(),
func(t *Type) *ast.Symbol {
return c.getPropertyOfType(t, symbol.Name)
})
}
if symbol.Flags&ast.SymbolFlagsTransient != 0 {
if c.spreadLinks.Has(symbol) {
leftSpread := c.spreadLinks.Get(symbol).leftSpread
rightSpread := c.spreadLinks.Get(symbol).rightSpread
if leftSpread != nil {
return []*ast.Symbol{leftSpread, rightSpread}
}
}
if c.mappedSymbolLinks.Has(symbol) {
syntheticOrigin := c.mappedSymbolLinks.Get(symbol).syntheticOrigin
if syntheticOrigin != nil {
return []*ast.Symbol{syntheticOrigin}
}
}
target := c.tryGetTarget(symbol)
if target != nil {
return []*ast.Symbol{target}
}
}
return nil
}
func (c *Checker) tryGetTarget(symbol *ast.Symbol) *ast.Symbol {
var target *ast.Symbol
next := symbol
for {
if c.valueSymbolLinks.Has(next) {
next = c.valueSymbolLinks.Get(next).target
} else if c.exportTypeLinks.Has(next) {
next = c.exportTypeLinks.Get(next).target
} else {
next = nil
}
if next == nil {
break
}
target = next
}
return target
}
func (c *Checker) GetExportSymbolOfSymbol(symbol *ast.Symbol) *ast.Symbol {
return c.getMergedSymbol(core.IfElse(symbol.ExportSymbol != nil, symbol.ExportSymbol, symbol))
}
func (c *Checker) GetExportSpecifierLocalTargetSymbol(node *ast.Node) *ast.Symbol {
// node should be ExportSpecifier | Identifier
switch node.Kind {
case ast.KindExportSpecifier:
if node.Parent.Parent.AsExportDeclaration().ModuleSpecifier != nil {
return c.getExternalModuleMember(node.Parent.Parent, node, false /*dontResolveAlias*/)
}
name := node.PropertyNameOrName()
if name.Kind == ast.KindStringLiteral {
// Skip for invalid syntax like this: export { "x" }
return nil
}
return c.resolveEntityName(name, ast.SymbolFlagsValue|ast.SymbolFlagsType|ast.SymbolFlagsNamespace|ast.SymbolFlagsAlias, true /*ignoreErrors*/, false, nil)
case ast.KindIdentifier:
return c.resolveEntityName(node, ast.SymbolFlagsValue|ast.SymbolFlagsType|ast.SymbolFlagsNamespace|ast.SymbolFlagsAlias, true /*ignoreErrors*/, false, nil)
}
panic("Unhandled case in getExportSpecifierLocalTargetSymbol, node should be ExportSpecifier | Identifier")
}
func (c *Checker) GetShorthandAssignmentValueSymbol(location *ast.Node) *ast.Symbol {
if location != nil && location.Kind == ast.KindShorthandPropertyAssignment {
return c.resolveEntityName(location.Name(), ast.SymbolFlagsValue|ast.SymbolFlagsAlias, true /*ignoreErrors*/, false, nil)
}
return nil
}
/**
* Get symbols that represent parameter-property-declaration as parameter and as property declaration
* @param parameter a parameterDeclaration node
* @param parameterName a name of the parameter to get the symbols for.
* @return a tuple of two symbols
*/
func (c *Checker) GetSymbolsOfParameterPropertyDeclaration(parameter *ast.Node /*ParameterPropertyDeclaration*/, parameterName string) (*ast.Symbol, *ast.Symbol) {
constructorDeclaration := parameter.Parent
classDeclaration := parameter.Parent.Parent
parameterSymbol := c.getSymbol(constructorDeclaration.Locals(), parameterName, ast.SymbolFlagsValue)
propertySymbol := c.getSymbol(c.getMembersOfSymbol(classDeclaration.Symbol()), parameterName, ast.SymbolFlagsValue)
if parameterSymbol != nil && propertySymbol != nil {
return parameterSymbol, propertySymbol
}
panic("There should exist two symbols, one as property declaration and one as parameter declaration")
}
func (c *Checker) GetTypeArgumentConstraint(node *ast.Node) *Type {
if !ast.IsTypeNode(node) {
return nil
}
return c.getTypeArgumentConstraint(node)
}
func (c *Checker) getTypeArgumentConstraint(node *ast.Node) *Type {
typeReferenceNode := core.IfElse(ast.IsTypeReferenceType(node.Parent), node.Parent, nil)
if typeReferenceNode == nil {
return nil
}
typeParameters := c.getTypeParametersForTypeReferenceOrImport(typeReferenceNode)
if len(typeParameters) == 0 {
return nil
}
typeParamIndex := core.FindIndex(typeReferenceNode.TypeArguments(), func(n *ast.Node) bool {
return n == node
})
constraint := c.getConstraintOfTypeParameter(typeParameters[typeParamIndex])
if constraint != nil {
return c.instantiateType(
constraint,
newTypeMapper(typeParameters, c.getEffectiveTypeArguments(typeReferenceNode, typeParameters)))
}
return nil
}
func (c *Checker) IsTypeInvalidDueToUnionDiscriminant(contextualType *Type, obj *ast.Node) bool {
properties := obj.Properties()
return core.Some(properties, func(property *ast.Node) bool {
var nameType *Type
propertyName := property.Name()
if propertyName != nil {
if ast.IsJsxNamespacedName(propertyName) {
nameType = c.getStringLiteralType(propertyName.Text())
} else {
nameType = c.getLiteralTypeFromPropertyName(propertyName)
}
}
var name string
if nameType != nil && isTypeUsableAsPropertyName(nameType) {
name = getPropertyNameFromType(nameType)
}
var expected *Type
if name != "" {
expected = c.getTypeOfPropertyOfType(contextualType, name)
}
return expected != nil && isLiteralType(expected) && !c.isTypeAssignableTo(c.getTypeOfNode(property), expected)
})
}
// Unlike `getExportsOfModule`, this includes properties of an `export =` value.
func (c *Checker) GetExportsAndPropertiesOfModule(moduleSymbol *ast.Symbol) []*ast.Symbol {
exports := c.getExportsOfModuleAsArray(moduleSymbol)
exportEquals := c.resolveExternalModuleSymbol(moduleSymbol, false /*dontResolveAlias*/)
if exportEquals != moduleSymbol {
t := c.getTypeOfSymbol(exportEquals)
if c.shouldTreatPropertiesOfExternalModuleAsExports(t) {
exports = append(exports, c.getPropertiesOfType(t)...)
}
}
return exports
}
func (c *Checker) getExportsOfModuleAsArray(moduleSymbol *ast.Symbol) []*ast.Symbol {
return symbolsToArray(c.getExportsOfModule(moduleSymbol))
}
// Returns all the properties of the Jsx.IntrinsicElements interface.
func (c *Checker) GetJsxIntrinsicTagNamesAt(location *ast.Node) []*ast.Symbol {
intrinsics := c.getJsxType(JsxNames.IntrinsicElements, location)
if intrinsics == nil {
return nil
}
return c.GetPropertiesOfType(intrinsics)
}
func (c *Checker) GetContextualTypeForJsxAttribute(attribute *ast.JsxAttributeLike) *Type {
return c.getContextualTypeForJsxAttribute(attribute, ContextFlagsNone)
}
func (c *Checker) GetConstantValue(node *ast.Node) any {
if node.Kind == ast.KindEnumMember {
return c.getEnumMemberValue(node).Value
}
if c.symbolNodeLinks.Get(node).resolvedSymbol == nil {
c.checkExpressionCached(node) // ensure cached resolved symbol is set
}
symbol := c.symbolNodeLinks.Get(node).resolvedSymbol
if symbol == nil && ast.IsEntityNameExpression(node) {
symbol = c.resolveEntityName(
node,
ast.SymbolFlagsValue,
true, /*ignoreErrors*/
false, /*dontResolveAlias*/
nil /*location*/)
}
if symbol != nil && symbol.Flags&ast.SymbolFlagsEnumMember != 0 {
// inline property\index accesses only for const enums
member := symbol.ValueDeclaration
if ast.IsEnumConst(member.Parent) {
return c.getEnumMemberValue(member).Value
}
}
return nil
}
func (c *Checker) getResolvedSignatureWorker(node *ast.Node, checkMode CheckMode, argumentCount int) (*Signature, []*Signature) {
parsedNode := printer.NewEmitContext().ParseNode(node)
c.apparentArgumentCount = &argumentCount
candidatesOutArray := &[]*Signature{}
var res *Signature
if parsedNode != nil {
res = c.getResolvedSignature(parsedNode, candidatesOutArray, checkMode)
}
c.apparentArgumentCount = nil
return res, *candidatesOutArray
}
func (c *Checker) GetCandidateSignaturesForStringLiteralCompletions(call *ast.CallLikeExpression, editingArgument *ast.Node) []*Signature {
// first, get candidates when inference is blocked from the source node.
candidates := runWithInferenceBlockedFromSourceNode(c, editingArgument, func() []*Signature {
_, blockedInferenceCandidates := c.getResolvedSignatureWorker(call, CheckModeNormal, 0)
return blockedInferenceCandidates
})
candidatesSet := collections.NewSetFromItems(candidates...)
// next, get candidates where the source node is considered for inference.
otherCandidates := runWithoutResolvedSignatureCaching(c, editingArgument, func() []*Signature {
_, inferenceCandidates := c.getResolvedSignatureWorker(call, CheckModeNormal, 0)
return inferenceCandidates
})
for _, candidate := range otherCandidates {
if candidatesSet.Has(candidate) {
continue
}
candidates = append(candidates, candidate)
}
return candidates
}
func (c *Checker) GetTypeParameterAtPosition(s *Signature, pos int) *Type {
t := c.getTypeAtPosition(s, pos)
if t.IsIndex() && isThisTypeParameter(t.AsIndexType().target) {
constraint := c.getBaseConstraintOfType(t.AsIndexType().target)
if constraint != nil {
return c.getIndexType(constraint)
}
}
return t
}
func (c *Checker) GetContextualDeclarationsForObjectLiteralElement(objectLiteral *ast.Node, name string) []*ast.Node {
var result []*ast.Node
if t := c.getApparentTypeOfContextualType(objectLiteral, ContextFlagsNone); t != nil {
for _, t := range t.Distributed() {
prop := c.getPropertyOfType(t, name)
if prop != nil {
for _, declaration := range prop.Declarations {
result = core.AppendIfUnique(result, declaration)
}
} else {
for _, info := range c.getApplicableIndexInfos(t, c.getStringLiteralType(name)) {
if info.declaration != nil {
result = core.AppendIfUnique(result, info.declaration)
}
}
}
}
}
return result
}
var knownGenericTypeNames = map[string]struct{}{
"Array": {},
"ArrayLike": {},
"ReadonlyArray": {},
"Promise": {},
"PromiseLike": {},
"Iterable": {},
"IterableIterator": {},
"AsyncIterable": {},
"Set": {},
"WeakSet": {},
"ReadonlySet": {},
"Map": {},
"WeakMap": {},
"ReadonlyMap": {},
"Partial": {},
"Required": {},
"Readonly": {},
"Pick": {},
"Omit": {},
"NonNullable": {},
}
func isKnownGenericTypeName(name string) bool {
_, exists := knownGenericTypeNames[name]
return exists
}
func (c *Checker) GetFirstTypeArgumentFromKnownType(t *Type) *Type {
if t.objectFlags&ObjectFlagsReference != 0 && isKnownGenericTypeName(t.symbol.Name) {
symbol := c.getGlobalSymbol(t.symbol.Name, ast.SymbolFlagsType, nil)
if symbol != nil && symbol == t.Target().symbol {
return core.FirstOrNil(c.getTypeArguments(t))
}
}
if t.alias != nil && isKnownGenericTypeName(t.alias.symbol.Name) {
symbol := c.getGlobalSymbol(t.alias.symbol.Name, ast.SymbolFlagsType, nil)
if symbol != nil && symbol == t.alias.symbol {
return core.FirstOrNil(t.alias.typeArguments)
}
}
return nil
}
// Gets all symbols for one property. Does not get symbols for every property.
func (c *Checker) GetPropertySymbolsFromContextualType(node *ast.Node, contextualType *Type, unionSymbolOk bool) []*ast.Symbol {
name := ast.GetTextOfPropertyName(node.Name())
if name == "" {
return nil
}
if contextualType.flags&TypeFlagsUnion == 0 {
if symbol := c.getPropertyOfType(contextualType, name); symbol != nil {
return []*ast.Symbol{symbol}
}
return nil
}
filteredTypes := contextualType.Types()
if ast.IsObjectLiteralExpression(node.Parent) || ast.IsJsxAttributes(node.Parent) {
filteredTypes = core.Filter(filteredTypes, func(t *Type) bool {
return !c.IsTypeInvalidDueToUnionDiscriminant(t, node.Parent)
})
}
discriminatedPropertySymbols := core.MapNonNil(filteredTypes, func(t *Type) *ast.Symbol {
return c.getPropertyOfType(t, name)
})
if unionSymbolOk && (len(discriminatedPropertySymbols) == 0 || len(discriminatedPropertySymbols) == len(contextualType.Types())) {
if symbol := c.getPropertyOfType(contextualType, name); symbol != nil {
return []*ast.Symbol{symbol}
}
}
if len(filteredTypes) == 0 && len(discriminatedPropertySymbols) == 0 {
// Bad discriminant -- do again without discriminating
return core.MapNonNil(contextualType.Types(), func(t *Type) *ast.Symbol {
return c.getPropertyOfType(t, name)
})
}
// by eliminating duplicates we might even end up with a single symbol
// that helps with displaying better quick infos on properties of union types
return core.Deduplicate(discriminatedPropertySymbols)
}
// Gets the property symbol corresponding to the property in destructuring assignment
// 'property1' from
//
// for ( { property1: a } of elems) {
// }
//
// 'property1' at location 'a' from:
//
// [a] = [ property1, property2 ]
func (c *Checker) GetPropertySymbolOfDestructuringAssignment(location *ast.Node) *ast.Symbol {
if ast.IsArrayLiteralOrObjectLiteralDestructuringPattern(location.Parent.Parent) {
// Get the type of the object or array literal and then look for property of given name in the type
if typeOfObjectLiteral := c.getTypeOfAssignmentPattern(location.Parent.Parent); typeOfObjectLiteral != nil {
return c.getPropertyOfType(typeOfObjectLiteral, location.Text())
}
}
return nil
}
// Gets the type of object literal or array literal of destructuring assignment.
// { a } from
//
// for ( { a } of elems) {
// }
//
// [ a ] from
//
// [a] = [ some array ...]
func (c *Checker) getTypeOfAssignmentPattern(expr *ast.Node) *Type {
// If this is from "for of"
// for ( { a } of elems) {
// }
if ast.IsForOfStatement(expr.Parent) {
iteratedType := c.checkRightHandSideOfForOf(expr.Parent)
return c.checkDestructuringAssignment(expr, core.OrElse(iteratedType, c.errorType), CheckModeNormal, false)
}
// If this is from "for" initializer
// for ({a } = elems[0];.....) { }
if ast.IsBinaryExpression(expr.Parent) {
iteratedType := c.getTypeOfExpression(expr.Parent.AsBinaryExpression().Right)
return c.checkDestructuringAssignment(expr, core.OrElse(iteratedType, c.errorType), CheckModeNormal, false)
}
// If this is from nested object binding pattern
// for ({ skills: { primary, secondary } } = multiRobot, i = 0; i < 1; i++) {
if ast.IsPropertyAssignment(expr.Parent) {
node := expr.Parent.Parent
typeOfParentObjectLiteral := core.OrElse(c.getTypeOfAssignmentPattern(node), c.errorType)
propertyIndex := slices.Index(node.AsObjectLiteralExpression().Properties.Nodes, expr.Parent)
return c.checkObjectLiteralDestructuringPropertyAssignment(node, typeOfParentObjectLiteral, propertyIndex, nil, false)
}
// Array literal assignment - array destructuring pattern
node := expr.Parent
// [{ property1: p1, property2 }] = elems;
typeOfArrayLiteral := core.OrElse(c.getTypeOfAssignmentPattern(node), c.errorType)
elementType := core.OrElse(c.checkIteratedTypeOrElementType(IterationUseDestructuring, typeOfArrayLiteral, c.undefinedType, expr.Parent), c.errorType)
return c.checkArrayLiteralDestructuringElementAssignment(node, typeOfArrayLiteral, slices.Index(node.AsArrayLiteralExpression().Elements.Nodes, expr), elementType, CheckModeNormal)
}

View File

@ -1,24 +0,0 @@
// Code generated by "stringer -type=SignatureKind -output=stringer_generated.go"; DO NOT EDIT.
package checker
import "strconv"
func _() {
// An "invalid array index" compiler error signifies that the constant values have changed.
// Re-run the stringer command to generate them again.
var x [1]struct{}
_ = x[SignatureKindCall-0]
_ = x[SignatureKindConstruct-1]
}
const _SignatureKind_name = "SignatureKindCallSignatureKindConstruct"
var _SignatureKind_index = [...]uint8{0, 17, 39}
func (i SignatureKind) String() string {
if i < 0 || i >= SignatureKind(len(_SignatureKind_index)-1) {
return "SignatureKind(" + strconv.FormatInt(int64(i), 10) + ")"
}
return _SignatureKind_name[_SignatureKind_index[i]:_SignatureKind_index[i+1]]
}

View File

@ -1,759 +0,0 @@
package checker
import (
"reflect"
"slices"
"unsafe"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/ast"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/core"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/printer"
)
func (ch *Checker) IsTypeSymbolAccessible(typeSymbol *ast.Symbol, enclosingDeclaration *ast.Node) bool {
access := ch.isSymbolAccessibleWorker(typeSymbol, enclosingDeclaration, ast.SymbolFlagsType /*shouldComputeAliasesToMakeVisible*/, false /*allowModules*/, true)
return access.Accessibility == printer.SymbolAccessibilityAccessible
}
func (ch *Checker) IsValueSymbolAccessible(symbol *ast.Symbol, enclosingDeclaration *ast.Node) bool {
access := ch.isSymbolAccessibleWorker(symbol, enclosingDeclaration, ast.SymbolFlagsValue /*shouldComputeAliasesToMakeVisible*/, false /*allowModules*/, true)
return access.Accessibility == printer.SymbolAccessibilityAccessible
}
func (ch *Checker) IsSymbolAccessibleByFlags(symbol *ast.Symbol, enclosingDeclaration *ast.Node, flags ast.SymbolFlags) bool {
access := ch.isSymbolAccessibleWorker(symbol, enclosingDeclaration, flags /*shouldComputeAliasesToMakeVisible*/, false /*allowModules*/, false) // TODO: Strada bug? Why is this allowModules: false?
return access.Accessibility == printer.SymbolAccessibilityAccessible
}
func (ch *Checker) IsAnySymbolAccessible(symbols []*ast.Symbol, enclosingDeclaration *ast.Node, initialSymbol *ast.Symbol, meaning ast.SymbolFlags, shouldComputeAliasesToMakeVisible bool, allowModules bool) *printer.SymbolAccessibilityResult {
if len(symbols) == 0 {
return nil
}
var hadAccessibleChain *ast.Symbol
earlyModuleBail := false
for _, symbol := range symbols {
// Symbol is accessible if it by itself is accessible
accessibleSymbolChain := ch.getAccessibleSymbolChain(symbol, enclosingDeclaration, meaning /*useOnlyExternalAliasing*/, false)
if len(accessibleSymbolChain) > 0 {
hadAccessibleChain = symbol
// TODO: going through emit resolver here is weird. Relayer these APIs.
hasAccessibleDeclarations := ch.GetEmitResolver().hasVisibleDeclarations(accessibleSymbolChain[0], shouldComputeAliasesToMakeVisible)
if hasAccessibleDeclarations != nil {
return hasAccessibleDeclarations
}
}
if allowModules {
if core.Some(symbol.Declarations, hasNonGlobalAugmentationExternalModuleSymbol) {
if shouldComputeAliasesToMakeVisible {
earlyModuleBail = true
// Generally speaking, we want to use the aliases that already exist to refer to a module, if present
// In order to do so, we need to find those aliases in order to retain them in declaration emit; so
// if we are in declaration emit, we cannot use the fast path for module visibility until we've exhausted
// all other visibility options (in order to capture the possible aliases used to reference the module)
continue
}
// Any meaning of a module symbol is always accessible via an `import` type
return &printer.SymbolAccessibilityResult{
Accessibility: printer.SymbolAccessibilityAccessible,
}
}
}
// If we haven't got the accessible symbol, it doesn't mean the symbol is actually inaccessible.
// It could be a qualified symbol and hence verify the path
// e.g.:
// module m {
// export class c {
// }
// }
// const x: typeof m.c
// In the above example when we start with checking if typeof m.c symbol is accessible,
// we are going to see if c can be accessed in scope directly.
// But it can't, hence the accessible is going to be undefined, but that doesn't mean m.c is inaccessible
// It is accessible if the parent m is accessible because then m.c can be accessed through qualification
containers := ch.getContainersOfSymbol(symbol, enclosingDeclaration, meaning)
nextMeaning := meaning
if initialSymbol == symbol {
nextMeaning = getQualifiedLeftMeaning(meaning)
}
parentResult := ch.IsAnySymbolAccessible(containers, enclosingDeclaration, initialSymbol, nextMeaning, shouldComputeAliasesToMakeVisible, allowModules)
if parentResult != nil {
return parentResult
}
}
if earlyModuleBail {
return &printer.SymbolAccessibilityResult{
Accessibility: printer.SymbolAccessibilityAccessible,
}
}
if hadAccessibleChain != nil {
var moduleName string
if hadAccessibleChain != initialSymbol {
moduleName = ch.symbolToStringEx(hadAccessibleChain, enclosingDeclaration, ast.SymbolFlagsNamespace, SymbolFormatFlagsAllowAnyNodeKind)
}
return &printer.SymbolAccessibilityResult{
Accessibility: printer.SymbolAccessibilityNotAccessible,
ErrorSymbolName: ch.symbolToStringEx(initialSymbol, enclosingDeclaration, meaning, SymbolFormatFlagsAllowAnyNodeKind),
ErrorModuleName: moduleName,
}
}
return nil
}
func hasNonGlobalAugmentationExternalModuleSymbol(declaration *ast.Node) bool {
return ast.IsModuleWithStringLiteralName(declaration) || (declaration.Kind == ast.KindSourceFile && ast.IsExternalOrCommonJSModule(declaration.AsSourceFile()))
}
func getQualifiedLeftMeaning(rightMeaning ast.SymbolFlags) ast.SymbolFlags {
// If we are looking in value space, the parent meaning is value, other wise it is namespace
if rightMeaning == ast.SymbolFlagsValue {
return ast.SymbolFlagsValue
}
return ast.SymbolFlagsNamespace
}
func (ch *Checker) getWithAlternativeContainers(container *ast.Symbol, symbol *ast.Symbol, enclosingDeclaration *ast.Node, meaning ast.SymbolFlags) []*ast.Symbol {
additionalContainers := core.MapNonNil(container.Declarations, func(d *ast.Node) *ast.Symbol {
return ch.getFileSymbolIfFileSymbolExportEqualsContainer(d, container)
})
var reexportContainers []*ast.Symbol
if enclosingDeclaration != nil {
reexportContainers = ch.getAlternativeContainingModules(symbol, enclosingDeclaration)
}
objectLiteralContainer := ch.getVariableDeclarationOfObjectLiteral(container, meaning)
leftMeaning := getQualifiedLeftMeaning(meaning)
if enclosingDeclaration != nil &&
container.Flags&leftMeaning != 0 &&
len(ch.getAccessibleSymbolChain(container, enclosingDeclaration, ast.SymbolFlagsNamespace /*useOnlyExternalAliasing*/, false)) > 0 {
// This order expresses a preference for the real container if it is in scope
res := append(append([]*ast.Symbol{container}, additionalContainers...), reexportContainers...)
if objectLiteralContainer != nil {
res = append(res, objectLiteralContainer)
}
return res
}
// we potentially have a symbol which is a member of the instance side of something - look for a variable in scope with the container's type
// which may be acting like a namespace (eg, `Symbol` acts like a namespace when looking up `Symbol.toStringTag`)
var firstVariableMatch *ast.Symbol
if (meaning == ast.SymbolFlagsValue &&
container.Flags&leftMeaning == 0) &&
container.Flags&ast.SymbolFlagsType != 0 &&
ch.getDeclaredTypeOfSymbol(container).flags&TypeFlagsObject != 0 {
ch.someSymbolTableInScope(enclosingDeclaration, func(t ast.SymbolTable, _ bool, _ bool, _ *ast.Node) bool {
for _, s := range t {
if s.Flags&leftMeaning != 0 && ch.getTypeOfSymbol(s) == ch.getDeclaredTypeOfSymbol(container) {
firstVariableMatch = s
return true
}
}
return false
})
}
var res []*ast.Symbol
if firstVariableMatch != nil {
res = append(res, firstVariableMatch)
}
res = append(res, additionalContainers...)
res = append(res, container)
if objectLiteralContainer != nil {
res = append(res, objectLiteralContainer)
}
res = append(res, reexportContainers...)
return res
}
func (ch *Checker) getAlternativeContainingModules(symbol *ast.Symbol, enclosingDeclaration *ast.Node) []*ast.Symbol {
if enclosingDeclaration == nil {
return nil
}
containingFile := ast.GetSourceFileOfNode(enclosingDeclaration)
id := ast.GetNodeId(containingFile.AsNode())
links := ch.symbolContainerLinks.Get(symbol)
if links.extendedContainersByFile == nil {
links.extendedContainersByFile = make(map[ast.NodeId][]*ast.Symbol)
}
existing, ok := links.extendedContainersByFile[id]
if ok && existing != nil {
return existing
}
var results []*ast.Symbol
if len(containingFile.Imports()) > 0 {
// Try to make an import using an import already in the enclosing file, if possible
for _, importRef := range containingFile.Imports() {
if ast.NodeIsSynthesized(importRef) {
// Synthetic names can't be resolved by `resolveExternalModuleName` - they'll cause a debug assert if they error
continue
}
resolvedModule := ch.resolveExternalModuleName(enclosingDeclaration, importRef /*ignoreErrors*/, true)
if resolvedModule == nil {
continue
}
ref := ch.getAliasForSymbolInContainer(resolvedModule, symbol)
if ref == nil {
continue
}
results = append(results, resolvedModule)
}
if len(results) > 0 {
links.extendedContainersByFile[id] = results
return results
}
}
if links.extendedContainers != nil {
return *links.extendedContainers
}
// No results from files already being imported by this file - expand search (expensive, but not location-specific, so cached)
otherFiles := ch.program.SourceFiles()
for _, file := range otherFiles {
if !ast.IsExternalModule(file) {
continue
}
sym := ch.getSymbolOfDeclaration(file.AsNode())
ref := ch.getAliasForSymbolInContainer(sym, symbol)
if ref == nil {
continue
}
results = append(results, sym)
}
links.extendedContainers = &results
return results
}
func (ch *Checker) getVariableDeclarationOfObjectLiteral(symbol *ast.Symbol, meaning ast.SymbolFlags) *ast.Symbol {
// If we're trying to reference some object literal in, eg `var a = { x: 1 }`, the symbol for the literal, `__object`, is distinct
// from the symbol of the declaration it is being assigned to. Since we can use the declaration to refer to the literal, however,
// we'd like to make that connection here - potentially causing us to paint the declaration's visibility, and therefore the literal.
if meaning&ast.SymbolFlagsValue == 0 {
return nil
}
if len(symbol.Declarations) == 0 {
return nil
}
firstDecl := symbol.Declarations[0]
if firstDecl.Parent == nil {
return nil
}
if !ast.IsVariableDeclaration(firstDecl.Parent) {
return nil
}
if ast.IsObjectLiteralExpression(firstDecl) && firstDecl == firstDecl.Parent.Initializer() || ast.IsTypeLiteralNode(firstDecl) && firstDecl == firstDecl.Parent.Type() {
return ch.getSymbolOfDeclaration(firstDecl.Parent)
}
return nil
}
func hasExternalModuleSymbol(declaration *ast.Node) bool {
return ast.IsAmbientModule(declaration) || (declaration.Kind == ast.KindSourceFile && ast.IsExternalOrCommonJSModule(declaration.AsSourceFile()))
}
func (ch *Checker) getExternalModuleContainer(declaration *ast.Node) *ast.Symbol {
node := ast.FindAncestor(declaration, hasExternalModuleSymbol)
if node == nil {
return nil
}
return ch.getSymbolOfDeclaration(node)
}
func (ch *Checker) getFileSymbolIfFileSymbolExportEqualsContainer(d *ast.Node, container *ast.Symbol) *ast.Symbol {
fileSymbol := ch.getExternalModuleContainer(d)
if fileSymbol == nil || fileSymbol.Exports == nil {
return nil
}
exported, ok := fileSymbol.Exports[ast.InternalSymbolNameExportEquals]
if !ok || exported == nil {
return nil
}
if ch.getSymbolIfSameReference(exported, container) != nil {
return fileSymbol
}
return nil
}
/**
* Attempts to find the symbol corresponding to the container a symbol is in - usually this
* is just its' `.parent`, but for locals, this value is `undefined`
*/
func (ch *Checker) getContainersOfSymbol(symbol *ast.Symbol, enclosingDeclaration *ast.Node, meaning ast.SymbolFlags) []*ast.Symbol {
container := ch.getParentOfSymbol(symbol)
// Type parameters end up in the `members` lists but are not externally visible
if container != nil && (symbol.Flags&ast.SymbolFlagsTypeParameter == 0) {
return ch.getWithAlternativeContainers(container, symbol, enclosingDeclaration, meaning)
}
var candidates []*ast.Symbol
for _, d := range symbol.Declarations {
if !ast.IsAmbientModule(d) && d.Parent != nil {
// direct children of a module
if hasNonGlobalAugmentationExternalModuleSymbol(d.Parent) {
sym := ch.getSymbolOfDeclaration(d.Parent)
if sym != nil && !slices.Contains(candidates, sym) {
candidates = append(candidates, sym)
}
continue
}
// export ='d member of an ambient module
if ast.IsModuleBlock(d.Parent) && d.Parent.Parent != nil && ch.resolveExternalModuleSymbol(ch.getSymbolOfDeclaration(d.Parent.Parent), false) == symbol {
sym := ch.getSymbolOfDeclaration(d.Parent.Parent)
if sym != nil && !slices.Contains(candidates, sym) {
candidates = append(candidates, sym)
}
continue
}
}
if ast.IsClassExpression(d) && ast.IsBinaryExpression(d.Parent) && d.Parent.AsBinaryExpression().OperatorToken.Kind == ast.KindEqualsToken && ast.IsAccessExpression(d.Parent.AsBinaryExpression().Left) && ast.IsEntityNameExpression(d.Parent.AsBinaryExpression().Left.Expression()) {
if ast.IsModuleExportsAccessExpression(d.Parent.AsBinaryExpression().Left) || ast.IsExportsIdentifier(d.Parent.AsBinaryExpression().Left.Expression()) {
sym := ch.getSymbolOfDeclaration(ast.GetSourceFileOfNode(d).AsNode())
if sym != nil && !slices.Contains(candidates, sym) {
candidates = append(candidates, sym)
}
continue
}
ch.checkExpressionCached(d.Parent.AsBinaryExpression().Left.Expression())
sym := ch.symbolNodeLinks.Get(d.Parent.AsBinaryExpression().Left.Expression()).resolvedSymbol
if sym != nil && !slices.Contains(candidates, sym) {
candidates = append(candidates, sym)
}
continue
}
}
if len(candidates) == 0 {
return nil
}
var bestContainers []*ast.Symbol
var alternativeContainers []*ast.Symbol
for _, container := range candidates {
if ch.getAliasForSymbolInContainer(container, symbol) == nil {
continue
}
allAlts := ch.getWithAlternativeContainers(container, symbol, enclosingDeclaration, meaning)
if len(allAlts) == 0 {
continue
}
bestContainers = append(bestContainers, allAlts[0])
alternativeContainers = append(alternativeContainers, allAlts[1:]...)
}
return append(bestContainers, alternativeContainers...)
}
func (ch *Checker) getAliasForSymbolInContainer(container *ast.Symbol, symbol *ast.Symbol) *ast.Symbol {
if container == ch.getParentOfSymbol(symbol) {
// fast path, `symbol` is either already the alias or isn't aliased
return symbol
}
// Check if container is a thing with an `export=` which points directly at `symbol`, and if so, return
// the container itself as the alias for the symbol
if container.Exports != nil {
exportEquals, ok := container.Exports[ast.InternalSymbolNameExportEquals]
if ok && exportEquals != nil && ch.getSymbolIfSameReference(exportEquals, symbol) != nil {
return container
}
}
exports := ch.getExportsOfSymbol(container)
quick, ok := exports[symbol.Name]
if ok && quick != nil && ch.getSymbolIfSameReference(quick, symbol) != nil {
return quick
}
var candidates []*ast.Symbol
for _, exported := range exports {
if ch.getSymbolIfSameReference(exported, symbol) != nil {
candidates = append(candidates, exported)
}
}
if len(candidates) > 0 {
ch.sortSymbols(candidates) // _must_ sort exports for stable results - symbol table is randomly iterated
return candidates[0]
}
return nil
}
func (ch *Checker) getAccessibleSymbolChain(
symbol *ast.Symbol,
enclosingDeclaration *ast.Node,
meaning ast.SymbolFlags,
useOnlyExternalAliasing bool,
) []*ast.Symbol {
return ch.getAccessibleSymbolChainEx(accessibleSymbolChainContext{symbol, enclosingDeclaration, meaning, useOnlyExternalAliasing, make(map[ast.SymbolId]map[unsafe.Pointer]struct{})})
}
func (ch *Checker) GetAccessibleSymbolChain(
symbol *ast.Symbol,
enclosingDeclaration *ast.Node,
meaning ast.SymbolFlags,
useOnlyExternalAliasing bool,
) []*ast.Symbol {
return ch.getAccessibleSymbolChain(symbol, enclosingDeclaration, meaning, useOnlyExternalAliasing)
}
type accessibleSymbolChainContext struct {
symbol *ast.Symbol
enclosingDeclaration *ast.Node
meaning ast.SymbolFlags
useOnlyExternalAliasing bool
visitedSymbolTablesMap map[ast.SymbolId]map[unsafe.Pointer]struct{}
}
func (ch *Checker) getAccessibleSymbolChainEx(ctx accessibleSymbolChainContext) []*ast.Symbol {
if ctx.symbol == nil {
return nil
}
if isPropertyOrMethodDeclarationSymbol(ctx.symbol) {
return nil
}
// Go from enclosingDeclaration to the first scope we check, so the cache is keyed off the scope and thus shared more
var firstRelevantLocation *ast.Node
ch.someSymbolTableInScope(ctx.enclosingDeclaration, func(_ ast.SymbolTable, _ bool, _ bool, node *ast.Node) bool {
firstRelevantLocation = node
return true
})
links := ch.symbolContainerLinks.Get(ctx.symbol)
linkKey := accessibleChainCacheKey{ctx.useOnlyExternalAliasing, firstRelevantLocation, ctx.meaning}
if links.accessibleChainCache == nil {
links.accessibleChainCache = make(map[accessibleChainCacheKey][]*ast.Symbol)
}
existing, ok := links.accessibleChainCache[linkKey]
if ok {
return existing
}
var result []*ast.Symbol
ch.someSymbolTableInScope(ctx.enclosingDeclaration, func(t ast.SymbolTable, ignoreQualification bool, isLocalNameLookup bool, _ *ast.Node) bool {
res := ch.getAccessibleSymbolChainFromSymbolTable(ctx, t, ignoreQualification, isLocalNameLookup)
if len(res) > 0 {
result = res
return true
}
return false
})
links.accessibleChainCache[linkKey] = result
return result
}
/**
* @param {ignoreQualification} boolean Set when a symbol is being looked for through the exports of another symbol (meaning we have a route to qualify it already)
*/
func (ch *Checker) getAccessibleSymbolChainFromSymbolTable(ctx accessibleSymbolChainContext, t ast.SymbolTable, ignoreQualification bool, isLocalNameLookup bool) []*ast.Symbol {
symId := ast.GetSymbolId(ctx.symbol)
visitedSymbolTables, ok := ctx.visitedSymbolTablesMap[symId]
if !ok {
visitedSymbolTables = make(map[unsafe.Pointer]struct{})
ctx.visitedSymbolTablesMap[symId] = visitedSymbolTables
}
id := reflect.ValueOf(t).UnsafePointer() // TODO: Is this seriously the only way to check reference equality of maps?
_, present := visitedSymbolTables[id]
if present {
return nil
}
visitedSymbolTables[id] = struct{}{}
res := ch.trySymbolTable(ctx, t, ignoreQualification, isLocalNameLookup)
delete(visitedSymbolTables, id)
return res
}
func (ch *Checker) trySymbolTable(
ctx accessibleSymbolChainContext,
symbols ast.SymbolTable,
ignoreQualification bool,
isLocalNameLookup bool,
) []*ast.Symbol {
// If symbol is directly available by its name in the symbol table
res, ok := symbols[ctx.symbol.Name]
if ok && res != nil && ch.isAccessible(ctx, res /*resolvedAliasSymbol*/, nil, ignoreQualification) {
return []*ast.Symbol{ctx.symbol}
}
var candidateChains [][]*ast.Symbol
// collect all possible chains to sort them and return the shortest/best
for _, symbolFromSymbolTable := range symbols {
// for every non-default, non-export= alias symbol in scope, check if it refers to or can chain to the target symbol
if symbolFromSymbolTable.Flags&ast.SymbolFlagsAlias != 0 &&
symbolFromSymbolTable.Name != ast.InternalSymbolNameExportEquals &&
symbolFromSymbolTable.Name != ast.InternalSymbolNameDefault &&
!(isUMDExportSymbol(symbolFromSymbolTable) && ctx.enclosingDeclaration != nil && ast.IsExternalModule(ast.GetSourceFileOfNode(ctx.enclosingDeclaration))) &&
// If `!useOnlyExternalAliasing`, we can use any type of alias to get the name
(!ctx.useOnlyExternalAliasing || core.Some(symbolFromSymbolTable.Declarations, ast.IsExternalModuleImportEqualsDeclaration)) &&
// If we're looking up a local name to reference directly, omit namespace reexports, otherwise when we're trawling through an export list to make a dotted name, we can keep it
(isLocalNameLookup && !core.Some(symbolFromSymbolTable.Declarations, isNamespaceReexportDeclaration) || !isLocalNameLookup) &&
// While exports are generally considered to be in scope, export-specifier declared symbols are _not_
// See similar comment in `resolveName` for details
(ignoreQualification || len(getDeclarationsOfKind(symbolFromSymbolTable, ast.KindExportSpecifier)) == 0) {
resolvedImportedSymbol := ch.resolveAlias(symbolFromSymbolTable)
candidate := ch.getCandidateListForSymbol(ctx, symbolFromSymbolTable, resolvedImportedSymbol, ignoreQualification)
if len(candidate) > 0 {
candidateChains = append(candidateChains, candidate)
}
}
if symbolFromSymbolTable.Name == ctx.symbol.Name && symbolFromSymbolTable.ExportSymbol != nil {
if ch.isAccessible(ctx, ch.getMergedSymbol(symbolFromSymbolTable.ExportSymbol) /*resolvedAliasSymbol*/, nil, ignoreQualification) {
candidateChains = append(candidateChains, []*ast.Symbol{ctx.symbol})
}
}
}
if len(candidateChains) > 0 {
// pick first, shortest
slices.SortStableFunc(candidateChains, ch.compareSymbolChains)
return candidateChains[0]
}
// If there's no result and we're looking at the global symbol table, treat `globalThis` like an alias and try to lookup thru that
if reflect.ValueOf(ch.globals).UnsafePointer() == reflect.ValueOf(symbols).UnsafePointer() {
return ch.getCandidateListForSymbol(ctx, ch.globalThisSymbol, ch.globalThisSymbol, ignoreQualification)
}
return nil
}
func (ch *Checker) compareSymbolChainsWorker(a []*ast.Symbol, b []*ast.Symbol) int {
chainLen := len(a) - len(b)
if chainLen != 0 {
return chainLen
}
idx := 0
for idx < len(a) {
comparison := ch.compareSymbols(a[idx], b[idx])
if comparison != 0 {
return comparison
}
idx++
}
return 0
}
func isUMDExportSymbol(symbol *ast.Symbol) bool {
return symbol != nil && len(symbol.Declarations) > 0 && symbol.Declarations[0] != nil && ast.IsNamespaceExportDeclaration(symbol.Declarations[0])
}
func isNamespaceReexportDeclaration(node *ast.Node) bool {
return ast.IsNamespaceExport(node) && node.Parent.AsExportDeclaration().ModuleSpecifier != nil
}
func (ch *Checker) getCandidateListForSymbol(
ctx accessibleSymbolChainContext,
symbolFromSymbolTable *ast.Symbol,
resolvedImportedSymbol *ast.Symbol,
ignoreQualification bool,
) []*ast.Symbol {
if ch.isAccessible(ctx, symbolFromSymbolTable, resolvedImportedSymbol, ignoreQualification) {
return []*ast.Symbol{symbolFromSymbolTable}
}
// Look in the exported members, if we can find accessibleSymbolChain, symbol is accessible using this chain
// but only if the symbolFromSymbolTable can be qualified
candidateTable := ch.getExportsOfSymbol(resolvedImportedSymbol)
if candidateTable == nil {
return nil
}
accessibleSymbolsFromExports := ch.getAccessibleSymbolChainFromSymbolTable(ctx, candidateTable /*ignoreQualification*/, true, false)
if len(accessibleSymbolsFromExports) == 0 {
return nil
}
if !ch.canQualifySymbol(ctx, symbolFromSymbolTable, getQualifiedLeftMeaning(ctx.meaning)) {
return nil
}
return append([]*ast.Symbol{symbolFromSymbolTable}, accessibleSymbolsFromExports...)
}
func (ch *Checker) isAccessible(
ctx accessibleSymbolChainContext,
symbolFromSymbolTable *ast.Symbol,
resolvedAliasSymbol *ast.Symbol,
ignoreQualification bool,
) bool {
likeSymbols := false
if ctx.symbol == resolvedAliasSymbol {
likeSymbols = true
}
if ctx.symbol == symbolFromSymbolTable {
likeSymbols = true
}
symbol := ch.getMergedSymbol(ctx.symbol)
if symbol == ch.getMergedSymbol(resolvedAliasSymbol) {
likeSymbols = true
}
if symbol == ch.getMergedSymbol(symbolFromSymbolTable) {
likeSymbols = true
}
if !likeSymbols {
return false
}
// if the symbolFromSymbolTable is not external module (it could be if it was determined as ambient external module and would be in globals table)
// and if symbolFromSymbolTable or alias resolution matches the symbol,
// check the symbol can be qualified, it is only then this symbol is accessible
return !core.Some(symbolFromSymbolTable.Declarations, hasNonGlobalAugmentationExternalModuleSymbol) &&
(ignoreQualification || ch.canQualifySymbol(ctx, ch.getMergedSymbol(symbolFromSymbolTable), ctx.meaning))
}
func (ch *Checker) canQualifySymbol(
ctx accessibleSymbolChainContext,
symbolFromSymbolTable *ast.Symbol,
meaning ast.SymbolFlags,
) bool {
// If the symbol is equivalent and doesn't need further qualification, this symbol is accessible
return !ch.needsQualification(symbolFromSymbolTable, ctx.enclosingDeclaration, meaning) ||
// If symbol needs qualification, make sure that parent is accessible, if it is then this symbol is accessible too
len(ch.getAccessibleSymbolChainEx(accessibleSymbolChainContext{symbolFromSymbolTable.Parent, ctx.enclosingDeclaration, getQualifiedLeftMeaning(meaning), ctx.useOnlyExternalAliasing, ctx.visitedSymbolTablesMap})) > 0
}
func (ch *Checker) needsQualification(symbol *ast.Symbol, enclosingDeclaration *ast.Node, meaning ast.SymbolFlags) bool {
qualify := false
ch.someSymbolTableInScope(enclosingDeclaration, func(symbolTable ast.SymbolTable, _ bool, _ bool, _ *ast.Node) bool {
// If symbol of this name is not available in the symbol table we are ok
res, ok := symbolTable[symbol.Name]
if !ok || res == nil {
return false
}
symbolFromSymbolTable := ch.getMergedSymbol(res)
if symbolFromSymbolTable == nil {
// Continue to the next symbol table
return false
}
// If the symbol with this name is present it should refer to the symbol
if symbolFromSymbolTable == symbol {
// No need to qualify
return true
}
// Qualify if the symbol from symbol table has same meaning as expected
shouldResolveAlias := symbolFromSymbolTable.Flags&ast.SymbolFlagsAlias != 0 && ast.GetDeclarationOfKind(symbolFromSymbolTable, ast.KindExportSpecifier) == nil
if shouldResolveAlias {
symbolFromSymbolTable = ch.resolveAlias(symbolFromSymbolTable)
}
flags := symbolFromSymbolTable.Flags
if shouldResolveAlias {
flags = ch.getSymbolFlags(symbolFromSymbolTable)
}
if flags&meaning != 0 {
qualify = true
return true
}
// Continue to the next symbol table
return false
})
return qualify
}
func isPropertyOrMethodDeclarationSymbol(symbol *ast.Symbol) bool {
if len(symbol.Declarations) > 0 {
for _, declaration := range symbol.Declarations {
switch declaration.Kind {
case ast.KindPropertyDeclaration,
ast.KindMethodDeclaration,
ast.KindGetAccessor,
ast.KindSetAccessor:
continue
default:
return false
}
}
return true
}
return false
}
func (ch *Checker) someSymbolTableInScope(
enclosingDeclaration *ast.Node,
callback func(symbolTable ast.SymbolTable, ignoreQualification bool, isLocalNameLookup bool, scopeNode *ast.Node) bool,
) bool {
for location := enclosingDeclaration; location != nil; location = location.Parent {
// Locals of a source file are not in scope (because they get merged into the global symbol table)
if canHaveLocals(location) && location.Locals() != nil && !ast.IsGlobalSourceFile(location) {
if callback(location.Locals(), false, true, location) {
return true
}
}
switch location.Kind {
case ast.KindSourceFile, ast.KindModuleDeclaration:
if ast.IsSourceFile(location) && !ast.IsExternalOrCommonJSModule(location.AsSourceFile()) {
break
}
sym := ch.getSymbolOfDeclaration(location)
if callback(sym.Exports, false, true, location) {
return true
}
case ast.KindClassDeclaration, ast.KindClassExpression, ast.KindInterfaceDeclaration:
// Type parameters are bound into `members` lists so they can merge across declarations
// This is troublesome, since in all other respects, they behave like locals :cries:
// TODO: the below is shared with similar code in `resolveName` - in fact, rephrasing all this symbol
// lookup logic in terms of `resolveName` would be nice
// The below is used to lookup type parameters within a class or interface, as they are added to the class/interface locals
// These can never be latebound, so the symbol's raw members are sufficient. `getMembersOfNode` cannot be used, as it would
// trigger resolving late-bound names, which we may already be in the process of doing while we're here!
var table ast.SymbolTable
sym := ch.getSymbolOfDeclaration(location)
// TODO: Should this filtered table be cached in some way?
for key, memberSymbol := range sym.Members {
if memberSymbol.Flags&(ast.SymbolFlagsType & ^ast.SymbolFlagsAssignment) != 0 {
if table == nil {
table = make(ast.SymbolTable)
}
table[key] = memberSymbol
}
}
if table != nil && callback(table, false, false, location) {
return true
}
}
}
return callback(ch.globals, false, true, nil)
}
/**
* Check if the given symbol in given enclosing declaration is accessible and mark all associated alias to be visible if requested
*
* @param symbol a Symbol to check if accessible
* @param enclosingDeclaration a Node containing reference to the symbol
* @param meaning a SymbolFlags to check if such meaning of the symbol is accessible
* @param shouldComputeAliasToMakeVisible a boolean value to indicate whether to return aliases to be mark visible in case the symbol is accessible
*/
func (c *Checker) IsSymbolAccessible(symbol *ast.Symbol, enclosingDeclaration *ast.Node, meaning ast.SymbolFlags, shouldComputeAliasesToMakeVisible bool) printer.SymbolAccessibilityResult {
return c.isSymbolAccessibleWorker(symbol, enclosingDeclaration, meaning, shouldComputeAliasesToMakeVisible, true /*allowModules*/)
}
func (c *Checker) isSymbolAccessibleWorker(symbol *ast.Symbol, enclosingDeclaration *ast.Node, meaning ast.SymbolFlags, shouldComputeAliasesToMakeVisible bool, allowModules bool) printer.SymbolAccessibilityResult {
if symbol != nil && enclosingDeclaration != nil {
result := c.IsAnySymbolAccessible([]*ast.Symbol{symbol}, enclosingDeclaration, symbol, meaning, shouldComputeAliasesToMakeVisible, allowModules)
if result != nil {
return *result
}
// This could be a symbol that is not exported in the external module
// or it could be a symbol from different external module that is not aliased and hence cannot be named
symbolExternalModule := core.FirstNonNil(symbol.Declarations, c.getExternalModuleContainer)
if symbolExternalModule != nil {
enclosingExternalModule := c.getExternalModuleContainer(enclosingDeclaration)
if symbolExternalModule != enclosingExternalModule {
// name from different external module that is not visible
return printer.SymbolAccessibilityResult{
Accessibility: printer.SymbolAccessibilityCannotBeNamed,
ErrorSymbolName: c.symbolToStringEx(symbol, enclosingDeclaration, meaning, SymbolFormatFlagsAllowAnyNodeKind),
ErrorModuleName: c.symbolToString(symbolExternalModule),
ErrorNode: core.IfElse(ast.IsInJSFile(enclosingDeclaration), enclosingDeclaration, nil),
}
}
}
// Just a local name that is not accessible
return printer.SymbolAccessibilityResult{
Accessibility: printer.SymbolAccessibilityNotAccessible,
ErrorSymbolName: c.symbolToStringEx(symbol, enclosingDeclaration, meaning, SymbolFormatFlagsAllowAnyNodeKind),
}
}
return printer.SymbolAccessibilityResult{
Accessibility: printer.SymbolAccessibilityAccessible,
}
}

View File

@ -1,138 +0,0 @@
package checker
import (
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/ast"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/modulespecifiers"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/nodebuilder"
)
type SymbolTrackerImpl struct {
context *NodeBuilderContext
inner nodebuilder.SymbolTracker
DisableTrackSymbol bool
tchost Host
}
func NewSymbolTrackerImpl(context *NodeBuilderContext, tracker nodebuilder.SymbolTracker, tchost Host) *SymbolTrackerImpl {
if tracker != nil {
for {
t, ok := tracker.(*SymbolTrackerImpl)
if !ok {
break
}
tracker = t.inner
}
}
return &SymbolTrackerImpl{context, tracker, false, tchost}
}
func (this *SymbolTrackerImpl) GetModuleSpecifierGenerationHost() modulespecifiers.ModuleSpecifierGenerationHost {
if this.inner == nil {
return this.tchost
}
return this.inner.GetModuleSpecifierGenerationHost()
}
func (this *SymbolTrackerImpl) TrackSymbol(symbol *ast.Symbol, enclosingDeclaration *ast.Node, meaning ast.SymbolFlags) bool {
if !this.DisableTrackSymbol {
if this.inner != nil && this.inner.TrackSymbol(symbol, enclosingDeclaration, meaning) {
this.onDiagnosticReported()
return true
}
// Skip recording type parameters as they dont contribute to late painted statements
if symbol.Flags&ast.SymbolFlagsTypeParameter == 0 {
this.context.trackedSymbols = append(this.context.trackedSymbols, &TrackedSymbolArgs{symbol, enclosingDeclaration, meaning})
}
}
return false
}
func (this *SymbolTrackerImpl) ReportInaccessibleThisError() {
this.onDiagnosticReported()
if this.inner == nil {
return
}
this.inner.ReportInaccessibleThisError()
}
func (this *SymbolTrackerImpl) ReportPrivateInBaseOfClassExpression(propertyName string) {
this.onDiagnosticReported()
if this.inner == nil {
return
}
this.inner.ReportPrivateInBaseOfClassExpression(propertyName)
}
func (this *SymbolTrackerImpl) ReportInaccessibleUniqueSymbolError() {
this.onDiagnosticReported()
if this.inner == nil {
return
}
this.inner.ReportInaccessibleUniqueSymbolError()
}
func (this *SymbolTrackerImpl) ReportCyclicStructureError() {
this.onDiagnosticReported()
if this.inner == nil {
return
}
this.inner.ReportCyclicStructureError()
}
func (this *SymbolTrackerImpl) ReportLikelyUnsafeImportRequiredError(specifier string) {
this.onDiagnosticReported()
if this.inner == nil {
return
}
this.inner.ReportLikelyUnsafeImportRequiredError(specifier)
}
func (this *SymbolTrackerImpl) ReportTruncationError() {
this.onDiagnosticReported()
if this.inner == nil {
return
}
this.inner.ReportTruncationError()
}
func (this *SymbolTrackerImpl) ReportNonlocalAugmentation(containingFile *ast.SourceFile, parentSymbol *ast.Symbol, augmentingSymbol *ast.Symbol) {
this.onDiagnosticReported()
if this.inner == nil {
return
}
this.inner.ReportNonlocalAugmentation(containingFile, parentSymbol, augmentingSymbol)
}
func (this *SymbolTrackerImpl) ReportNonSerializableProperty(propertyName string) {
this.onDiagnosticReported()
if this.inner == nil {
return
}
this.inner.ReportNonSerializableProperty(propertyName)
}
func (this *SymbolTrackerImpl) onDiagnosticReported() {
this.context.reportedDiagnostic = true
}
func (this *SymbolTrackerImpl) ReportInferenceFallback(node *ast.Node) {
if this.inner == nil {
return
}
this.inner.ReportInferenceFallback(node)
}
func (this *SymbolTrackerImpl) PushErrorFallbackNode(node *ast.Node) {
if this.inner == nil {
return
}
this.inner.PushErrorFallbackNode(node)
}
func (this *SymbolTrackerImpl) PopErrorFallbackNode() {
if this.inner == nil {
return
}
this.inner.PopErrorFallbackNode()
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff