vendor tsgo

This commit is contained in:
2026-07-09 16:50:43 -04:00
parent c06ea2e5a4
commit 98978e4930
5804 changed files with 1556156 additions and 101 deletions

View File

@@ -0,0 +1,236 @@
package ls
import (
"context"
"github.com/microsoft/typescript-go/internal/ast"
"github.com/microsoft/typescript-go/internal/astnav"
"github.com/microsoft/typescript-go/internal/checker"
"github.com/microsoft/typescript-go/internal/collections"
"github.com/microsoft/typescript-go/internal/core"
"github.com/microsoft/typescript-go/internal/diagnostics"
"github.com/microsoft/typescript-go/internal/locale"
"github.com/microsoft/typescript-go/internal/ls/autoimport"
"github.com/microsoft/typescript-go/internal/ls/change"
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
"github.com/microsoft/typescript-go/internal/scanner"
)
const fixClassIncorrectlyImplementsInterfaceFixID = "fixClassIncorrectlyImplementsInterface"
var fixClassIncorrectlyImplementsInterfaceErrorCodes = []int32{
diagnostics.Class_0_incorrectly_implements_interface_1.Code(),
diagnostics.Class_0_incorrectly_implements_class_1_Did_you_mean_to_extend_1_and_inherit_its_members_as_a_subclass.Code(),
}
var FixClassIncorrectlyImplementsInterfaceProvider = &CodeFixProvider{
ErrorCodes: fixClassIncorrectlyImplementsInterfaceErrorCodes,
GetCodeActions: getCodeActionsToFixClassIncorrectlyImplementsInterface,
FixIds: []string{fixClassIncorrectlyImplementsInterfaceFixID},
GetAllCodeActions: getAllCodeActionsToFixClassIncorrectlyImplementsInterface,
}
func getCodeActionsToFixClassIncorrectlyImplementsInterface(context context.Context, fixContext *CodeFixContext) ([]*CodeAction, error) {
classDeclaration := getClass(fixContext.SourceFile, fixContext.Span)
if classDeclaration == nil {
return nil, nil
}
implementsTypes := ast.GetImplementsTypeNodes(classDeclaration)
locale := locale.FromContext(context)
typeChecker, done := fixContext.Program.GetTypeCheckerForFile(context, fixContext.SourceFile)
defer done()
var actions []*CodeAction
for _, implementedTypeNode := range implementsTypes {
changeTracker := change.NewTracker(context, fixContext.Program.Options(), fixContext.LS.FormatOptions(), fixContext.LS.converters)
importAdder, err := createImportAdder(context, fixContext, typeChecker)
if err != nil {
return nil, err
}
addChanges(context, fixContext, changeTracker, importAdder, typeChecker, classDeclaration, implementedTypeNode)
changes := getChanges(changeTracker, importAdder, fixContext.SourceFile)
if len(changes) == 0 {
continue
}
actions = append(actions, &CodeAction{
Description: diagnostics.Implement_interface_0.Localize(locale, scanner.GetTextOfNode(implementedTypeNode)),
Changes: changes,
FixID: fixClassIncorrectlyImplementsInterfaceFixID,
FixAllDescription: diagnostics.Implement_all_unimplemented_interfaces.Localize(locale),
})
}
return actions, nil
}
func getAllCodeActionsToFixClassIncorrectlyImplementsInterface(context context.Context, fixContext *CodeFixContext) (*CombinedCodeActions, error) {
typeChecker, done := fixContext.Program.GetTypeCheckerForFile(context, fixContext.SourceFile)
defer done()
changeTracker := change.NewTracker(context, fixContext.Program.Options(), fixContext.LS.FormatOptions(), fixContext.LS.converters)
importAdder, err := createImportAdder(context, fixContext, typeChecker)
if err != nil {
return nil, err
}
seenClassDeclarations := collections.Set[*ast.Node]{}
for _, diag := range getAllDiagnostics(context, fixContext.Program, fixContext.SourceFile) {
if containsErrorCode(fixClassIncorrectlyImplementsInterfaceErrorCodes, diag.Code()) {
classDeclaration := getClass(fixContext.SourceFile, core.NewTextRange(diag.Pos(), diag.End()))
if classDeclaration == nil {
continue
}
if seenClassDeclarations.AddIfAbsent(classDeclaration) {
implementsTypes := ast.GetImplementsTypeNodes(classDeclaration)
for _, implementedTypeNode := range implementsTypes {
addChanges(context, fixContext, changeTracker, importAdder, typeChecker, classDeclaration, implementedTypeNode)
}
}
}
}
changes := getChanges(changeTracker, importAdder, fixContext.SourceFile)
if len(changes) == 0 {
return nil, nil
}
return &CombinedCodeActions{
Description: diagnostics.Implement_all_unimplemented_interfaces.Localize(locale.FromContext(context)),
Changes: changes,
}, nil
}
func addChanges(context context.Context, fixContext *CodeFixContext, changeTracker *change.Tracker, importAdder autoimport.ImportAdder, typeChecker *checker.Checker, classDeclaration *ast.Node, implementedTypeNode *ast.Node) {
missingMemberFixer := newMissingMemberFixer(changeTracker, fixContext.Program, typeChecker, fixContext.LS.UserPreferences(), importAdder, locale.FromContext(context))
constructor := getConstructor(classDeclaration)
implementedType := typeChecker.GetTypeAtLocation(implementedTypeNode)
classType := typeChecker.GetTypeAtLocation(classDeclaration)
if typeChecker.GetNumberIndexType(classType) == nil {
member := missingMemberFixer.createIndexSignatureDeclarationFromType(classDeclaration, implementedType, typeChecker.GetNumberType())
if member != nil {
insertInterfaceMemberNode(changeTracker, fixContext.SourceFile, classDeclaration, constructor, member)
}
}
if typeChecker.GetStringIndexType(classType) == nil {
member := missingMemberFixer.createIndexSignatureDeclarationFromType(classDeclaration, implementedType, typeChecker.GetStringType())
if member != nil {
insertInterfaceMemberNode(changeTracker, fixContext.SourceFile, classDeclaration, constructor, member)
}
}
missingMembers := getMissingMembers(typeChecker, classDeclaration, []*checker.Type{implementedType})
for _, member := range missingMembers {
memberNodes := missingMemberFixer.createMemberFromSymbol(member, classDeclaration, fixContext.SourceFile, nil /*body*/, preserveOptionalFlagsAll)
for _, memberNode := range memberNodes {
insertInterfaceMemberNode(changeTracker, fixContext.SourceFile, classDeclaration, constructor, memberNode)
}
}
}
func getChanges(changeTracker *change.Tracker, importAdder autoimport.ImportAdder, sourceFile *ast.SourceFile) []*lsproto.TextEdit {
fileChanges := changeTracker.GetChanges()[sourceFile.FileName()]
if importAdder != nil && importAdder.HasFixes() {
fileChanges = append(fileChanges, importAdder.Edits()...)
}
return fileChanges
}
func insertInterfaceMemberNode(changeTracker *change.Tracker, sourceFile *ast.SourceFile, classDeclaration *ast.Node, constructor *ast.Node, member *ast.Node) {
if constructor == nil {
changeTracker.InsertMemberAtStart(sourceFile, classDeclaration, member)
} else {
changeTracker.InsertNodeAfter(sourceFile, constructor, member)
}
}
func getClass(sourceFile *ast.SourceFile, span core.TextRange) *ast.Node {
token := astnav.GetTokenAtPosition(sourceFile, span.Pos())
if token == nil {
return nil
}
return ast.GetContainingClass(token)
}
func getConstructor(classDeclaration *ast.Node) *ast.Node {
if classDeclaration == nil || classDeclaration.MemberList() == nil {
return nil
}
for _, member := range classDeclaration.MemberList().Nodes {
if member != nil && ast.IsConstructorDeclaration(member) {
return member
}
}
return nil
}
func getMissingMembers(typeChecker *checker.Checker, classDeclaration *ast.Node, implementedTypes []*checker.Type) []*ast.Symbol {
inheritedMembers := getInheritedMembers(typeChecker, classDeclaration)
seenMembers := make(map[string]*ast.Symbol)
var classMembers ast.SymbolTable
if classDeclaration.Symbol() != nil {
classMembers = classDeclaration.Symbol().Members
}
var missingMembers []*ast.Symbol
for _, implementedType := range implementedTypes {
for _, symbol := range typeChecker.GetPropertiesOfType(implementedType) {
if symbol == nil {
continue
}
if classMembers != nil && classMembers[symbol.Name] != nil {
continue
}
if inheritedMembers[symbol.Name] != nil || seenMembers[symbol.Name] != nil {
continue
}
flags := checker.GetDeclarationModifierFlagsFromSymbol(symbol)
if flags&ast.ModifierFlagsPrivate == 0 {
seenMembers[symbol.Name] = symbol
missingMembers = append(missingMembers, symbol)
}
}
}
return missingMembers
}
func getInheritedMembers(typeChecker *checker.Checker, classDeclaration *ast.Node) ast.SymbolTable {
typeNode := ast.GetClassExtendsHeritageElement(classDeclaration)
if typeNode == nil {
return ast.SymbolTable{}
}
baseType := typeChecker.GetTypeAtLocation(typeNode.AsNode())
if baseType == nil {
return ast.SymbolTable{}
}
inheritedMembers := make(ast.SymbolTable)
for _, symbol := range typeChecker.GetPropertiesOfType(baseType) {
if symbol == nil {
continue
}
flags := checker.GetDeclarationModifierFlagsFromSymbol(symbol)
if flags&ast.ModifierFlagsPrivate == 0 {
inheritedMembers[symbol.Name] = symbol
}
}
return inheritedMembers
}
func createImportAdder(context context.Context, fixContext *CodeFixContext, typeChecker *checker.Checker) (autoimport.ImportAdder, error) {
view, err := fixContext.LS.getPreparedAutoImportView(fixContext.SourceFile)
if err != nil {
return nil, err
}
if view == nil {
return nil, nil
}
return autoimport.NewImportAdder(context, fixContext.Program, typeChecker, fixContext.SourceFile, view, fixContext.LS.FormatOptions(), fixContext.LS.converters, fixContext.LS.UserPreferences()), nil
}