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

1226 lines
49 KiB
Go

package api
import (
"errors"
"fmt"
"github.com/microsoft/typescript-go/internal/ast"
"github.com/microsoft/typescript-go/internal/checker"
"github.com/microsoft/typescript-go/internal/core"
"github.com/microsoft/typescript-go/internal/diagnostics"
"github.com/microsoft/typescript-go/internal/jsnum"
"github.com/microsoft/typescript-go/internal/json"
"github.com/microsoft/typescript-go/internal/locale"
"github.com/microsoft/typescript-go/internal/ls/lsconv"
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
"github.com/microsoft/typescript-go/internal/project"
"github.com/microsoft/typescript-go/internal/tspath"
)
var (
ErrInvalidRequest = errors.New("api: invalid request")
ErrClientError = errors.New("api: client error")
)
type Method string
type (
SnapshotID uint64
ProjectID string
SymbolID uint64
TypeID uint32
SignatureID uint64
NodeHandle string
)
func ProjectHandle(p *project.Project) ProjectID {
return ProjectID(p.ID())
}
func SymbolHandle(symbol *ast.Symbol) SymbolID {
return SymbolID(ast.GetSymbolId(symbol))
}
func TypeHandle(t *checker.Type) TypeID {
return TypeID(t.Id())
}
func SignatureHandle(sig *checker.Signature) SignatureID {
return SignatureID(sig.Id())
}
func parseProjectHandle(handle ProjectID) tspath.Path {
return tspath.Path(handle)
}
const (
MethodRelease Method = "release"
// MethodGetServerTiming retrieves the server's collected per-request
// processing-time totals and recent-request ring buffer. It is handled by
// the connection itself (not the session) and is not recorded in the timing
// it reports.
MethodGetServerTiming Method = "getServerTiming"
// MethodResetServerTiming clears the server's collected timing totals and
// recent-request ring buffer. Like MethodGetServerTiming, it is handled by
// the connection itself and is not recorded.
MethodResetServerTiming Method = "resetServerTiming"
MethodInitialize Method = "initialize"
MethodUpdateSnapshot Method = "updateSnapshot"
MethodParseConfigFile Method = "parseConfigFile"
MethodGetDefaultProjectForFile Method = "getDefaultProjectForFile"
MethodGetSymbolAtPosition Method = "getSymbolAtPosition"
MethodGetSymbolsAtPositions Method = "getSymbolsAtPositions"
MethodGetSymbolAtLocation Method = "getSymbolAtLocation"
MethodGetSymbolsAtLocations Method = "getSymbolsAtLocations"
MethodGetTypeOfSymbol Method = "getTypeOfSymbol"
MethodGetTypesOfSymbols Method = "getTypesOfSymbols"
MethodGetDeclaredTypeOfSymbol Method = "getDeclaredTypeOfSymbol"
MethodGetSourceFile Method = "getSourceFile"
MethodGetSourceFileNames Method = "getSourceFileNames"
MethodGetSourceFileMetadata Method = "getSourceFileMetadata"
MethodResolveName Method = "resolveName"
MethodGetSignaturesOfType Method = "getSignaturesOfType"
MethodGetResolvedSignature Method = "getResolvedSignature"
MethodGetTypeAtLocation Method = "getTypeAtLocation"
MethodGetTypeAtLocations Method = "getTypeAtLocations"
MethodGetTypeAtPosition Method = "getTypeAtPosition"
MethodGetTypesAtPositions Method = "getTypesAtPositions"
// Symbol sub-property methods
MethodGetParentOfSymbol Method = "getParentOfSymbol"
MethodGetMembersOfSymbol Method = "getMembersOfSymbol"
MethodGetExportsOfSymbol Method = "getExportsOfSymbol"
MethodGetExportSymbolOfSymbol Method = "getExportSymbolOfSymbol"
// Type sub-property methods
MethodGetSymbolOfType Method = "getSymbolOfType"
MethodGetTargetOfType Method = "getTargetOfType"
MethodGetFreshTypeOfType Method = "getFreshTypeOfType"
MethodGetRegularTypeOfType Method = "getRegularTypeOfType"
MethodGetTypesOfType Method = "getTypesOfType"
MethodGetTypeParametersOfType Method = "getTypeParametersOfType"
MethodGetOuterTypeParametersOfType Method = "getOuterTypeParametersOfType"
MethodGetLocalTypeParametersOfType Method = "getLocalTypeParametersOfType"
MethodGetAliasTypeArgumentsOfType Method = "getAliasTypeArgumentsOfType"
MethodGetAliasSymbolOfType Method = "getAliasSymbolOfType"
MethodGetObjectTypeOfType Method = "getObjectTypeOfType"
MethodGetIndexTypeOfType Method = "getIndexTypeOfType"
MethodGetCheckTypeOfType Method = "getCheckTypeOfType"
MethodGetExtendsTypeOfType Method = "getExtendsTypeOfType"
MethodGetBaseTypeOfType Method = "getBaseTypeOfType"
MethodGetConstraintOfType Method = "getConstraintOfType"
// Signature sub-property methods
MethodGetTypeParametersOfSignature Method = "getTypeParametersOfSignature"
MethodGetParametersOfSignature Method = "getParametersOfSignature"
MethodGetThisParameterOfSignature Method = "getThisParameterOfSignature"
MethodGetTargetOfSignature Method = "getTargetOfSignature"
// Checker methods
MethodGetContextualType Method = "getContextualType"
MethodGetBaseTypeOfLiteralType Method = "getBaseTypeOfLiteralType"
MethodGetNonNullableType Method = "getNonNullableType"
MethodGetTypeFromTypeNode Method = "getTypeFromTypeNode"
MethodGetWidenedType Method = "getWidenedType"
MethodGetParameterType Method = "getParameterType"
MethodIsArrayLikeType Method = "isArrayLikeType"
MethodIsTypeAssignableTo Method = "isTypeAssignableTo"
MethodGetShorthandAssignmentValueSymbol Method = "getShorthandAssignmentValueSymbol"
MethodGetTypeOfSymbolAtLocation Method = "getTypeOfSymbolAtLocation"
MethodTypeToTypeNode Method = "typeToTypeNode"
MethodSignatureToSignatureDeclaration Method = "signatureToSignatureDeclaration"
MethodTypeToString Method = "typeToString"
MethodIsContextSensitive Method = "isContextSensitive"
MethodGetReturnTypeOfSignature Method = "getReturnTypeOfSignature"
MethodGetRestTypeOfSignature Method = "getRestTypeOfSignature"
MethodGetTypePredicateOfSignature Method = "getTypePredicateOfSignature"
MethodGetBaseTypes Method = "getBaseTypes"
MethodGetPropertiesOfType Method = "getPropertiesOfType"
MethodGetApparentType Method = "getApparentType"
MethodGetPropertyOfType Method = "getPropertyOfType"
MethodGetIndexInfosOfType Method = "getIndexInfosOfType"
MethodGetConstraintOfTypeParameter Method = "getConstraintOfTypeParameter"
MethodGetBaseConstraintOfType Method = "getBaseConstraintOfType"
MethodGetTypeArguments Method = "getTypeArguments"
MethodGetTrueTypeOfConditionalType Method = "getTrueTypeOfConditionalType"
MethodGetFalseTypeOfConditionalType Method = "getFalseTypeOfConditionalType"
MethodGetConstantValue Method = "getConstantValue"
MethodGetSignatureFromDeclaration Method = "getSignatureFromDeclaration"
MethodGetExportSpecifierLocalTarget Method = "getExportSpecifierLocalTargetSymbol"
MethodGetAliasedSymbol Method = "getAliasedSymbol"
MethodGetImmediateAliasedSymbol Method = "getImmediateAliasedSymbol"
MethodGetExportsOfModule Method = "getExportsOfModule"
MethodGetMemberInModuleExports Method = "getMemberInModuleExports"
MethodGetJSDocTags Method = "getJsDocTags"
MethodGetDocumentationComment Method = "getDocumentationComment"
MethodIsArrayType Method = "isArrayType"
MethodIsTupleType Method = "isTupleType"
// Reference methods
MethodGetReferencesToSymbolInFile Method = "getReferencesToSymbolInFile"
MethodGetReferencedSymbolsForNode Method = "getReferencedSymbolsForNode"
MethodGetSignatureUsages Method = "getSignatureUsages"
// Language service methods
MethodGetCompletionsAtPosition Method = "getCompletionsAtPosition"
// Diagnostic methods
MethodGetSyntacticDiagnostics Method = "getSyntacticDiagnostics"
MethodGetBindDiagnostics Method = "getBindDiagnostics"
MethodGetSemanticDiagnostics Method = "getSemanticDiagnostics"
MethodGetSuggestionDiagnostics Method = "getSuggestionDiagnostics"
MethodGetDeclarationDiagnostics Method = "getDeclarationDiagnostics"
MethodGetProgramDiagnostics Method = "getProgramDiagnostics"
MethodGetGlobalDiagnostics Method = "getGlobalDiagnostics"
MethodGetConfigFileParsingDiagnostics Method = "getConfigFileParsingDiagnostics"
// Emitter methods
MethodPrintNode Method = "printNode"
// Intrinsic type getters
MethodGetAnyType Method = "getAnyType"
MethodGetStringType Method = "getStringType"
MethodGetNumberType Method = "getNumberType"
MethodGetBooleanType Method = "getBooleanType"
MethodGetVoidType Method = "getVoidType"
MethodGetUndefinedType Method = "getUndefinedType"
MethodGetNullType Method = "getNullType"
MethodGetNeverType Method = "getNeverType"
MethodGetUnknownType Method = "getUnknownType"
MethodGetBigIntType Method = "getBigIntType"
MethodGetESSymbolType Method = "getESSymbolType"
// Well-known per-checker symbols
MethodGetWellKnownSymbols Method = "getWellKnownSymbols"
// Well-known per-checker signatures
MethodGetWellKnownSignatures Method = "getWellKnownSignatures"
// Profiling methods
MethodStartCPUProfile Method = "startCPUProfile"
MethodStopCPUProfile Method = "stopCPUProfile"
MethodSaveHeapProfile Method = "saveHeapProfile"
)
// InitializeResponse is returned by the initialize method.
type InitializeResponse struct {
// UseCaseSensitiveFileNames indicates whether the host file system is case-sensitive.
UseCaseSensitiveFileNames bool `json:"useCaseSensitiveFileNames"`
// CurrentDirectory is the server's current working directory.
CurrentDirectory string `json:"currentDirectory"`
}
// DocumentIdentifier identifies a document by either a file name (plain string) or a URI object.
// On the wire it is string | { uri: string }.
type DocumentIdentifier struct {
FileName string `json:"fileName,omitempty"`
URI lsproto.DocumentUri `json:"uri,omitempty"`
}
var _ json.UnmarshalerFrom = (*DocumentIdentifier)(nil)
func (d *DocumentIdentifier) UnmarshalJSONFrom(dec *json.Decoder) error {
// Try reading as a plain string first
tok, err := dec.ReadToken()
if err != nil {
return err
}
switch tok.Kind() {
case '"':
d.FileName = tok.String()
return nil
case '{':
// Read the object fields
for dec.PeekKind() != '}' {
key, err := dec.ReadToken()
if err != nil {
return err
}
isURI := key.String() == "uri"
val, err := dec.ReadToken()
if err != nil {
return err
}
if isURI {
d.URI = lsproto.DocumentUri(val.String())
}
}
// Consume the closing brace
if _, err := dec.ReadToken(); err != nil {
return err
}
return nil
default:
return fmt.Errorf("DocumentIdentifier: expected string or object, got %v", tok.Kind())
}
}
func (d DocumentIdentifier) ToFileName() string {
if d.URI != "" {
return d.URI.FileName()
}
return d.FileName
}
// ToURI returns the document URI for this identifier. An explicitly provided URI
// is returned as-is; a file name is first normalized to an absolute path against
// cwd before being converted to a URI.
func (d DocumentIdentifier) ToURI(cwd string) lsproto.DocumentUri {
if d.URI != "" {
return d.URI
}
return lsconv.FileNameToDocumentURI(tspath.GetNormalizedAbsolutePath(d.FileName, cwd))
}
func (d DocumentIdentifier) ToAbsoluteFileName(cwd string) string {
if d.URI != "" {
return d.URI.FileName()
}
return tspath.GetNormalizedAbsolutePath(d.FileName, cwd)
}
func (d DocumentIdentifier) String() string {
if d.URI != "" {
return string(d.URI)
}
return d.FileName
}
// APIFileChangeSummary lists documents that have been changed, created, or deleted.
type APIFileChangeSummary struct {
Changed []DocumentIdentifier `json:"changed,omitempty"`
Created []DocumentIdentifier `json:"created,omitempty"`
Deleted []DocumentIdentifier `json:"deleted,omitempty"`
}
// APIFileChanges describes file changes to apply when updating a snapshot.
// Either InvalidateAll is true (discard all caches) or Changed/Created/Deleted
// list individual documents.
type APIFileChanges struct {
InvalidateAll bool `json:"invalidateAll,omitempty"`
Changed []DocumentIdentifier `json:"changed,omitempty"`
Created []DocumentIdentifier `json:"created,omitempty"`
Deleted []DocumentIdentifier `json:"deleted,omitempty"`
}
// UpdateSnapshotParams are the parameters for creating a new snapshot.
// All fields are optional. With no fields set, the server adopts the latest LSP state.
type UpdateSnapshotParams struct {
// OpenProjects lists tsconfig.json files to open/load in the new snapshot.
// Opens are ref-counted and persist across snapshots until closed.
OpenProjects []DocumentIdentifier `json:"openProjects,omitempty"`
// CloseProjects lists tsconfig.json files to release in the new snapshot.
// A project is only unloaded once every API client that opened it closes it.
CloseProjects []DocumentIdentifier `json:"closeProjects,omitempty"`
// FileChanges describes file system changes since the last snapshot.
FileChanges *APIFileChanges `json:"fileChanges,omitempty"`
// OpenFiles lists files to keep open for the API client, mirroring LSP's
// textDocument/didOpen. For each file, ancestor directories are searched for a
// tsconfig that contains it; if found, that configured project is loaded and
// becomes the file's default project. Otherwise the file is loaded into the
// inferred project (e.g. a node_modules d.ts not in any project's import graph).
// Opens persist across snapshots until the file is closed.
OpenFiles []DocumentIdentifier `json:"openFiles,omitempty"`
// CloseFiles lists files to release in the new snapshot. A file is only fully
// closed once every API client that opened it closes it.
CloseFiles []DocumentIdentifier `json:"closeFiles,omitempty"`
}
// ProjectFileChanges describes what source files changed within a single project.
type ProjectFileChanges struct {
// ChangedFiles lists source file paths whose content differs.
ChangedFiles []tspath.Path `json:"changedFiles,omitempty"`
// DeletedFiles lists source file paths removed from the project's program.
DeletedFiles []tspath.Path `json:"deletedFiles,omitempty"`
}
// SnapshotChanges describes what changed between the previous latest snapshot
// and the newly created snapshot. Changes are reported per-project so clients
// can track cache refs at the (snapshot, project) level.
type SnapshotChanges struct {
// ChangedProjects maps project handles to the file changes within that project.
// Projects not listed here (and not in RemovedProjects) are unchanged.
ChangedProjects map[ProjectID]*ProjectFileChanges `json:"changedProjects,omitempty"`
// RemovedProjects lists project handles that were present in the previous
// snapshot but absent from the new one.
RemovedProjects []ProjectID `json:"removedProjects,omitempty"`
}
// UpdateSnapshotResponse is returned by updateSnapshot.
type UpdateSnapshotResponse struct {
// Snapshot is the handle for the newly created snapshot.
Snapshot SnapshotID `json:"snapshot"`
// Projects is the list of projects in the snapshot.
Projects []*ProjectResponse `json:"projects"`
// Changes describes source file differences from the previous snapshot.
// Nil for the first snapshot in a session.
Changes *SnapshotChanges `json:"changes,omitempty"`
}
var unmarshalers = map[Method]func([]byte) (any, error){
MethodRelease: unmarshallerFor[ReleaseParams],
MethodInitialize: noParams,
MethodUpdateSnapshot: unmarshallerFor[UpdateSnapshotParams],
MethodParseConfigFile: unmarshallerFor[ParseConfigFileParams],
MethodGetDefaultProjectForFile: unmarshallerFor[GetDefaultProjectForFileParams],
MethodGetSourceFile: unmarshallerFor[GetSourceFileParams],
MethodGetSourceFileNames: unmarshallerFor[GetSourceFileNamesParams],
MethodGetSourceFileMetadata: unmarshallerFor[GetSourceFileParams],
MethodGetSymbolAtPosition: unmarshallerFor[GetSymbolAtPositionParams],
MethodGetSymbolsAtPositions: unmarshallerFor[GetSymbolsAtPositionsParams],
MethodGetSymbolAtLocation: unmarshallerFor[GetSymbolAtLocationParams],
MethodGetSymbolsAtLocations: unmarshallerFor[GetSymbolsAtLocationsParams],
MethodGetTypeOfSymbol: unmarshallerFor[GetTypeOfSymbolParams],
MethodGetTypesOfSymbols: unmarshallerFor[GetTypesOfSymbolsParams],
MethodGetDeclaredTypeOfSymbol: unmarshallerFor[GetTypeOfSymbolParams],
MethodResolveName: unmarshallerFor[ResolveNameParams],
MethodGetSignaturesOfType: unmarshallerFor[GetSignaturesOfTypeParams],
MethodGetResolvedSignature: unmarshallerFor[GetResolvedSignatureParams],
MethodGetTypeAtLocation: unmarshallerFor[GetTypeAtLocationParams],
MethodGetTypeAtLocations: unmarshallerFor[GetTypeAtLocationsParams],
MethodGetTypeAtPosition: unmarshallerFor[GetTypeAtPositionParams],
MethodGetTypesAtPositions: unmarshallerFor[GetTypesAtPositionsParams],
MethodGetParentOfSymbol: unmarshallerFor[GetSymbolPropertyParams],
MethodGetMembersOfSymbol: unmarshallerFor[GetSymbolPropertyParams],
MethodGetExportsOfSymbol: unmarshallerFor[GetSymbolPropertyParams],
MethodGetExportSymbolOfSymbol: unmarshallerFor[GetSymbolPropertyParams],
MethodGetSymbolOfType: unmarshallerFor[GetTypePropertyParams],
MethodGetTargetOfType: unmarshallerFor[GetTypePropertyParams],
MethodGetFreshTypeOfType: unmarshallerFor[GetTypePropertyParams],
MethodGetRegularTypeOfType: unmarshallerFor[GetTypePropertyParams],
MethodGetTypesOfType: unmarshallerFor[GetTypePropertyParams],
MethodGetTypeParametersOfType: unmarshallerFor[GetTypePropertyParams],
MethodGetOuterTypeParametersOfType: unmarshallerFor[GetTypePropertyParams],
MethodGetLocalTypeParametersOfType: unmarshallerFor[GetTypePropertyParams],
MethodGetAliasTypeArgumentsOfType: unmarshallerFor[GetTypePropertyParams],
MethodGetAliasSymbolOfType: unmarshallerFor[GetTypePropertyParams],
MethodGetObjectTypeOfType: unmarshallerFor[GetTypePropertyParams],
MethodGetIndexTypeOfType: unmarshallerFor[GetTypePropertyParams],
MethodGetCheckTypeOfType: unmarshallerFor[GetTypePropertyParams],
MethodGetExtendsTypeOfType: unmarshallerFor[GetTypePropertyParams],
MethodGetBaseTypeOfType: unmarshallerFor[GetTypePropertyParams],
MethodGetConstraintOfType: unmarshallerFor[GetTypePropertyParams],
MethodGetTrueTypeOfConditionalType: unmarshallerFor[GetTypePropertyParams],
MethodGetFalseTypeOfConditionalType: unmarshallerFor[GetTypePropertyParams],
MethodGetTypeParametersOfSignature: unmarshallerFor[GetSignaturePropertyParams],
MethodGetParametersOfSignature: unmarshallerFor[GetSignaturePropertyParams],
MethodGetThisParameterOfSignature: unmarshallerFor[GetSignaturePropertyParams],
MethodGetTargetOfSignature: unmarshallerFor[GetSignaturePropertyParams],
MethodGetContextualType: unmarshallerFor[GetContextualTypeParams],
MethodGetBaseTypeOfLiteralType: unmarshallerFor[GetBaseTypeOfLiteralTypeParams],
MethodGetNonNullableType: unmarshallerFor[GetNonNullableTypeParams],
MethodGetTypeFromTypeNode: unmarshallerFor[GetTypeFromTypeNodeParams],
MethodGetWidenedType: unmarshallerFor[GetWidenedTypeParams],
MethodGetParameterType: unmarshallerFor[GetParameterTypeParams],
MethodIsArrayLikeType: unmarshallerFor[IsArrayLikeTypeParams],
MethodIsTypeAssignableTo: unmarshallerFor[IsTypeAssignableToParams],
MethodGetShorthandAssignmentValueSymbol: unmarshallerFor[GetTypeAtLocationParams],
MethodGetTypeOfSymbolAtLocation: unmarshallerFor[GetTypeOfSymbolAtLocationParams],
MethodTypeToTypeNode: unmarshallerFor[TypeToTypeNodeParams],
MethodSignatureToSignatureDeclaration: unmarshallerFor[SignatureToSignatureDeclarationParams],
MethodTypeToString: unmarshallerFor[TypeToTypeNodeParams],
MethodIsContextSensitive: unmarshallerFor[GetContextualTypeParams],
MethodGetReturnTypeOfSignature: unmarshallerFor[CheckerSignatureParams],
MethodGetRestTypeOfSignature: unmarshallerFor[CheckerSignatureParams],
MethodGetTypePredicateOfSignature: unmarshallerFor[CheckerSignatureParams],
MethodGetBaseTypes: unmarshallerFor[CheckerTypeParams],
MethodGetPropertiesOfType: unmarshallerFor[CheckerTypeParams],
MethodGetApparentType: unmarshallerFor[CheckerTypeParams],
MethodGetPropertyOfType: unmarshallerFor[GetPropertyOfTypeParams],
MethodGetIndexInfosOfType: unmarshallerFor[CheckerTypeParams],
MethodGetConstraintOfTypeParameter: unmarshallerFor[CheckerTypeParams],
MethodGetBaseConstraintOfType: unmarshallerFor[CheckerTypeParams],
MethodGetTypeArguments: unmarshallerFor[CheckerTypeParams],
MethodGetConstantValue: unmarshallerFor[CheckerNodeParams],
MethodGetSignatureFromDeclaration: unmarshallerFor[CheckerNodeParams],
MethodGetExportSpecifierLocalTarget: unmarshallerFor[CheckerNodeParams],
MethodGetAliasedSymbol: unmarshallerFor[CheckerSymbolParams],
MethodGetImmediateAliasedSymbol: unmarshallerFor[CheckerSymbolParams],
MethodGetExportsOfModule: unmarshallerFor[CheckerSymbolParams],
MethodGetMemberInModuleExports: unmarshallerFor[GetMemberInModuleExportsParams],
MethodGetJSDocTags: unmarshallerFor[CheckerSymbolParams],
MethodGetDocumentationComment: unmarshallerFor[CheckerSymbolParams],
MethodIsArrayType: unmarshallerFor[CheckerTypeParams],
MethodIsTupleType: unmarshallerFor[CheckerTypeParams],
MethodGetReferencesToSymbolInFile: unmarshallerFor[GetReferencesToSymbolInFileParams],
MethodGetReferencedSymbolsForNode: unmarshallerFor[GetReferencedSymbolsForNodeParams],
MethodGetSignatureUsages: unmarshallerFor[GetSignatureUsagesParams],
MethodGetCompletionsAtPosition: unmarshallerFor[GetCompletionsAtPositionParams],
MethodPrintNode: unmarshallerFor[PrintNodeParams],
MethodGetAnyType: unmarshallerFor[GetIntrinsicTypeParams],
MethodGetStringType: unmarshallerFor[GetIntrinsicTypeParams],
MethodGetNumberType: unmarshallerFor[GetIntrinsicTypeParams],
MethodGetBooleanType: unmarshallerFor[GetIntrinsicTypeParams],
MethodGetVoidType: unmarshallerFor[GetIntrinsicTypeParams],
MethodGetUndefinedType: unmarshallerFor[GetIntrinsicTypeParams],
MethodGetNullType: unmarshallerFor[GetIntrinsicTypeParams],
MethodGetNeverType: unmarshallerFor[GetIntrinsicTypeParams],
MethodGetUnknownType: unmarshallerFor[GetIntrinsicTypeParams],
MethodGetBigIntType: unmarshallerFor[GetIntrinsicTypeParams],
MethodGetESSymbolType: unmarshallerFor[GetIntrinsicTypeParams],
MethodGetWellKnownSymbols: unmarshallerFor[GetIntrinsicTypeParams],
MethodGetWellKnownSignatures: unmarshallerFor[GetIntrinsicTypeParams],
MethodGetSyntacticDiagnostics: unmarshallerFor[GetDiagnosticsParams],
MethodGetBindDiagnostics: unmarshallerFor[GetDiagnosticsParams],
MethodGetSemanticDiagnostics: unmarshallerFor[GetDiagnosticsParams],
MethodGetSuggestionDiagnostics: unmarshallerFor[GetDiagnosticsParams],
MethodGetDeclarationDiagnostics: unmarshallerFor[GetDiagnosticsParams],
MethodGetProgramDiagnostics: unmarshallerFor[GetProjectDiagnosticsParams],
MethodGetGlobalDiagnostics: unmarshallerFor[GetProjectDiagnosticsParams],
MethodGetConfigFileParsingDiagnostics: unmarshallerFor[GetProjectDiagnosticsParams],
MethodStartCPUProfile: unmarshallerFor[ProfileParams],
MethodStopCPUProfile: noParams,
MethodSaveHeapProfile: unmarshallerFor[ProfileParams],
}
type ParseConfigFileParams struct {
File DocumentIdentifier `json:"file"`
}
// ReleaseParams are the parameters for the release method.
type ReleaseParams struct {
Snapshot SnapshotID `json:"snapshot"`
}
type ProfileParams struct {
Dir string `json:"dir"`
}
type ProfileResult struct {
File string `json:"file"`
}
type ConfigFileResponse struct {
FileNames []string `json:"fileNames"`
Options *core.CompilerOptions `json:"options"`
}
type GetDefaultProjectForFileParams struct {
Snapshot SnapshotID `json:"snapshot"`
File DocumentIdentifier `json:"file"`
}
type ProjectResponse struct {
Id ProjectID `json:"id"`
ConfigFileName string `json:"configFileName"`
RootFiles []string `json:"rootFiles"`
CompilerOptions *core.CompilerOptions `json:"compilerOptions"`
}
func NewProjectResponse(p *project.Project) *ProjectResponse {
if p == nil || p.CommandLine == nil {
panic("NewProjectResponse called with unloaded project")
}
return &ProjectResponse{
Id: ProjectHandle(p),
ConfigFileName: p.Name(),
RootFiles: p.CommandLine.FileNames(),
CompilerOptions: p.CommandLine.CompilerOptions(),
}
}
type GetSymbolAtPositionParams struct {
Snapshot SnapshotID `json:"snapshot"`
Project ProjectID `json:"project"`
File DocumentIdentifier `json:"file"`
Position uint32 `json:"position"`
}
type GetSymbolsAtPositionsParams struct {
Snapshot SnapshotID `json:"snapshot"`
Project ProjectID `json:"project"`
File DocumentIdentifier `json:"file"`
Positions []uint32 `json:"positions"`
}
type GetSymbolAtLocationParams struct {
Snapshot SnapshotID `json:"snapshot"`
Project ProjectID `json:"project"`
Location NodeHandle `json:"location"`
}
type GetSymbolsAtLocationsParams struct {
Snapshot SnapshotID `json:"snapshot"`
Project ProjectID `json:"project"`
Locations []NodeHandle `json:"locations"`
}
type SymbolResponse struct {
Id SymbolID `json:"id"`
Project ProjectID `json:"project"`
Name string `json:"name"`
Flags uint32 `json:"flags"`
CheckFlags uint32 `json:"checkFlags"`
Declarations []NodeHandle `json:"declarations,omitempty"`
ValueDeclaration NodeHandle `json:"valueDeclaration,omitempty"`
Parent SymbolID `json:"parent,omitzero"`
ExportSymbol SymbolID `json:"exportSymbol,omitzero"`
}
func symbolHandles(symbols []*ast.Symbol) []SymbolID {
if len(symbols) == 0 {
return nil
}
handles := make([]SymbolID, len(symbols))
for i, t := range symbols {
handles[i] = SymbolHandle(t)
}
return handles
}
type GetTypeOfSymbolParams struct {
Snapshot SnapshotID `json:"snapshot"`
Project ProjectID `json:"project"`
Symbol SymbolID `json:"symbol"`
}
type GetTypesOfSymbolsParams struct {
Snapshot SnapshotID `json:"snapshot"`
Project ProjectID `json:"project"`
Symbols []SymbolID `json:"symbols"`
}
type TypeResponse struct {
Id TypeID `json:"id"`
Flags uint32 `json:"flags"`
ObjectFlags uint32 `json:"objectFlags,omitempty"`
// LiteralType data
Value any `json:"value"`
// ObjectType / TypeReference / StringMappingType / IndexType target
Target TypeID `json:"target,omitzero"`
// InterfaceType type parameters
TypeParameters []TypeID `json:"typeParameters,omitempty"`
OuterTypeParameters []TypeID `json:"outerTypeParameters,omitempty"`
LocalTypeParameters []TypeID `json:"localTypeParameters,omitempty"`
// TupleType data
ElementFlags []checker.ElementFlags `json:"elementFlags,omitempty"`
FixedLength *int `json:"fixedLength,omitempty"`
TupleReadonly *bool `json:"readonly,omitempty"`
// IndexedAccessType data
ObjectType TypeID `json:"objectType,omitzero"`
IndexType TypeID `json:"indexType,omitzero"`
// ConditionalType data
CheckType TypeID `json:"checkType,omitzero"`
ExtendsType TypeID `json:"extendsType,omitzero"`
// SubstitutionType data
BaseType TypeID `json:"baseType,omitzero"`
SubstConstraint TypeID `json:"substConstraint,omitzero"`
// TemplateLiteralType text segments
Texts []string `json:"texts,omitempty"`
// FreshableType data (LiteralType and computed enum types)
FreshType TypeID `json:"freshType,omitzero"`
RegularType TypeID `json:"regularType,omitzero"`
// TypeParameter data
IsThisType bool `json:"isThisType,omitempty"`
// IntrinsicType data
IntrinsicName string `json:"intrinsicName,omitempty"`
// TypeAlias data
AliasTypeArguments []TypeID `json:"aliasTypeArguments,omitempty"`
AliasSymbol SymbolID `json:"aliasSymbol,omitzero"`
// Symbol associated with structured types
Symbol SymbolID `json:"symbol,omitzero"`
}
func newTypeResponse(t *checker.Type, id TypeID) *TypeResponse {
resp := &TypeResponse{
Id: id,
Flags: uint32(t.Flags()),
}
if t.Symbol() != nil {
resp.Symbol = SymbolHandle(t.Symbol())
}
if t.Alias() != nil {
resp.AliasTypeArguments = typeHandles(t.Alias().TypeArguments())
if t.Alias().Symbol() != nil {
resp.AliasSymbol = SymbolHandle(t.Alias().Symbol())
}
}
switch flags := t.Flags(); {
case flags&checker.TypeFlagsFreshable != 0:
lit := t.AsLiteralType()
if flags&checker.TypeFlagsLiteral != 0 {
resp.Value = literalValueToJSON(lit.Value())
}
if lit.FreshType() != nil {
resp.FreshType = TypeHandle(lit.FreshType())
}
if lit.RegularType() != nil {
resp.RegularType = TypeHandle(lit.RegularType())
}
case flags&checker.TypeFlagsObject != 0:
resp.ObjectFlags = uint32(t.ObjectFlags())
objectFlags := t.ObjectFlags()
if objectFlags&checker.ObjectFlagsReference != 0 {
var ref *checker.TypeReference
if objectFlags&checker.ObjectFlagsTuple != 0 {
tuple := t.AsTupleType()
ref = tuple.AsTypeReference()
resp.ElementFlags = tuple.ElementFlags()
fixedLen := tuple.FixedLength()
resp.FixedLength = &fixedLen
isReadonly := tuple.IsReadonly()
resp.TupleReadonly = &isReadonly
} else {
ref = t.AsTypeReference()
}
if ref.Target() != nil {
resp.Target = TypeHandle(ref.Target())
}
}
if objectFlags&checker.ObjectFlagsClassOrInterface != 0 {
iface := t.AsInterfaceType()
resp.TypeParameters = typeHandles(iface.TypeParameters())
resp.OuterTypeParameters = typeHandles(iface.OuterTypeParameters())
resp.LocalTypeParameters = typeHandles(iface.LocalTypeParameters())
}
case flags&checker.TypeFlagsUnionOrIntersection != 0:
// types omitted; fetched via separate request
case flags&checker.TypeFlagsIndex != 0:
resp.Target = TypeHandle(t.AsIndexType().Target())
case flags&checker.TypeFlagsIndexedAccess != 0:
data := t.AsIndexedAccessType()
resp.ObjectType = TypeHandle(data.ObjectType())
resp.IndexType = TypeHandle(data.IndexType())
case flags&checker.TypeFlagsConditional != 0:
data := t.AsConditionalType()
resp.CheckType = TypeHandle(data.CheckType())
resp.ExtendsType = TypeHandle(data.ExtendsType())
case flags&checker.TypeFlagsSubstitution != 0:
data := t.AsSubstitutionType()
resp.BaseType = TypeHandle(data.BaseType())
resp.SubstConstraint = TypeHandle(data.SubstConstraint())
case flags&checker.TypeFlagsTemplateLiteral != 0:
tl := t.AsTemplateLiteralType()
resp.Texts = tl.Texts()
// types omitted; fetched via separate request
case flags&checker.TypeFlagsStringMapping != 0:
resp.Target = TypeHandle(t.AsStringMappingType().Target())
case flags&checker.TypeFlagsTypeParameter != 0:
resp.IsThisType = t.AsTypeParameter().IsThisType()
case flags&checker.TypeFlagsIntrinsic != 0:
resp.IntrinsicName = t.AsIntrinsicType().IntrinsicName()
}
return resp
}
func typeHandles(types []*checker.Type) []TypeID {
if len(types) == 0 {
return nil
}
handles := make([]TypeID, len(types))
for i, t := range types {
handles[i] = TypeHandle(t)
}
return handles
}
func literalValueToJSON(value any) any {
switch v := value.(type) {
case string:
return v
case jsnum.Number:
return float64(v)
case bool:
return v
case jsnum.PseudoBigInt:
// Encode bigint literals as a signed decimal string (e.g. "-123"); the
// API client decodes this back into a real bigint. JSON has no bigint.
return v.String()
default:
return nil
}
}
type SignatureResponse struct {
Id SignatureID `json:"id"`
Flags uint32 `json:"flags"`
Declaration NodeHandle `json:"declaration,omitempty"`
TypeParameters []TypeID `json:"typeParameters,omitempty"`
Parameters []SymbolID `json:"parameters,omitempty"`
ThisParameter SymbolID `json:"thisParameter,omitzero"`
Target SignatureID `json:"target,omitzero"`
}
type GetSourceFileParams struct {
Snapshot SnapshotID `json:"snapshot"`
Project ProjectID `json:"project"`
File DocumentIdentifier `json:"file"`
}
type GetSourceFileNamesParams struct {
Snapshot SnapshotID `json:"snapshot"`
Project ProjectID `json:"project"`
}
// SourceFileMetadata carries program-stored metadata about a single source file.
type SourceFileMetadata struct {
IsDefaultLibrary bool `json:"isDefaultLibrary"`
IsFromExternalLibrary bool `json:"isFromExternalLibrary"`
PackageJsonType string `json:"packageJsonType"`
PackageJsonDirectory string `json:"packageJsonDirectory"`
ImpliedNodeFormat core.ResolutionMode `json:"impliedNodeFormat"`
}
type ResolveNameParams struct {
Snapshot SnapshotID `json:"snapshot"`
Project ProjectID `json:"project"`
Name string `json:"name"`
Location NodeHandle `json:"location,omitempty"` // Optional: node handle for location context
File *DocumentIdentifier `json:"file,omitempty"` // Optional: file for location context (alternative to Location)
Position *uint32 `json:"position,omitempty"` // Optional: position in file for location context (with File)
Meaning uint32 `json:"meaning"` // SymbolFlags for what kind of symbol to find
ExcludeGlobals bool `json:"excludeGlobals,omitempty"` // Whether to exclude global symbols
}
// GetTypePropertyParams is used for all type sub-property endpoints.
type GetTypePropertyParams struct {
Snapshot SnapshotID `json:"snapshot"`
Project ProjectID `json:"project"`
Type TypeID `json:"objectId"`
}
// GetSymbolPropertyParams is used for all symbol sub-property endpoints.
type GetSymbolPropertyParams struct {
Snapshot SnapshotID `json:"snapshot"`
Project ProjectID `json:"project"`
Symbol SymbolID `json:"objectId"`
}
// GetSignaturePropertyParams is used for all signature sub-property endpoints.
type GetSignaturePropertyParams struct {
Snapshot SnapshotID `json:"snapshot"`
Project ProjectID `json:"project"`
Signature SignatureID `json:"objectId"`
}
// GetContextualTypeParams returns the contextual type for a node.
type GetContextualTypeParams struct {
Snapshot SnapshotID `json:"snapshot"`
Project ProjectID `json:"project"`
Location NodeHandle `json:"location"`
}
// GetTypeOfSymbolAtLocationParams returns the narrowed type of a symbol at a specific location.
type GetTypeOfSymbolAtLocationParams struct {
Snapshot SnapshotID `json:"snapshot"`
Project ProjectID `json:"project"`
Symbol SymbolID `json:"symbol"`
Location NodeHandle `json:"location"`
}
// GetReferencesToSymbolInFileParams are the parameters for the getReferencesToSymbolInFile method.
type GetReferencesToSymbolInFileParams struct {
Snapshot SnapshotID `json:"snapshot"`
Project ProjectID `json:"project"`
File DocumentIdentifier `json:"file"`
Symbol SymbolID `json:"symbol"`
}
// GetReferencedSymbolsForNodeParams are the parameters for the getReferencedSymbolsForNode method.
type GetReferencedSymbolsForNodeParams struct {
Snapshot SnapshotID `json:"snapshot"`
Project ProjectID `json:"project"`
Node NodeHandle `json:"node"`
Position int `json:"position"`
}
// ReferencedSymbolEntry represents a symbol definition and its references.
type ReferencedSymbolEntry struct {
Definition NodeHandle `json:"definition"`
Symbol *SymbolResponse `json:"symbol,omitempty"`
References []NodeHandle `json:"references"`
}
// GetSignatureUsagesParams are the parameters for the getSignatureUsages method.
type GetSignatureUsagesParams struct {
Snapshot SnapshotID `json:"snapshot"`
Project ProjectID `json:"project"`
SignatureDecl NodeHandle `json:"signatureDecl"`
}
// SignatureUsageResponse represents a single usage of a signature as a name-call pair.
type SignatureUsageResponse struct {
Name NodeHandle `json:"name"`
Call NodeHandle `json:"call,omitempty"`
}
// GetCompletionsAtPositionParams are the parameters for the getCompletionsAtPosition method.
type GetCompletionsAtPositionParams struct {
Snapshot SnapshotID `json:"snapshot"`
Project ProjectID `json:"project"`
File DocumentIdentifier `json:"file"`
Position uint32 `json:"position"`
TriggerCharacter *string `json:"triggerCharacter,omitempty"`
IncludeSymbol bool `json:"includeSymbol,omitempty"`
}
// CompletionEntryLabelDetailsResponse holds additional label display text for a completion entry.
type CompletionEntryLabelDetailsResponse struct {
Detail *string `json:"detail,omitempty"`
Description *string `json:"description,omitempty"`
}
// CompletionEntryResponse represents a single completion item.
type CompletionEntryResponse struct {
Name string `json:"name"`
Kind uint32 `json:"kind,omitempty"`
SortText *string `json:"sortText,omitempty"`
InsertText *string `json:"insertText,omitempty"`
FilterText *string `json:"filterText,omitempty"`
Detail *string `json:"detail,omitempty"`
LabelDetails *CompletionEntryLabelDetailsResponse `json:"labelDetails,omitempty"`
Symbol *SymbolResponse `json:"symbol,omitempty"`
}
// CompletionInfoResponse wraps a list of completion entries.
type CompletionInfoResponse struct {
IsIncomplete bool `json:"isIncomplete"`
Entries []*CompletionEntryResponse `json:"entries"`
}
// GetIntrinsicTypeParams is used for intrinsic type getters (anyType, stringType, etc.).
type GetIntrinsicTypeParams struct {
Snapshot SnapshotID `json:"snapshot"`
Project ProjectID `json:"project"`
}
// WellKnownSymbolsResponse carries the handle ids of the per-checker singleton
// symbols (unknown, undefined, arguments) so the client can identify them by id
// without a round-trip on every check.
type WellKnownSymbolsResponse struct {
Unknown SymbolID `json:"unknown"`
Undefined SymbolID `json:"undefined"`
Arguments SymbolID `json:"arguments"`
}
// WellKnownSignaturesResponse carries the handle id of the per-checker singleton
// unknown signature (the signature the checker yields when a call cannot be
// resolved) so the client can identify it by id without a round-trip on every check.
type WellKnownSignaturesResponse struct {
Unknown SignatureID `json:"unknown"`
}
// GetBaseTypeOfLiteralTypeParams returns the base type of a literal type.
type GetBaseTypeOfLiteralTypeParams struct {
Snapshot SnapshotID `json:"snapshot"`
Project ProjectID `json:"project"`
Type TypeID `json:"type"`
}
// GetNonNullableTypeParams are the parameters for the getNonNullableType method.
type GetNonNullableTypeParams struct {
Snapshot SnapshotID `json:"snapshot"`
Project ProjectID `json:"project"`
Type TypeID `json:"type"`
}
// GetTypeFromTypeNodeParams are the parameters for the getTypeFromTypeNode method.
type GetTypeFromTypeNodeParams struct {
Snapshot SnapshotID `json:"snapshot"`
Project ProjectID `json:"project"`
Location NodeHandle `json:"location"`
}
// GetWidenedTypeParams are the parameters for the getWidenedType method.
type GetWidenedTypeParams struct {
Snapshot SnapshotID `json:"snapshot"`
Project ProjectID `json:"project"`
Type TypeID `json:"type"`
}
// GetParameterTypeParams are the parameters for the getParameterType method.
type GetParameterTypeParams struct {
Snapshot SnapshotID `json:"snapshot"`
Project ProjectID `json:"project"`
Signature SignatureID `json:"signature"`
Index int32 `json:"index"`
}
// IsArrayLikeTypeParams checks whether a type is array-like.
type IsArrayLikeTypeParams struct {
Snapshot SnapshotID `json:"snapshot"`
Project ProjectID `json:"project"`
Type TypeID `json:"type"`
}
// IsTypeAssignableToParams checks assignability between two types.
type IsTypeAssignableToParams struct {
Snapshot SnapshotID `json:"snapshot"`
Project ProjectID `json:"project"`
Source TypeID `json:"source"`
Target TypeID `json:"target"`
}
type GetSignaturesOfTypeParams struct {
Snapshot SnapshotID `json:"snapshot"`
Project ProjectID `json:"project"`
Type TypeID `json:"type"`
Kind int32 `json:"kind"`
}
type GetResolvedSignatureParams struct {
Snapshot SnapshotID `json:"snapshot"`
Project ProjectID `json:"project"`
Location NodeHandle `json:"location"`
}
type GetTypeAtLocationParams struct {
Snapshot SnapshotID `json:"snapshot"`
Project ProjectID `json:"project"`
Location NodeHandle `json:"location"`
}
type GetTypeAtLocationsParams struct {
Snapshot SnapshotID `json:"snapshot"`
Project ProjectID `json:"project"`
Locations []NodeHandle `json:"locations"`
}
type GetTypeAtPositionParams struct {
Snapshot SnapshotID `json:"snapshot"`
Project ProjectID `json:"project"`
File DocumentIdentifier `json:"file"`
Position uint32 `json:"position"`
}
type GetTypesAtPositionsParams struct {
Snapshot SnapshotID `json:"snapshot"`
Project ProjectID `json:"project"`
File DocumentIdentifier `json:"file"`
Positions []uint32 `json:"positions"`
}
// TypeToTypeNodeParams are the parameters for the typeToTypeNode method.
type TypeToTypeNodeParams struct {
Snapshot SnapshotID `json:"snapshot"`
Project ProjectID `json:"project"`
Type TypeID `json:"type"`
Location NodeHandle `json:"location,omitempty"`
Flags int32 `json:"flags,omitempty"`
}
// SignatureToSignatureDeclarationParams are the parameters for the signatureToSignatureDeclaration method.
type SignatureToSignatureDeclarationParams struct {
Snapshot SnapshotID `json:"snapshot"`
Project ProjectID `json:"project"`
Signature SignatureID `json:"signature"`
Kind int32 `json:"kind"`
Location NodeHandle `json:"location,omitempty"`
Flags int32 `json:"flags,omitempty"`
}
// PrintNodeParams are the parameters for the printNode method.
type PrintNodeParams struct {
Data string `json:"data"` // base64-encoded binary AST data
PreserveSourceNewlines bool `json:"preserveSourceNewlines,omitempty"`
NeverAsciiEscape bool `json:"neverAsciiEscape,omitempty"`
TerminateUnterminatedLiterals bool `json:"terminateUnterminatedLiterals,omitempty"`
}
// CheckerTypeParams are parameters for checker methods that operate on a type.
type CheckerTypeParams struct {
Snapshot SnapshotID `json:"snapshot"`
Project ProjectID `json:"project"`
Type TypeID `json:"type"`
}
// GetPropertyOfTypeParams are parameters for getPropertyOfType (a named property of a type).
type GetPropertyOfTypeParams struct {
Snapshot SnapshotID `json:"snapshot"`
Project ProjectID `json:"project"`
Type TypeID `json:"type"`
Name string `json:"name"`
}
// GetMemberInModuleExportsParams are parameters for getMemberInModuleExports.
type GetMemberInModuleExportsParams struct {
Snapshot SnapshotID `json:"snapshot"`
Project ProjectID `json:"project"`
Symbol SymbolID `json:"symbol"`
Name string `json:"name"`
}
// CheckerNodeParams are parameters for checker methods that operate on a node location.
type CheckerNodeParams struct {
Snapshot SnapshotID `json:"snapshot"`
Project ProjectID `json:"project"`
Location NodeHandle `json:"location"`
}
// CheckerSymbolParams are parameters for checker methods that operate on a symbol.
type CheckerSymbolParams struct {
Snapshot SnapshotID `json:"snapshot"`
Project ProjectID `json:"project"`
Symbol SymbolID `json:"symbol"`
}
// JSDocTagInfo is a single JSDoc tag, mirroring Strada's JSDocTagInfo but with the tag text
// rendered as a plain string rather than SymbolDisplayPart[].
type JSDocTagInfo struct {
Name string `json:"name"`
Text string `json:"text,omitempty"`
}
// CheckerSignatureParams are parameters for checker methods that operate on a signature.
type CheckerSignatureParams struct {
Snapshot SnapshotID `json:"snapshot"`
Project ProjectID `json:"project"`
Signature SignatureID `json:"signature"`
}
// TypePredicateResponse is the response for getTypePredicateOfSignature.
type TypePredicateResponse struct {
Kind int32 `json:"kind"`
ParameterIndex int32 `json:"parameterIndex"`
ParameterName string `json:"parameterName,omitempty"`
Type *TypeResponse `json:"type,omitempty"`
}
// IndexInfoResponse represents a single index signature.
type IndexInfoResponse struct {
KeyType TypeResponse `json:"keyType"`
ValueType TypeResponse `json:"valueType"`
IsReadonly bool `json:"isReadonly,omitempty"`
Declaration NodeHandle `json:"declaration,omitempty"`
}
// SourceFileResponse contains the binary-encoded AST data for a source file.
// The Data field is base64-encoded binary data in the encoder's format.
type SourceFileResponse struct {
Data string `json:"data"`
}
// GetDiagnosticsParams are parameters for per-file diagnostic methods.
type GetDiagnosticsParams struct {
Snapshot SnapshotID `json:"snapshot"`
Project ProjectID `json:"project"`
File *DocumentIdentifier `json:"file,omitempty"`
}
// GetProjectDiagnosticsParams are parameters for project-wide diagnostic methods.
type GetProjectDiagnosticsParams struct {
Snapshot SnapshotID `json:"snapshot"`
Project ProjectID `json:"project"`
}
// DiagnosticResponse is the API response for a single diagnostic.
type DiagnosticResponse struct {
// FileName is the path of the file this diagnostic belongs to, if any.
FileName string `json:"fileName,omitempty"`
// Pos is the start position of the diagnostic in the source file.
Pos int `json:"pos"`
// End is the end position of the diagnostic in the source file.
End int `json:"end"`
// Code is the diagnostic error code.
Code int32 `json:"code"`
// Category is the diagnostic category (error, warning, suggestion, message).
Category diagnostics.Category `json:"category"`
// Text is the localized diagnostic message text.
Text string `json:"text"`
// ReportsUnnecessary indicates this diagnostic highlights unnecessary code.
ReportsUnnecessary bool `json:"reportsUnnecessary,omitzero"`
// ReportsDeprecated indicates this diagnostic highlights deprecated code.
ReportsDeprecated bool `json:"reportsDeprecated,omitzero"`
// MessageChain contains chained diagnostic messages, if any.
MessageChain []*DiagnosticResponse `json:"messageChain,omitempty"`
// RelatedInformation contains related diagnostic information, if any.
RelatedInformation []*DiagnosticResponse `json:"relatedInformation,omitempty"`
}
// NewDiagnosticResponse converts an ast.Diagnostic to a DiagnosticResponse.
func NewDiagnosticResponse(d *ast.Diagnostic) *DiagnosticResponse {
pos := d.Pos()
end := d.End()
file := d.File()
if file != nil {
positionMap := file.GetPositionMap()
pos = positionMap.UTF8ToUTF16(pos)
end = positionMap.UTF8ToUTF16(end)
}
resp := &DiagnosticResponse{
Pos: pos,
End: end,
Code: d.Code(),
Category: d.Category(),
Text: d.Localize(locale.Default),
ReportsUnnecessary: d.ReportsUnnecessary(),
ReportsDeprecated: d.ReportsDeprecated(),
}
if file != nil {
resp.FileName = file.FileName()
}
if chain := d.MessageChain(); len(chain) > 0 {
resp.MessageChain = make([]*DiagnosticResponse, len(chain))
for i, c := range chain {
resp.MessageChain[i] = NewDiagnosticResponse(c)
}
}
if related := d.RelatedInformation(); len(related) > 0 {
resp.RelatedInformation = make([]*DiagnosticResponse, len(related))
for i, r := range related {
resp.RelatedInformation[i] = NewDiagnosticResponse(r)
}
}
return resp
}
// NewDiagnosticResponses converts a slice of ast.Diagnostics to DiagnosticResponses.
func NewDiagnosticResponses(diags []*ast.Diagnostic) []*DiagnosticResponse {
if len(diags) == 0 {
return nil
}
result := make([]*DiagnosticResponse, len(diags))
for i, d := range diags {
result[i] = NewDiagnosticResponse(d)
}
return result
}
func unmarshalPayload(method string, payload json.Value) (any, error) {
unmarshaler, ok := unmarshalers[Method(method)]
if !ok {
return nil, fmt.Errorf("unknown API method %q", method)
}
return unmarshaler(payload)
}
func unmarshallerFor[T any](data []byte) (any, error) {
var v T
if err := json.Unmarshal(data, &v); err != nil {
return nil, fmt.Errorf("failed to unmarshal %T: %w", (*T)(nil), err)
}
return &v, nil
}
func noParams(data []byte) (any, error) {
return nil, nil
}