remove unused packages
This commit is contained in:
parent
b7ee86ab1d
commit
dc4c800ad4
File diff suppressed because it is too large
Load Diff
@ -1,51 +0,0 @@
|
||||
package binder
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/ast"
|
||||
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/core"
|
||||
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/parser"
|
||||
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/testutil/fixtures"
|
||||
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/tspath"
|
||||
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/vfs/osvfs"
|
||||
)
|
||||
|
||||
func BenchmarkBind(b *testing.B) {
|
||||
for _, f := range fixtures.BenchFixtures {
|
||||
b.Run(f.Name(), func(b *testing.B) {
|
||||
f.SkipIfNotExist(b)
|
||||
|
||||
fileName := tspath.GetNormalizedAbsolutePath(f.Path(), "/")
|
||||
path := tspath.ToPath(fileName, "/", osvfs.FS().UseCaseSensitiveFileNames())
|
||||
sourceText := f.ReadFile(b)
|
||||
|
||||
compilerOptions := &core.CompilerOptions{Target: core.ScriptTargetESNext, Module: core.ModuleKindNodeNext}
|
||||
sourceAffecting := compilerOptions.SourceFileAffecting()
|
||||
|
||||
parseOptions := ast.SourceFileParseOptions{
|
||||
FileName: fileName,
|
||||
Path: path,
|
||||
CompilerOptions: sourceAffecting,
|
||||
JSDocParsingMode: ast.JSDocParsingModeParseAll,
|
||||
}
|
||||
scriptKind := core.GetScriptKindFromFileName(fileName)
|
||||
|
||||
sourceFiles := make([]*ast.SourceFile, b.N)
|
||||
for i := range b.N {
|
||||
sourceFiles[i] = parser.ParseSourceFile(parseOptions, sourceText, scriptKind)
|
||||
}
|
||||
|
||||
// The above parses do a lot of work; ensure GC is finished before we start collecting performance data.
|
||||
// GC must be called twice to allow things to settle.
|
||||
runtime.GC()
|
||||
runtime.GC()
|
||||
|
||||
b.ResetTimer()
|
||||
for i := range b.N {
|
||||
BindSourceFile(sourceFiles[i])
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -1,503 +0,0 @@
|
||||
package binder
|
||||
|
||||
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"
|
||||
)
|
||||
|
||||
type NameResolver struct {
|
||||
CompilerOptions *core.CompilerOptions
|
||||
GetSymbolOfDeclaration func(node *ast.Node) *ast.Symbol
|
||||
Error func(location *ast.Node, message *diagnostics.Message, args ...any) *ast.Diagnostic
|
||||
Globals ast.SymbolTable
|
||||
ArgumentsSymbol *ast.Symbol
|
||||
RequireSymbol *ast.Symbol
|
||||
GetModuleSymbol func(sourceFile *ast.Node) *ast.Symbol
|
||||
Lookup func(symbols ast.SymbolTable, name string, meaning ast.SymbolFlags) *ast.Symbol
|
||||
SymbolReferenced func(symbol *ast.Symbol, meaning ast.SymbolFlags)
|
||||
SetRequiresScopeChangeCache func(node *ast.Node, value core.Tristate)
|
||||
GetRequiresScopeChangeCache func(node *ast.Node) core.Tristate
|
||||
OnPropertyWithInvalidInitializer func(location *ast.Node, name string, declaration *ast.Node, result *ast.Symbol) bool
|
||||
OnFailedToResolveSymbol func(location *ast.Node, name string, meaning ast.SymbolFlags, nameNotFoundMessage *diagnostics.Message)
|
||||
OnSuccessfullyResolvedSymbol func(location *ast.Node, result *ast.Symbol, meaning ast.SymbolFlags, lastLocation *ast.Node, associatedDeclarationForContainingInitializerOrBindingName *ast.Node, withinDeferredContext bool)
|
||||
}
|
||||
|
||||
func (r *NameResolver) Resolve(location *ast.Node, name string, meaning ast.SymbolFlags, nameNotFoundMessage *diagnostics.Message, isUse bool, excludeGlobals bool) *ast.Symbol {
|
||||
var result *ast.Symbol
|
||||
var lastLocation *ast.Node
|
||||
var lastSelfReferenceLocation *ast.Node
|
||||
var propertyWithInvalidInitializer *ast.Node
|
||||
var associatedDeclarationForContainingInitializerOrBindingName *ast.Node
|
||||
var withinDeferredContext bool
|
||||
var grandparent *ast.Node
|
||||
originalLocation := location // needed for did-you-mean error reporting, which gathers candidates starting from the original location
|
||||
nameIsConst := name == "const"
|
||||
loop:
|
||||
for location != nil {
|
||||
if nameIsConst && ast.IsConstAssertion(location) {
|
||||
// `const` in an `as const` has no symbol, but issues no error because there is no *actual* lookup of the type
|
||||
// (it refers to the constant type of the expression instead)
|
||||
return nil
|
||||
}
|
||||
if ast.IsModuleOrEnumDeclaration(location) && lastLocation != nil && location.Name() == lastLocation {
|
||||
// If lastLocation is the name of a namespace or enum, skip the parent since it will have is own locals that could
|
||||
// conflict.
|
||||
lastLocation = location
|
||||
location = location.Parent
|
||||
}
|
||||
locals := location.Locals()
|
||||
// Locals of a source file are not in scope (because they get merged into the global symbol table)
|
||||
if locals != nil && !ast.IsGlobalSourceFile(location) {
|
||||
result = r.lookup(locals, name, meaning)
|
||||
if result != nil {
|
||||
useResult := true
|
||||
if ast.IsFunctionLike(location) && lastLocation != nil && lastLocation != location.Body() {
|
||||
// symbol lookup restrictions for function-like declarations
|
||||
// - Type parameters of a function are in scope in the entire function declaration, including the parameter
|
||||
// list and return type. However, local types are only in scope in the function body.
|
||||
// - parameters are only in the scope of function body
|
||||
if meaning&result.Flags&ast.SymbolFlagsType != 0 {
|
||||
useResult = result.Flags&ast.SymbolFlagsTypeParameter != 0 && (lastLocation == location.Type() || ast.IsParameterLike(lastLocation))
|
||||
}
|
||||
if meaning&result.Flags&ast.SymbolFlagsVariable != 0 {
|
||||
// expression inside parameter will lookup as normal variable scope when targeting es2015+
|
||||
if r.useOuterVariableScopeInParameter(result, location, lastLocation) {
|
||||
useResult = false
|
||||
} else if result.Flags&ast.SymbolFlagsFunctionScopedVariable != 0 {
|
||||
// parameters are visible only inside function body, parameter list and return type
|
||||
// technically for parameter list case here we might mix parameters and variables declared in function,
|
||||
// however it is detected separately when checking initializers of parameters
|
||||
// to make sure that they reference no variables declared after them.
|
||||
useResult = lastLocation.Kind == ast.KindParameter ||
|
||||
lastLocation.Flags&ast.NodeFlagsSynthesized != 0 ||
|
||||
lastLocation == location.Type() && ast.FindAncestor(result.ValueDeclaration, ast.IsParameter) != nil
|
||||
}
|
||||
}
|
||||
} else if location.Kind == ast.KindConditionalType {
|
||||
// A type parameter declared using 'infer T' in a conditional type is visible only in
|
||||
// the true branch of the conditional type.
|
||||
useResult = lastLocation == location.AsConditionalTypeNode().TrueType
|
||||
}
|
||||
if useResult {
|
||||
break loop
|
||||
}
|
||||
result = nil
|
||||
}
|
||||
}
|
||||
withinDeferredContext = withinDeferredContext || getIsDeferredContext(location, lastLocation)
|
||||
switch location.Kind {
|
||||
case ast.KindSourceFile:
|
||||
if !ast.IsExternalOrCommonJSModule(location.AsSourceFile()) {
|
||||
break
|
||||
}
|
||||
fallthrough
|
||||
case ast.KindModuleDeclaration:
|
||||
moduleExports := r.getSymbolOfDeclaration(location).Exports
|
||||
if ast.IsSourceFile(location) || (ast.IsModuleDeclaration(location) && location.Flags&ast.NodeFlagsAmbient != 0 && !ast.IsGlobalScopeAugmentation(location)) {
|
||||
// It's an external module. First see if the module has an export default and if the local
|
||||
// name of that export default matches.
|
||||
result = moduleExports[ast.InternalSymbolNameDefault]
|
||||
if result != nil {
|
||||
localSymbol := GetLocalSymbolForExportDefault(result)
|
||||
if localSymbol != nil && result.Flags&meaning != 0 && localSymbol.Name == name {
|
||||
break loop
|
||||
}
|
||||
result = nil
|
||||
}
|
||||
// Because of module/namespace merging, a module's exports are in scope,
|
||||
// yet we never want to treat an export specifier as putting a member in scope.
|
||||
// Therefore, if the name we find is purely an export specifier, it is not actually considered in scope.
|
||||
// Two things to note about this:
|
||||
// 1. We have to check this without calling getSymbol. The problem with calling getSymbol
|
||||
// on an export specifier is that it might find the export specifier itself, and try to
|
||||
// resolve it as an alias. This will cause the checker to consider the export specifier
|
||||
// a circular alias reference when it might not be.
|
||||
// 2. We check === SymbolFlags.Alias in order to check that the symbol is *purely*
|
||||
// an alias. If we used &, we'd be throwing out symbols that have non alias aspects,
|
||||
// which is not the desired behavior.
|
||||
moduleExport := moduleExports[name]
|
||||
if moduleExport != nil && moduleExport.Flags == ast.SymbolFlagsAlias && (ast.GetDeclarationOfKind(moduleExport, ast.KindExportSpecifier) != nil || ast.GetDeclarationOfKind(moduleExport, ast.KindNamespaceExport) != nil) {
|
||||
break
|
||||
}
|
||||
}
|
||||
if name != ast.InternalSymbolNameDefault {
|
||||
result = r.lookup(moduleExports, name, meaning&ast.SymbolFlagsModuleMember)
|
||||
if result != nil {
|
||||
break loop
|
||||
}
|
||||
}
|
||||
case ast.KindEnumDeclaration:
|
||||
result = r.lookup(r.getSymbolOfDeclaration(location).Exports, name, meaning&ast.SymbolFlagsEnumMember)
|
||||
if result != nil {
|
||||
if nameNotFoundMessage != nil && r.CompilerOptions.GetIsolatedModules() && location.Flags&ast.NodeFlagsAmbient == 0 && ast.GetSourceFileOfNode(location) != ast.GetSourceFileOfNode(result.ValueDeclaration) {
|
||||
isolatedModulesLikeFlagName := core.IfElse(r.CompilerOptions.VerbatimModuleSyntax == core.TSTrue, "verbatimModuleSyntax", "isolatedModules")
|
||||
r.error(originalLocation, diagnostics.Cannot_access_0_from_another_file_without_qualification_when_1_is_enabled_Use_2_instead,
|
||||
name, isolatedModulesLikeFlagName, r.getSymbolOfDeclaration(location).Name+"."+name)
|
||||
}
|
||||
break loop
|
||||
}
|
||||
case ast.KindPropertyDeclaration:
|
||||
if !ast.IsStatic(location) {
|
||||
ctor := ast.FindConstructorDeclaration(location.Parent)
|
||||
if ctor != nil && ctor.Locals() != nil {
|
||||
if r.lookup(ctor.Locals(), name, meaning&ast.SymbolFlagsValue) != nil {
|
||||
// Remember the property node, it will be used later to report appropriate error
|
||||
propertyWithInvalidInitializer = location
|
||||
}
|
||||
}
|
||||
}
|
||||
case ast.KindClassDeclaration, ast.KindClassExpression, ast.KindInterfaceDeclaration:
|
||||
result = r.lookup(r.getSymbolOfDeclaration(location).Members, name, meaning&ast.SymbolFlagsType)
|
||||
if result != nil {
|
||||
if !isTypeParameterSymbolDeclaredInContainer(result, location) {
|
||||
// ignore type parameters not declared in this container
|
||||
result = nil
|
||||
break
|
||||
}
|
||||
if lastLocation != nil && ast.IsStatic(lastLocation) {
|
||||
// TypeScript 1.0 spec (April 2014): 3.4.1
|
||||
// The scope of a type parameter extends over the entire declaration with which the type
|
||||
// parameter list is associated, with the exception of static member declarations in classes.
|
||||
if nameNotFoundMessage != nil {
|
||||
r.error(originalLocation, diagnostics.Static_members_cannot_reference_class_type_parameters)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
break loop
|
||||
}
|
||||
if ast.IsClassExpression(location) && meaning&ast.SymbolFlagsClass != 0 {
|
||||
className := location.Name()
|
||||
if className != nil && name == className.Text() {
|
||||
result = location.Symbol()
|
||||
break loop
|
||||
}
|
||||
}
|
||||
case ast.KindExpressionWithTypeArguments:
|
||||
if lastLocation == location.AsExpressionWithTypeArguments().Expression && ast.IsHeritageClause(location.Parent) && location.Parent.AsHeritageClause().Token == ast.KindExtendsKeyword {
|
||||
container := location.Parent.Parent
|
||||
if ast.IsClassLike(container) {
|
||||
result = r.lookup(r.getSymbolOfDeclaration(container).Members, name, meaning&ast.SymbolFlagsType)
|
||||
if result != nil {
|
||||
if nameNotFoundMessage != nil {
|
||||
r.error(originalLocation, diagnostics.Base_class_expressions_cannot_reference_class_type_parameters)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
// It is not legal to reference a class's own type parameters from a computed property name that
|
||||
// belongs to the class. For example:
|
||||
//
|
||||
// function foo<T>() { return '' }
|
||||
// class C<T> { // <-- Class's own type parameter T
|
||||
// [foo<T>()]() { } // <-- Reference to T from class's own computed property
|
||||
// }
|
||||
case ast.KindComputedPropertyName:
|
||||
grandparent = location.Parent.Parent
|
||||
if ast.IsClassLike(grandparent) || ast.IsInterfaceDeclaration(grandparent) {
|
||||
// A reference to this grandparent's type parameters would be an error
|
||||
result = r.lookup(r.getSymbolOfDeclaration(grandparent).Members, name, meaning&ast.SymbolFlagsType)
|
||||
if result != nil {
|
||||
if nameNotFoundMessage != nil {
|
||||
r.error(originalLocation, diagnostics.A_computed_property_name_cannot_reference_a_type_parameter_from_its_containing_type)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
case ast.KindArrowFunction:
|
||||
// when targeting ES6 or higher there is no 'arguments' in an arrow function
|
||||
// for lower compile targets the resolved symbol is used to emit an error
|
||||
if r.CompilerOptions.GetEmitScriptTarget() >= core.ScriptTargetES2015 {
|
||||
break
|
||||
}
|
||||
fallthrough
|
||||
case ast.KindMethodDeclaration, ast.KindConstructor, ast.KindGetAccessor, ast.KindSetAccessor, ast.KindFunctionDeclaration:
|
||||
if meaning&ast.SymbolFlagsVariable != 0 && name == "arguments" {
|
||||
result = r.argumentsSymbol()
|
||||
break loop
|
||||
}
|
||||
case ast.KindFunctionExpression:
|
||||
if meaning&ast.SymbolFlagsVariable != 0 && name == "arguments" {
|
||||
result = r.argumentsSymbol()
|
||||
break loop
|
||||
}
|
||||
if meaning&ast.SymbolFlagsFunction != 0 {
|
||||
functionName := location.AsFunctionExpression().Name()
|
||||
if functionName != nil && name == functionName.AsIdentifier().Text {
|
||||
result = location.AsFunctionExpression().Symbol
|
||||
break loop
|
||||
}
|
||||
}
|
||||
case ast.KindDecorator:
|
||||
// Decorators are resolved at the class declaration. Resolving at the parameter
|
||||
// or member would result in looking up locals in the method.
|
||||
//
|
||||
// function y() {}
|
||||
// class C {
|
||||
// method(@y x, y) {} // <-- decorator y should be resolved at the class declaration, not the parameter.
|
||||
// }
|
||||
//
|
||||
if location.Parent != nil && location.Parent.Kind == ast.KindParameter {
|
||||
location = location.Parent
|
||||
}
|
||||
// function y() {}
|
||||
// class C {
|
||||
// @y method(x, y) {} // <-- decorator y should be resolved at the class declaration, not the method.
|
||||
// }
|
||||
//
|
||||
// class Decorators are resolved outside of the class to avoid referencing type parameters of that class.
|
||||
//
|
||||
// type T = number;
|
||||
// declare function y(x: T): any;
|
||||
// @param(1 as T) // <-- T should resolve to the type alias outside of class C
|
||||
// class C<T> {}
|
||||
if location.Parent != nil && (ast.IsClassElement(location.Parent) || location.Parent.Kind == ast.KindClassDeclaration) {
|
||||
location = location.Parent
|
||||
}
|
||||
case ast.KindParameter:
|
||||
parameterDeclaration := location.AsParameterDeclaration()
|
||||
if lastLocation != nil && (lastLocation == parameterDeclaration.Initializer ||
|
||||
lastLocation == parameterDeclaration.Name() && ast.IsBindingPattern(lastLocation)) {
|
||||
if associatedDeclarationForContainingInitializerOrBindingName == nil {
|
||||
associatedDeclarationForContainingInitializerOrBindingName = location
|
||||
}
|
||||
}
|
||||
case ast.KindBindingElement:
|
||||
bindingElement := location.AsBindingElement()
|
||||
if lastLocation != nil && (lastLocation == bindingElement.Initializer ||
|
||||
lastLocation == bindingElement.Name() && ast.IsBindingPattern(lastLocation)) {
|
||||
if ast.IsPartOfParameterDeclaration(location) && associatedDeclarationForContainingInitializerOrBindingName == nil {
|
||||
associatedDeclarationForContainingInitializerOrBindingName = location
|
||||
}
|
||||
}
|
||||
case ast.KindInferType:
|
||||
if meaning&ast.SymbolFlagsTypeParameter != 0 {
|
||||
parameterName := location.AsInferTypeNode().TypeParameter.AsTypeParameter().Name()
|
||||
if parameterName != nil && name == parameterName.AsIdentifier().Text {
|
||||
result = location.AsInferTypeNode().TypeParameter.AsTypeParameter().Symbol
|
||||
break loop
|
||||
}
|
||||
}
|
||||
case ast.KindExportSpecifier:
|
||||
exportSpecifier := location.AsExportSpecifier()
|
||||
if lastLocation != nil && lastLocation == exportSpecifier.PropertyName && location.Parent.Parent.AsExportDeclaration().ModuleSpecifier != nil {
|
||||
location = location.Parent.Parent.Parent
|
||||
}
|
||||
}
|
||||
if isSelfReferenceLocation(location, lastLocation) {
|
||||
lastSelfReferenceLocation = location
|
||||
}
|
||||
lastLocation = location
|
||||
location = location.Parent
|
||||
}
|
||||
// We just climbed up parents looking for the name, meaning that we started in a descendant node of `lastLocation`.
|
||||
// If `result === lastSelfReferenceLocation.symbol`, that means that we are somewhere inside `lastSelfReferenceLocation` looking up a name, and resolving to `lastLocation` itself.
|
||||
// That means that this is a self-reference of `lastLocation`, and shouldn't count this when considering whether `lastLocation` is used.
|
||||
if isUse && result != nil && (lastSelfReferenceLocation == nil || result != lastSelfReferenceLocation.Symbol()) {
|
||||
if r.SymbolReferenced != nil {
|
||||
r.SymbolReferenced(result, meaning)
|
||||
}
|
||||
}
|
||||
if result == nil {
|
||||
if lastLocation != nil &&
|
||||
lastLocation.Kind == ast.KindSourceFile &&
|
||||
lastLocation.AsSourceFile().CommonJSModuleIndicator != nil &&
|
||||
name == "exports" &&
|
||||
meaning&lastLocation.Symbol().Flags != 0 {
|
||||
return lastLocation.Symbol()
|
||||
}
|
||||
if lastLocation != nil &&
|
||||
r.GetModuleSymbol != nil &&
|
||||
lastLocation.Kind == ast.KindSourceFile &&
|
||||
lastLocation.AsSourceFile().CommonJSModuleIndicator != nil &&
|
||||
name == "module" &&
|
||||
originalLocation.Parent != nil &&
|
||||
ast.IsModuleExportsAccessExpression(originalLocation.Parent) &&
|
||||
meaning&lastLocation.Symbol().Flags != 0 {
|
||||
return r.GetModuleSymbol(lastLocation)
|
||||
}
|
||||
if !excludeGlobals {
|
||||
result = r.lookup(r.Globals, name, meaning|ast.SymbolFlagsGlobalLookup)
|
||||
}
|
||||
}
|
||||
if result == nil {
|
||||
if originalLocation != nil && ast.IsInJSFile(originalLocation) && originalLocation.Parent != nil {
|
||||
if ast.IsRequireCall(originalLocation.Parent, false /*requireStringLiteralLikeArgument*/) {
|
||||
return r.RequireSymbol
|
||||
}
|
||||
}
|
||||
}
|
||||
if nameNotFoundMessage != nil {
|
||||
if propertyWithInvalidInitializer != nil && r.OnPropertyWithInvalidInitializer != nil && r.OnPropertyWithInvalidInitializer(originalLocation, name, propertyWithInvalidInitializer, result) {
|
||||
return nil
|
||||
}
|
||||
if result == nil {
|
||||
if r.OnFailedToResolveSymbol != nil {
|
||||
r.OnFailedToResolveSymbol(originalLocation, name, meaning, nameNotFoundMessage)
|
||||
}
|
||||
} else {
|
||||
if r.OnSuccessfullyResolvedSymbol != nil {
|
||||
r.OnSuccessfullyResolvedSymbol(originalLocation, result, meaning, lastLocation, associatedDeclarationForContainingInitializerOrBindingName, withinDeferredContext)
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (r *NameResolver) useOuterVariableScopeInParameter(result *ast.Symbol, location *ast.Node, lastLocation *ast.Node) bool {
|
||||
if ast.IsParameter(lastLocation) {
|
||||
body := location.Body()
|
||||
if body != nil && result.ValueDeclaration != nil && result.ValueDeclaration.Pos() >= body.Pos() && result.ValueDeclaration.End() <= body.End() {
|
||||
// check for several cases where we introduce temporaries that require moving the name/initializer of the parameter to the body
|
||||
// - static field in a class expression
|
||||
// - optional chaining pre-es2020
|
||||
// - nullish coalesce pre-es2020
|
||||
// - spread assignment in binding pattern pre-es2017
|
||||
target := r.CompilerOptions.GetEmitScriptTarget()
|
||||
if target >= core.ScriptTargetES2015 {
|
||||
functionLocation := location
|
||||
declarationRequiresScopeChange := core.TSUnknown
|
||||
if r.GetRequiresScopeChangeCache != nil {
|
||||
declarationRequiresScopeChange = r.GetRequiresScopeChangeCache(functionLocation)
|
||||
}
|
||||
if declarationRequiresScopeChange == core.TSUnknown {
|
||||
declarationRequiresScopeChange = core.IfElse(core.Some(functionLocation.Parameters(), r.requiresScopeChange), core.TSTrue, core.TSFalse)
|
||||
if r.SetRequiresScopeChangeCache != nil {
|
||||
r.SetRequiresScopeChangeCache(functionLocation, declarationRequiresScopeChange)
|
||||
}
|
||||
}
|
||||
return declarationRequiresScopeChange != core.TSTrue
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (r *NameResolver) requiresScopeChange(node *ast.Node) bool {
|
||||
d := node.AsParameterDeclaration()
|
||||
return r.requiresScopeChangeWorker(d.Name()) || d.Initializer != nil && r.requiresScopeChangeWorker(d.Initializer)
|
||||
}
|
||||
|
||||
func (r *NameResolver) requiresScopeChangeWorker(node *ast.Node) bool {
|
||||
switch node.Kind {
|
||||
case ast.KindArrowFunction, ast.KindFunctionExpression, ast.KindFunctionDeclaration, ast.KindConstructor:
|
||||
return false
|
||||
case ast.KindMethodDeclaration, ast.KindGetAccessor, ast.KindSetAccessor, ast.KindPropertyAssignment:
|
||||
return r.requiresScopeChangeWorker(node.Name())
|
||||
case ast.KindPropertyDeclaration:
|
||||
if ast.HasStaticModifier(node) {
|
||||
return !r.CompilerOptions.GetEmitStandardClassFields()
|
||||
}
|
||||
return r.requiresScopeChangeWorker(node.AsPropertyDeclaration().Name())
|
||||
default:
|
||||
if ast.IsNullishCoalesce(node) || ast.IsOptionalChain(node) {
|
||||
return r.CompilerOptions.GetEmitScriptTarget() < core.ScriptTargetES2020
|
||||
}
|
||||
if ast.IsBindingElement(node) && node.AsBindingElement().DotDotDotToken != nil && ast.IsObjectBindingPattern(node.Parent) {
|
||||
return r.CompilerOptions.GetEmitScriptTarget() < core.ScriptTargetES2017
|
||||
}
|
||||
if ast.IsTypeNode(node) {
|
||||
return false
|
||||
}
|
||||
return node.ForEachChild(r.requiresScopeChangeWorker)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *NameResolver) error(location *ast.Node, message *diagnostics.Message, args ...any) {
|
||||
if r.Error != nil {
|
||||
r.Error(location, message, args...)
|
||||
}
|
||||
// Default implementation does not report errors
|
||||
}
|
||||
|
||||
func (r *NameResolver) getSymbolOfDeclaration(node *ast.Node) *ast.Symbol {
|
||||
if r.GetSymbolOfDeclaration != nil {
|
||||
return r.GetSymbolOfDeclaration(node)
|
||||
}
|
||||
|
||||
// Default implementation does not support merged symbols
|
||||
return node.Symbol()
|
||||
}
|
||||
|
||||
func (r *NameResolver) lookup(symbols ast.SymbolTable, name string, meaning ast.SymbolFlags) *ast.Symbol {
|
||||
if r.Lookup != nil {
|
||||
return r.Lookup(symbols, name, meaning)
|
||||
}
|
||||
// Default implementation does not support following aliases or merged symbols
|
||||
if meaning != 0 {
|
||||
symbol := symbols[name]
|
||||
if symbol != nil {
|
||||
if symbol.Flags&meaning != 0 {
|
||||
return symbol
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *NameResolver) argumentsSymbol() *ast.Symbol {
|
||||
if r.ArgumentsSymbol == nil {
|
||||
// Default implementation synthesizes a transient symbol for `arguments`
|
||||
r.ArgumentsSymbol = &ast.Symbol{Name: "arguments", Flags: ast.SymbolFlagsProperty | ast.SymbolFlagsTransient}
|
||||
}
|
||||
return r.ArgumentsSymbol
|
||||
}
|
||||
|
||||
func GetLocalSymbolForExportDefault(symbol *ast.Symbol) *ast.Symbol {
|
||||
if !isExportDefaultSymbol(symbol) || len(symbol.Declarations) == 0 {
|
||||
return nil
|
||||
}
|
||||
for _, decl := range symbol.Declarations {
|
||||
localSymbol := decl.LocalSymbol()
|
||||
if localSymbol != nil {
|
||||
return localSymbol
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func isExportDefaultSymbol(symbol *ast.Symbol) bool {
|
||||
return symbol != nil && len(symbol.Declarations) > 0 && ast.HasSyntacticModifier(symbol.Declarations[0], ast.ModifierFlagsDefault)
|
||||
}
|
||||
|
||||
func getIsDeferredContext(location *ast.Node, lastLocation *ast.Node) bool {
|
||||
if location.Kind != ast.KindArrowFunction && location.Kind != ast.KindFunctionExpression {
|
||||
// initializers in instance property declaration of class like entities are executed in constructor and thus deferred
|
||||
// A name is evaluated within the enclosing scope - so it shouldn't count as deferred
|
||||
return ast.IsTypeQueryNode(location) ||
|
||||
(ast.IsFunctionLikeDeclaration(location) || location.Kind == ast.KindPropertyDeclaration && !ast.IsStatic(location)) &&
|
||||
(lastLocation == nil || lastLocation != location.Name())
|
||||
}
|
||||
if lastLocation != nil && lastLocation == location.Name() {
|
||||
return false
|
||||
}
|
||||
// generator functions and async functions are not inlined in control flow when immediately invoked
|
||||
if location.BodyData().AsteriskToken != nil || ast.HasSyntacticModifier(location, ast.ModifierFlagsAsync) {
|
||||
return true
|
||||
}
|
||||
return ast.GetImmediatelyInvokedFunctionExpression(location) == nil
|
||||
}
|
||||
|
||||
func isTypeParameterSymbolDeclaredInContainer(symbol *ast.Symbol, container *ast.Node) bool {
|
||||
for _, decl := range symbol.Declarations {
|
||||
if decl.Kind == ast.KindTypeParameter {
|
||||
parent := decl.Parent
|
||||
if parent == container {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func isSelfReferenceLocation(node *ast.Node, lastLocation *ast.Node) bool {
|
||||
switch node.Kind {
|
||||
case ast.KindParameter:
|
||||
return lastLocation != nil && lastLocation == node.Name()
|
||||
case ast.KindFunctionDeclaration, ast.KindClassDeclaration, ast.KindInterfaceDeclaration, ast.KindEnumDeclaration,
|
||||
ast.KindTypeAliasDeclaration, ast.KindJSTypeAliasDeclaration, ast.KindModuleDeclaration: // For `namespace N { N; }`
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
@ -1,251 +0,0 @@
|
||||
package binder
|
||||
|
||||
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"
|
||||
)
|
||||
|
||||
type ReferenceResolver interface {
|
||||
GetReferencedExportContainer(node *ast.IdentifierNode, prefixLocals bool) *ast.Node
|
||||
GetReferencedImportDeclaration(node *ast.IdentifierNode) *ast.Declaration
|
||||
GetReferencedValueDeclaration(node *ast.IdentifierNode) *ast.Declaration
|
||||
GetReferencedValueDeclarations(node *ast.IdentifierNode) []*ast.Declaration
|
||||
GetElementAccessExpressionName(expression *ast.ElementAccessExpression) string
|
||||
}
|
||||
|
||||
type ReferenceResolverHooks struct {
|
||||
ResolveName func(location *ast.Node, name string, meaning ast.SymbolFlags, nameNotFoundMessage *diagnostics.Message, isUse bool, excludeGlobals bool) *ast.Symbol
|
||||
GetResolvedSymbol func(*ast.Node) *ast.Symbol
|
||||
GetMergedSymbol func(*ast.Symbol) *ast.Symbol
|
||||
GetParentOfSymbol func(*ast.Symbol) *ast.Symbol
|
||||
GetSymbolOfDeclaration func(*ast.Declaration) *ast.Symbol
|
||||
GetTypeOnlyAliasDeclaration func(symbol *ast.Symbol, include ast.SymbolFlags) *ast.Declaration
|
||||
GetExportSymbolOfValueSymbolIfExported func(*ast.Symbol) *ast.Symbol
|
||||
GetElementAccessExpressionName func(*ast.ElementAccessExpression) (string, bool)
|
||||
}
|
||||
|
||||
var _ ReferenceResolver = &referenceResolver{}
|
||||
|
||||
type referenceResolver struct {
|
||||
resolver *NameResolver
|
||||
options *core.CompilerOptions
|
||||
hooks ReferenceResolverHooks
|
||||
}
|
||||
|
||||
func NewReferenceResolver(options *core.CompilerOptions, hooks ReferenceResolverHooks) ReferenceResolver {
|
||||
return &referenceResolver{
|
||||
options: options,
|
||||
hooks: hooks,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *referenceResolver) getResolvedSymbol(node *ast.Node) *ast.Symbol {
|
||||
if node != nil {
|
||||
if r.hooks.GetResolvedSymbol != nil {
|
||||
return r.hooks.GetResolvedSymbol(node)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *referenceResolver) getMergedSymbol(symbol *ast.Symbol) *ast.Symbol {
|
||||
if symbol != nil {
|
||||
if r.hooks.GetMergedSymbol != nil {
|
||||
return r.hooks.GetMergedSymbol(symbol)
|
||||
}
|
||||
return symbol
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *referenceResolver) getParentOfSymbol(symbol *ast.Symbol) *ast.Symbol {
|
||||
if symbol != nil {
|
||||
if r.hooks.GetParentOfSymbol != nil {
|
||||
return r.hooks.GetParentOfSymbol(symbol)
|
||||
}
|
||||
return symbol.Parent
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *referenceResolver) getSymbolOfDeclaration(declaration *ast.Declaration) *ast.Symbol {
|
||||
if declaration != nil {
|
||||
if r.hooks.GetSymbolOfDeclaration != nil {
|
||||
return r.hooks.GetSymbolOfDeclaration(declaration)
|
||||
}
|
||||
return declaration.Symbol()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *referenceResolver) getReferencedValueSymbol(reference *ast.IdentifierNode, startInDeclarationContainer bool) *ast.Symbol {
|
||||
resolvedSymbol := r.getResolvedSymbol(reference)
|
||||
if resolvedSymbol != nil {
|
||||
return resolvedSymbol
|
||||
}
|
||||
|
||||
location := reference
|
||||
if startInDeclarationContainer && reference.Parent != nil && ast.IsDeclaration(reference.Parent) && reference.Parent.Name() == reference {
|
||||
location = ast.GetDeclarationContainer(reference.Parent)
|
||||
}
|
||||
|
||||
if r.hooks.ResolveName != nil {
|
||||
return r.hooks.ResolveName(location, reference.Text(), ast.SymbolFlagsExportValue|ast.SymbolFlagsValue|ast.SymbolFlagsAlias, nil /*nameNotFoundMessage*/, false /*isUse*/, false /*excludeGlobals*/)
|
||||
}
|
||||
|
||||
if r.resolver == nil {
|
||||
r.resolver = &NameResolver{
|
||||
CompilerOptions: r.options,
|
||||
}
|
||||
}
|
||||
|
||||
return r.resolver.Resolve(location, reference.Text(), ast.SymbolFlagsExportValue|ast.SymbolFlagsValue|ast.SymbolFlagsAlias, nil /*nameNotFoundMessage*/, false /*isUse*/, false /*excludeGlobals*/)
|
||||
}
|
||||
|
||||
func (r *referenceResolver) isTypeOnlyAliasDeclaration(symbol *ast.Symbol) bool {
|
||||
if symbol != nil {
|
||||
if r.hooks.GetTypeOnlyAliasDeclaration != nil {
|
||||
return r.hooks.GetTypeOnlyAliasDeclaration(symbol, ast.SymbolFlagsValue) != nil
|
||||
}
|
||||
|
||||
node := r.getDeclarationOfAliasSymbol(symbol)
|
||||
for node != nil {
|
||||
switch node.Kind {
|
||||
case ast.KindImportEqualsDeclaration, ast.KindExportDeclaration:
|
||||
return node.IsTypeOnly()
|
||||
case ast.KindImportClause, ast.KindImportSpecifier, ast.KindExportSpecifier:
|
||||
if node.IsTypeOnly() {
|
||||
return true
|
||||
}
|
||||
node = node.Parent
|
||||
continue
|
||||
case ast.KindNamedImports, ast.KindNamedExports:
|
||||
node = node.Parent
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (r *referenceResolver) getDeclarationOfAliasSymbol(symbol *ast.Symbol) *ast.Declaration {
|
||||
return core.FindLast(symbol.Declarations, ast.IsAliasSymbolDeclaration)
|
||||
}
|
||||
|
||||
func (r *referenceResolver) getExportSymbolOfValueSymbolIfExported(symbol *ast.Symbol) *ast.Symbol {
|
||||
if symbol != nil {
|
||||
if r.hooks.GetExportSymbolOfValueSymbolIfExported != nil {
|
||||
return r.hooks.GetExportSymbolOfValueSymbolIfExported(symbol)
|
||||
}
|
||||
if symbol.Flags&ast.SymbolFlagsExportValue != 0 && symbol.ExportSymbol != nil {
|
||||
symbol = symbol.ExportSymbol
|
||||
}
|
||||
return r.getMergedSymbol(symbol)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *referenceResolver) GetReferencedExportContainer(node *ast.IdentifierNode, prefixLocals bool) *ast.Node /*SourceFile|ModuleDeclaration|EnumDeclaration*/ {
|
||||
// When resolving the export for the name of a module or enum
|
||||
// declaration, we need to start resolution at the declaration's container.
|
||||
// Otherwise, we could incorrectly resolve the export as the
|
||||
// declaration if it contains an exported member with the same name.
|
||||
startInDeclarationContainer := node.Parent != nil && (node.Parent.Kind == ast.KindModuleDeclaration || node.Parent.Kind == ast.KindEnumDeclaration) && node == node.Parent.Name()
|
||||
if symbol := r.getReferencedValueSymbol(node, startInDeclarationContainer); symbol != nil {
|
||||
if symbol.Flags&ast.SymbolFlagsExportValue != 0 {
|
||||
// If we reference an exported entity within the same module declaration, then whether
|
||||
// we prefix depends on the kind of entity. SymbolFlags.ExportHasLocal encompasses all the
|
||||
// kinds that we do NOT prefix.
|
||||
exportSymbol := r.getMergedSymbol(symbol.ExportSymbol)
|
||||
if !prefixLocals && exportSymbol.Flags&ast.SymbolFlagsExportHasLocal != 0 && exportSymbol.Flags&ast.SymbolFlagsVariable == 0 {
|
||||
return nil
|
||||
}
|
||||
symbol = exportSymbol
|
||||
}
|
||||
parentSymbol := r.getParentOfSymbol(symbol)
|
||||
if parentSymbol != nil {
|
||||
if parentSymbol.Flags&ast.SymbolFlagsValueModule != 0 && parentSymbol.ValueDeclaration != nil && parentSymbol.ValueDeclaration.Kind == ast.KindSourceFile {
|
||||
symbolFile := parentSymbol.ValueDeclaration.AsSourceFile()
|
||||
referenceFile := ast.GetSourceFileOfNode(node)
|
||||
// If `node` accesses an export and that export isn't in the same file, then symbol is a namespace export, so return nil.
|
||||
symbolIsUmdExport := symbolFile != referenceFile
|
||||
if symbolIsUmdExport {
|
||||
return nil
|
||||
}
|
||||
return symbolFile.AsNode()
|
||||
}
|
||||
isMatchingContainer := func(n *ast.Node) bool {
|
||||
return (n.Kind == ast.KindModuleDeclaration || n.Kind == ast.KindEnumDeclaration) && r.getSymbolOfDeclaration(n) == parentSymbol
|
||||
}
|
||||
if container := ast.FindAncestor(symbol.ValueDeclaration, isMatchingContainer); container != nil {
|
||||
return container
|
||||
}
|
||||
return ast.FindAncestor(node.Parent, isMatchingContainer)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *referenceResolver) GetReferencedImportDeclaration(node *ast.IdentifierNode) *ast.Declaration {
|
||||
if symbol := r.getReferencedValueSymbol(node, false /*startInDeclarationContainer*/); symbol != nil {
|
||||
// We should only get the declaration of an alias if there isn't a local value
|
||||
// declaration for the symbol
|
||||
if ast.IsNonLocalAlias(symbol, ast.SymbolFlagsValue /*excludes*/) && !r.isTypeOnlyAliasDeclaration(symbol) {
|
||||
return r.getDeclarationOfAliasSymbol(symbol)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *referenceResolver) GetReferencedValueDeclaration(node *ast.IdentifierNode) *ast.Declaration {
|
||||
if symbol := r.getReferencedValueSymbol(node, false /*startInDeclarationContainer*/); symbol != nil {
|
||||
return r.getExportSymbolOfValueSymbolIfExported(symbol).ValueDeclaration
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *referenceResolver) GetReferencedValueDeclarations(node *ast.IdentifierNode) []*ast.Declaration {
|
||||
var declarations []*ast.Declaration
|
||||
if symbol := r.getReferencedValueSymbol(node, false /*startInDeclarationContainer*/); symbol != nil {
|
||||
symbol = r.getExportSymbolOfValueSymbolIfExported(symbol)
|
||||
for _, declaration := range symbol.Declarations {
|
||||
switch declaration.Kind {
|
||||
case ast.KindVariableDeclaration,
|
||||
ast.KindParameter,
|
||||
ast.KindBindingElement,
|
||||
ast.KindPropertyDeclaration,
|
||||
ast.KindPropertyAssignment,
|
||||
ast.KindShorthandPropertyAssignment,
|
||||
ast.KindEnumMember,
|
||||
ast.KindObjectLiteralExpression,
|
||||
ast.KindFunctionDeclaration,
|
||||
ast.KindFunctionExpression,
|
||||
ast.KindArrowFunction,
|
||||
ast.KindClassDeclaration,
|
||||
ast.KindClassExpression,
|
||||
ast.KindEnumDeclaration,
|
||||
ast.KindMethodDeclaration,
|
||||
ast.KindGetAccessor,
|
||||
ast.KindSetAccessor,
|
||||
ast.KindModuleDeclaration:
|
||||
declarations = append(declarations, declaration)
|
||||
}
|
||||
}
|
||||
}
|
||||
return declarations
|
||||
}
|
||||
|
||||
func (r *referenceResolver) GetElementAccessExpressionName(expression *ast.ElementAccessExpression) string {
|
||||
if expression != nil {
|
||||
if r.hooks.GetElementAccessExpressionName != nil {
|
||||
if name, ok := r.hooks.GetElementAccessExpressionName(expression); ok {
|
||||
return name
|
||||
}
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user