diff --git a/docs/tsp/typeServerProtocol.ts b/docs/tsp/typeServerProtocol.ts index 4fe2ac2f..3ff4a122 100644 --- a/docs/tsp/typeServerProtocol.ts +++ b/docs/tsp/typeServerProtocol.ts @@ -41,12 +41,13 @@ export interface NotificationReceiver { } export namespace TypeServerProtocol { + export const ReturnAttributeName = '__return__'; // Special name for the return value of a function or method. + export const InvalidHandle = -1; // Special value for an invalid handle. This is used to indicate that a type or declaration is not valid. + // Represents a node in an AST (Abstract Syntax Tree) or similar structure. export interface Node { // URI of the source file containing this node. uri: string; - // Hash of the content of the source file at the time the AST was created. - fileContentHash: number; // The start byte position (zero-based) of the node in the source file. // Note this is per byte and not per character. start: number; @@ -82,6 +83,7 @@ export namespace TypeServerProtocol { Literal = 1 << 3, // Indicates if the instance is a literal (like `42`, `"hello"`, etc.). Interface = 1 << 4, // Indicates if the type is an interface (a type that defines a set of methods and properties). In Python this would be a Protocol. Generic = 1 << 5, // Indicates if the type is a generic type (a type that can be parameterized with other types). + FromAlias = 1 << 6, // Indicates if the type came from an alias (a type that refers to another type). } // Flags that describe the characteristics of a function or method. @@ -99,6 +101,21 @@ export namespace TypeServerProtocol { export const enum ClassFlags { None = 0, Enum = 1 << 0, // Indicates if the class is an enum (a special kind of class that defines a set of named values). + TypedDict = 1 << 1, // Indicates if the class is a TypedDict or derived from a TypedDict (a special kind of class that defines a dictionary with specific keys and types). + } + + // Flags that describe the characteristics of a type variable. + // These flags can be combined using bitwise operations. + export const enum TypeVarFlags { + None = 0, + IsParamSpec = 1 << 0, // Indicates if the type variable is a ParamSpec (as defined in PEP 612). + } + + export interface ModuleName { + // The leading dots in the module name. This is used to determine the relative import level. + leadingDots: number; + // The parts of the module name, split by dots. For example, for `my_module.sub_module`, this would be `['my_module', 'sub_module']`. + nameParts: string[]; } export interface Type { @@ -118,34 +135,51 @@ export namespace TypeServerProtocol { flags: TypeFlags; // Name of the module the type comes from - moduleName: string | undefined; + moduleName: ModuleName | undefined; // Simple name of the type. For example, for a class `MyClass` in module `my_module`, this would be `MyClass`. name: string; - // Flags specific to the category + // Flags specific to the category. For example, for a class type, this would be ClassFlags. + // For a function type, this would be FunctionFlags. categoryFlags: number; + // Declaration of the type, if available. + decl: Declaration | undefined; + } + + export const enum AttributeFlags { + None = 0, + IsArgsList = 1 << 0, // Indicates if a parameter is an argument list (e.g., `*args`). + IsKwargsDict = 1 << 1, // Indicates if the attribute is a keyword argument dictionary (e.g., `**kwargs`). } export interface Attribute { - // The name of the attribute. + // The name of the attribute. This is the name used to access the attribute in code. + // For a function, this would be the name of a parameter or a special name like `__return__` for the return value. name: string; // The type of the attribute. type: Type; - // The type the attribute came from - classType: Type | undefined; + // The type the attribute came from (can be a class, function, module, etc.). + owner: Type | undefined; // The type the attribute is bound to, if applicable. boundType: Type | undefined; + // Flags describing extra data about an attribute. + // For example, if the attribute is a parameter, this could indicate if it's a positional or keyword parameter. + flags: number; + // The declarations for the attribute. + decls: Declaration[]; } // Flags that are used for searching for attributes of a class Type. export const enum AttributeAccessFlags { None = 0, SkipInstanceAttributes = 1 << 0, // Skip instance attributes when searching for attributes of a type. - GetBoundAttributes = 1 << 1, // Look for bound attributes when searching for attributes of a type. That is methods bound specifically to an instance. + SkipTypeBaseClass = 1 << 2, // Skip members from the base class of a type when searching for members of a type. + SkipAttributeAccessOverride = 1 << 3, // Skip attribute access overrides when searching for members of a type. + GetBoundAttributes = 1 << 4, // Look for bound attributes when searching for attributes of a type. That is methods bound specifically to an instance. } // Represents the category of a declaration in the type system. @@ -161,6 +195,16 @@ export namespace TypeServerProtocol { Import, // An import declaration, which is a reference to another module. } + export const enum DeclarationFlags { + None = 0, + ClassMember = 1 << 0, // Indicates if the declaration is a method (a function defined within a class). + Constant = 1 << 1, // Indicates if the declaration is a constant (a variable that cannot be changed). + Final = 1 << 2, // Indicates if the declaration is final variable (a class that cannot be subclassed). + IsDefinedBySlots = 1 << 3, // Indicates if the declaration is defined by slots (a class that uses __slots__). + UsesLocalName = 1 << 4, // Indicates if the import declaration uses 'as' with a different name (ex: import foo as f). + UnresolvedImport = 1 << 5, // Indicates if the import declaration is unresolved (the module or symbol could not be found). + } + // Represents a symbol declaration in the type system. // A declaration is a specific instance of a symbol in the source code, such as a variable, function, or class. export interface Declaration { @@ -170,6 +214,9 @@ export namespace TypeServerProtocol { // Category of this symbol (function, variable, etc.). category: DeclarationCategory; + // Extra information about the declaration. + flags: DeclarationFlags; + // Parse node associated with the declaration node?: Node; @@ -177,32 +224,38 @@ export namespace TypeServerProtocol { // contains the declaration (may not be definitive // because a source file can be accessed via different // import names in some cases). - moduleName: string; - } + moduleName: ModuleName; - // Synthesized type information for a declaration that is not directly - // represented in the source code, but is derived from the declaration. Other languages - // may refer to this as an anonymous type. - export interface SynthesizedTypeInfo { - type: Type; + // The symbol name for the declaration (as the user sees it) + name: string; - // An optional node that is not used by the type evaluator - // but can be used by language services to provide additional - // functionality (such as go-to-definition). - node?: Node; + // The file that contains the declaration. + // Unless this is an import declaration, then the uri refers to the file + // the import is referring to. + uri: string; } - // Declaration information for a symbol, which includes + // Symbol information for a node, which includes // a list of declarations and potentially synthesized types for those declarations. - export interface SymbolDeclInfo { + export interface Symbol { + // The node for which the declaration information is being requested. + node: Node; + // The name of the symbol found. + name: string; + // The declarations for the symbol. + // This can include multiple declarations for the same symbol, such as when a symbol is defined in multiple files. decls: Declaration[]; - synthesizedTypes: SynthesizedTypeInfo[]; + // Synthesized type information for a declaration that is not directly + // represented in the source code, but is derived from the declaration. Other languages + // may refer to this as an anonymous type. + synthesizedTypes: TypeServerProtocol.Type[]; } - // Describes an import - export interface ImportedModuleDescriptor { - leadingDots: number; - nameParts: string[]; + export interface FileSymbolInfo { + // The URI of the source file. + uri: string; + // The symbols in the file. + symbols: Symbol[]; } // Options for resolving an import declaration. @@ -240,30 +293,84 @@ export namespace TypeServerProtocol { // The URI of the source file where the import is referenced. sourceUri: string; // The descriptor of the imported module. - moduleDescriptor: ImportedModuleDescriptor; + moduleDescriptor: ModuleName; snapshot: number; } - export interface GetTypeAttributeParams { - // The type for which the attribute is being requested. - type: Type; + // Flags that control how type representations are formatted. + export const enum TypeReprFlags { + None = 0, + // Turn type aliases into their original type. + ExpandTypeAliases = 1 << 0, + // Print the variance of a type parameter. + PrintTypeVarVariance = 1 << 1, + // Convert the type into an instance type before printing it. + ConvertToInstanceType = 1 << 2, + } + + export interface SearchForTypeAttributeParams { + // The starting point in the type heirarchy to search for the attribute. + startType: Type; // The name of the attribute being requested. attributeName: string; // Flags that control how the attribute is accessed. accessFlags: AttributeAccessFlags; // Optional: The expression node that the member is being accessed from. expressionNode?: Node; + // Optional: The type of an instance that the attribute is being accessed from. + // Example: type of `a` in `a = MyClass()`, where `MyClass` is a class and `a` is an instance of that class. + instanceType?: Type; + // The snapshot version of the type server state. + snapshot: number; + } + export interface GetTypeAttributesParams { + // The type for which the attributes are being requested. + type: Type; + // The snapshot version of the type server state. + snapshot: number; + } + export interface GetDeclarationInfoParams { + // The node for which the declaration information is being requested. + node: Node; + // The name of the symbol being requested. This is optional and can be undefined especially when the node is a name node. + // If this node is a module node, this would be the name of the symbol being requested. + name?: string; + // Whether to skip unreachable code when looking for the symbol declaration. + skipUnreachableCode: boolean; // The snapshot version of the type server state. snapshot: number; } - // Represents settings that can be sent to the type server. + export interface GetBuiltinTypeParams { + // The node that is used to scope the builtin type. Every module may have a different set of builtins based on + // where the module is located. + scopingNode: Node; + // The name of the builtin type being requested. + name: string; + // The snapshot version of the type server state. + snapshot: number; + } + // Represents settings that can be sent to the type server. export type Settings = { [key: string]: any; }; + // Parts of a function, including its parameters and return type. + // This is used to provide a string representation of a function's signature. + export type FunctionParts = { + params: string[]; + returnType: string; + }; + + export interface TypeAliasInfo { + // The original name of the alias. + name: string; + // The arguments for the type alias, if any. + typeArgs: Type[] | undefined; + } + // Requests and notifications for the type server protocol. export enum Requests { // First request to initialize the type server. @@ -284,22 +391,47 @@ export namespace TypeServerProtocol { GetDiagnosticsVersion = 'typeServer/getDiagnosticsVersion', // Request to get the type information for a specific node. GetType = 'typeServer/getType', - // Request to get the collection of subtypes that make up a union type. - GetUnionTypes = 'typeServer/getUnionTypes', + // Request to get the type information for a specific builtin type. + GetBuiltinType = 'typeServer/getBuiltinType', + // Request to get the collection of subtypes that make up a union type or the types that makes up a generic type. + GetTypeArgs = 'typeServer/getTypeArgs', // Request to find an attribute of a class. - GetTypeAttribute = 'typeServer/getTypeAttribute', + SearchForTypeAttribute = 'typeServer/searchForTypeAttribute', + // Request to get the attributes of a specific class or the parameters and return value of a specific function. + GetTypeAttributes = 'typeServer/getTypeAttributes', // Request to get all overloads of a function or method. The returned value doesn't include the implementation signature. GetOverloads = 'typeServer/getOverloads', + // Request to get the overloads that a call node matches. + GetMatchingOverloads = 'typeServer/getMatchingOverloads', // Request to get the meta class of a type. GetMetaclass = 'typeServer/getMetaclass', // Request to get the type of a declaration. GetTypeOfDeclaration = 'typeServer/getTypeOfDeclaration', // Request to get symbol declaration information for a node. - GetSymbolDeclarationInfo = 'typeServer/getSymbolDeclarationInfo', - // Request to resolve an import declaration. Example: `from module import something`. The `something` is the import declaration. + GetSymbol = 'typeServer/getSymbol', + // Request to get all symbols for a file. This is used to get all symbols in a file. + GetSymbolsForFile = 'typeServer/getSymbolsForFile', + // Request to get the string representation of a function's parts, meaning its parameters and return type. + GetFunctionParts = 'typeServer/getFunctionParts', + // Request to get the string representation of a type in a human-readable format. This may or may not be the same as the type's "name". + GetRepr = 'typeServer/getRepr', + // Request to get the docstring for a specific declaration. + GetDocString = 'typeServer/getDocString', + // Request to resolve an import declaration. Example: `from module import something`. The `something` is the import declaration. Resolving it + // means finding the actual declaration of `something` in the module. ResolveImportDeclaration = 'typeServer/resolveImportDeclaration', - // Request to resolve an import. + // Request to resolve an import. This is used to resolve the import name to its location in the file system. ResolveImport = 'typeServer/resolveImport', + // Get information about a type alias. + // Example: `MyType = List[int]` is a type alias. In this case the List[int] is the type passed to this function but it has the Alias TypeFlag set. + // The type alias info will return the name 'MyType' and the args [int] + GetTypeAliasInfo = 'typeServer/getTypeAliasInfo', + // Request to combine types. This is used to combine multiple types into a single type. + // Example: + // `if (someCondition) { x = 1 } else { x = "hello" }`. The combined type of `x` would be `int | str`. + CombineTypes = 'typeServer/combineTypes', + // Request to get the search paths that the type server uses for Python modules. + GetPythonSearchPaths = 'typeServer/getPythonSearchPaths', } export enum Notifications { @@ -315,6 +447,11 @@ export namespace TypeServerProtocol { SettingsChange = 'typeServer/settingsChange', // Notification sent by the client to indicate that files have changed. FilesChanged = 'typeServer/filesChanged', + // Notification sent by the server to indicate any outstanding snapshots are invalid. + SnapshotChanged = 'typeServer/snapshotChanged', + // Notification sent by the server to indicate that diagnostics have changed and the client + // should re-request diagnostics for the file. + DiagnosticsChanged = 'typeServer/diagnosticsChanged', } export interface Params { @@ -324,28 +461,55 @@ export namespace TypeServerProtocol { [Requests.GetDiagnostics]: { uri: string; snapshot: number }; [Requests.GetDiagnosticsVersion]: { uri: string; snapshot: number }; [Requests.GetType]: { node: Node; snapshot: number }; - [Requests.GetUnionTypes]: { type: Type; snapshot: number }; - [Requests.GetTypeAttribute]: GetTypeAttributeParams; + [Requests.GetBuiltinType]: GetBuiltinTypeParams; + [Requests.GetTypeArgs]: { type: Type; snapshot: number }; + [Requests.SearchForTypeAttribute]: SearchForTypeAttributeParams; + [Requests.GetTypeAttributes]: GetTypeAttributesParams; [Requests.GetOverloads]: { type: Type; snapshot: number }; + [Requests.GetMatchingOverloads]: { callNode: Node; snapshot: number }; [Requests.GetMetaclass]: { type: Type; snapshot: number }; [Requests.GetTypeOfDeclaration]: { decl: Declaration; snapshot: number }; - [Requests.GetSymbolDeclarationInfo]: { - node: Node; - skipUnreachableCode: boolean; + [Requests.GetRepr]: { + type: Type; + flags: TypeReprFlags; + snapshot: number; + }; + [Requests.GetFunctionParts]: { + type: Type; + flags: TypeReprFlags; + snapshot: number; + }; + [Requests.GetDocString]: { + type: Type | undefined; // The type of declaration if known. + decl: Declaration; // The symbol to get the docstring for. + boundObjectOrClass: Type | undefined; // The object or class the docstring is bound to, if applicable. snapshot: number; }; + [Requests.GetSymbol]: GetDeclarationInfoParams; + [Requests.GetSymbolsForFile]: { uri: string; snapshot: number }; [Requests.ResolveImportDeclaration]: { decl: Declaration; options: ResolveImportOptions; snapshot: number; }; [Requests.ResolveImport]: ResolveImportParams; + [Requests.GetTypeAliasInfo]: { + type: Type; + snapshot: number; + }; + [Requests.CombineTypes]: { + types: Type[]; + snapshot: number; + }; + [Requests.GetPythonSearchPaths]: { fromUri: string; snapshot: number }; [Notifications.Initialized]: void; [Notifications.ShutDown]: void; [Notifications.TextDocumentOpen]: TextDocumentOpenParams; [Notifications.TextDocumentClose]: TextDocumentCloseParams; [Notifications.SettingsChange]: Settings; [Notifications.FilesChanged]: { changes: FileEvent[] }; + [Notifications.SnapshotChanged]: { old: number; new: number }; + [Notifications.DiagnosticsChanged]: { uri: string; snapshot: number; version: number }; } export interface Response { @@ -355,14 +519,24 @@ export namespace TypeServerProtocol { [Requests.GetDiagnostics]: Diagnostic[] | undefined; [Requests.GetDiagnosticsVersion]: number | undefined; [Requests.GetType]: Type | undefined; - [Requests.GetUnionTypes]: Type[] | undefined; - [Requests.GetTypeAttribute]: Attribute | undefined; + [Requests.GetBuiltinType]: Type | undefined; + [Requests.GetTypeArgs]: Type[] | undefined; + [Requests.SearchForTypeAttribute]: Attribute | undefined; + [Requests.GetTypeAttributes]: Attribute[] | undefined; [Requests.GetOverloads]: Type[] | undefined; + [Requests.GetMatchingOverloads]: Type[] | undefined; [Requests.GetMetaclass]: Type | undefined; [Requests.GetTypeOfDeclaration]: Type | undefined; - [Requests.GetSymbolDeclarationInfo]: SymbolDeclInfo | undefined; + [Requests.GetRepr]: string | undefined; + [Requests.GetFunctionParts]: FunctionParts | undefined; + [Requests.GetDocString]: string | undefined; + [Requests.GetSymbol]: Symbol | undefined; + [Requests.GetSymbolsForFile]: FileSymbolInfo | undefined; [Requests.ResolveImportDeclaration]: Declaration | undefined; [Requests.ResolveImport]: string | undefined; + [Requests.GetTypeAliasInfo]: TypeAliasInfo | undefined; + [Requests.GetPythonSearchPaths]: string[] | undefined; + [Requests.CombineTypes]: Type | undefined; } export function sendRequest
(