diff --git a/tools/SourceKit/docs/Protocol.md b/tools/SourceKit/docs/Protocol.md new file mode 100644 index 0000000000000..3b5f4b5b63dad --- /dev/null +++ b/tools/SourceKit/docs/Protocol.md @@ -0,0 +1,338 @@ +# The SourceKit Protocol + +This documents the request/response API as it is currently implemented. +For specific details related to Swift, see `SwiftSupport.md`. + +The protocol is documented in the following format: + +``` +{ + : (type) // comments +} +``` + +- `"{ }"` indicates a dictionary +- `"[ ]"` indicates an array. +- `"[opt]"` indicates an optional key. +- Specific UIDs are written as ``. + + +# Requests + +## Code-Completion + +SourceKit is capable of providing code completion suggestions. To do so, it +must be given either the path to a file (`key.sourcefile`), or some text +(`key.sourcetext`). `key.sourcefile` is ignored when `key.sourcetext` is also +provided. + +### Request + +``` +{ + : (UID) + [opt] : (string) // Source contents. + [opt] : (string) // Absolute path to the file. + : (int64) // Byte offset of code-completion point inside the source contents. + [opt] [string*] // Array of zero or more strings for the compiler arguments, + // e.g ["-sdk", "/path/to/sdk"]. If key.sourcefile is provided, + // these must include the path to that file. + [opt] [bool] // True if this result is to be avoided, e.g. because + // the declaration is unavailable. +} +``` + +### Response + +``` +{ + : (array) [completion-result*] // array of zero or more completion-result dictionaries +} +``` + +``` +completion-result ::= +{ + : (string) // Text to be displayed in code-completion window. + : (UID) // UID for the declaration kind (function, class, etc.). + : (string) // Text to be inserted in source. + : (string) // Text describing the type of the result. + : (string) // Brief documentation comment attached to the entity. + : (UID) // Semantic context of the code completion result. + : (int64) // Number of bytes to the left of the cursor that should be erased before inserting this completion result. +} +``` + +### Testing + +``` +$ sourcekitd-test -req=complete -offset= [-- ] +``` + +For example, to get a code completion suggestion for the 58th character in an +ASCII file at `path/to/file.swift`: + +``` +$ sourcekitd-test -req=complete -offset=58 /path/to/file.swift -- /path/to/file.swift +``` + +You could also issue the following request in the `sourcekitd-repl`: + +``` +$ sourcekitd-repl +Welcome to SourceKit. Type ':help' for assistance. +(SourceKit) { + key.request: source.request.codecomplete, + key.sourcefile: "/path/to/file.swift", + key.offset: 57, + key.compilerargs: ["/path/to/file.swift"] +} +``` + +## Indexing + +SourceKit is capable of "indexing" source code, responding with which ranges +of text contain what kinds of source code. In other words, SourceKit is +capable of telling you that "the source code on line 2, column 9, is a +reference to a struct". + +To index source code, SourceKit must be given either the path to a file +(`key.sourcefile`), or some text (`key.sourcetext`). `key.sourcefile` is +ignored when `key.sourcetext` is also provided. + +A hash (`key.hash`) may be provided in order to determine whether the source +code has changed since the last time it was indexed. If the provided hash +matches the one generated from the source code, the response will omit entries +that have already been returned. + +### Request + +``` +{ + : (UID) + [opt] : (string) // Source contents. + [opt] : (string) // Absolute path to the file. + [opt] [string*] // Array of zero or more strings for the compiler arguments + // e.g ["-sdk", "/path/to/sdk"]. If key.sourcefile is provided, + // these must include the path to that file. + [opt] : (string) // Known hash for the indexed file, used to determine whether + // the file has changed since the last time it was indexed. +} +``` + +### Response + +``` +{ + : (array) [dependency*] // Array of zero or more dependencies. + : (string) // Hash associated with the indexed file. + [opt] : (array) [entity*] // Array of zero or more top-level indexed entities. + // If the key.hash provided in the request matches the + // one in the response, this key will not be included in + // the response. +} +``` + +``` +entity ::= +{ + : (UID) // UID for the declaration or reference kind (function, class, etc.). + : (string) // Displayed name for the entity. + : (string) // USR string for the entity. + : (int64) // Line of the position of the entity in source contents. + : (int64) // Column of the position of the entity in source contents. + [opt] : (array) [entity+] // One or more entities contained in the particular entity (sub-classes, references, etc.). + [opt] : (array) [entity+] // One or more entities related with the particular entity (inherited classes, protocols, etc.). +} +``` + +``` +dependency ::= +{ + : (UID) // UID for the kind (import of a swift module, etc.). + : (string) // Displayed name for dependency. + : (string) // Path to the file. + [opt] : (string) // Hash associated with this dependency. +} +``` + +### Testing + +``` +$ sourcekitd-test -req=index [-- ] +``` + +For example, to index a file at `path/to/file.swift`: + +``` +$ sourcekitd-test -req=index /path/to/file.swift -- /path/to/file.swift +``` + +You could also issue the following request in the `sourcekitd-repl`: + +``` +$ sourcekitd-repl +Welcome to SourceKit. Type ':help' for assistance. +(SourceKit) { + key.request: source.request.index, + key.sourcefile: "/path/to/file.swift", + key.compilerargs: ["/path/to/file.swift"] +} +``` + +## DocInfo + +``` +{ + "key.request": source.request.docinfo, + "key.modulename": "Foundation", + "key.compilerargs": ["-sdk", "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk"] +} +``` + +This will return: + +- `key.sourcetext`: The pretty-printed module interface in swift source code +- `key.annotations`: An array of annotations for the tokens of source text, they refer to the text via offset+length entries. This includes syntactic annotations (e.g. keywords) and semantic ones. The semantic ones include the name and USR of the referenced symbol. +- `key.entities`: A structure of the symbols, similar to what the indexing request returns (a class has its methods as sub-entities, etc.). This includes the function parameters and their types as entities. Each entity refers to the range of the original text via offset+length entries. + + +For source text (you can also pass a source filename with `key.sourcefile`): + +``` +{ + "key.request": source.request.docinfo, + "key.sourcefile": "/whatever/virtual/path", + "key.sourcetext": "import Foundation\n var s: NSString\n", + "key.compilerargs": ["/whatever/virtual/path", "-sdk", "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk"] +} +``` + +This will return + +- `key.annotations` +- `key.entities` + +...which will refer to the original text, and: + +- `key.diagnostics` + +...for any compiler diagnostics during parsing. + +## Module interface generation + +### Request + +``` +{ + : (UID) + : (string) // virtual name/path to associate with the interface document + : (string) // Full module name, e.g. "Foundation.NSArray" + [opt] [string*] // array of zero or more strings for the compiler arguments + // e.g ["-sdk", "/path/to/sdk"] +} +``` + +### Response + +This will return the Swift interface of the specified module. + +- `key.sourcetext`: The pretty-printed module interface in swift source code +- `key.syntaxmap`: An array of syntactic annotations, same as the one returned for the source.request.editor.open request. +- `key.annotations`: An array of semantic annotations, same as the one returned for the source.request.editor.open request. + +All SourceKit requests that don't modify the source buffer should work on the +opened document, by passing the associated 'name' for the document. + +If pointing at a symbol which came from a clang module or the stdlib, then the +response for the cursor-info request will have an entry for the module name: + +``` +key.modulename: "" +``` + +Also if there is already a generated-interface document for this module +previously opened, there will be an entry with the "virtual name" associated +with this document (from the previous 'editor.open.interface' request): + +``` +key.module_interface_name: "" +``` + +After 'opening' the module interface, to 'jump' to the location of a declaration +with a particular USR, use the 'find_usr' request: + +``` +{ + : (UID) + : (string) // USR to look for. + : (string) // virtual name/path associated with the interface document +} +``` + +This returns the byte offset if the USR is found, or an empty response otherwise: + +``` +key.offset: +``` + +# Diagnostics + +Diagnostic entries occur as part of the responses for editor requests. +If there is a diagnostic, `` is present and contains an array +of diagnostic entries. A diagnostic entry has this format: + +``` +{ + : (UID) // severity of error + : (int64) // error location + : (string) // error description + [opts] : (array) [fixit+] // one or more entries for fixits + [opts] : (array) [range+] // one or more entries for ranges + [opts] : (array) [diagnostic+] // one or more sub-diagnostic entries +} +``` + +Where `key.severity` can be one of: + +- `source.diagnostic.severity.note` +- `source.diagnostic.severity.warning` +- `source.diagnostic.severity.error` + +``` +fixit ::= +{ + : (int64) // location of the fixit range + : (int64) // length of the fixit range + : (string) // text to replace the range with +} +``` + +``` +range ::= +{ + : (int64) // location of the range + : (int64) // length of the range +} +``` + +Sub-diagnostics are only diagnostic notes currently. + +# UIDs + +## Keys + +- `key.column` +- `key.compilerargs` +- `key.description` +- `key.kind` +- `key.line` +- `key.name` +- `key.offset` +- `key.results` +- `key.request` +- `key.sourcefile` +- `key.sourcetext` +- `key.typename` +- `key.usr` + diff --git a/tools/SourceKit/docs/Protocol.txt b/tools/SourceKit/docs/Protocol.txt deleted file mode 100644 index 8c2ae1be407da..0000000000000 --- a/tools/SourceKit/docs/Protocol.txt +++ /dev/null @@ -1,252 +0,0 @@ -This documents the Request/Response API as it is currently. -For specific details related to Swift see SwiftSupport.txt - -The format is -{ - : (type) // comments - ... -} - -"{ }" indicates dictionary -"[ ]" indicates array. -"[opt]" indicates optional key - -Specific UIDs are written as - - -================================================ -Requests -================================================ - -=== Code-Completion === - -// If "SourceText" is provided, "SourceFile" is ignored. Not specifying either one is erroneous. -Request: -{ - : (UID) - [opt] : (string) // source contents - [opt] : (string) // absolute path to the file - : (int64) // byte offset of code-completion point inside the source contents - [opt] [string*] // array of zero or more strings for the compiler arguments - // e.g ["-sdk", "/path/to/sdk"] - [opt] [bool] // true if this result is to be avoided, e.g. because - // the declaration is unavailable. -} - -Response: -{ - : (array) [completion-result*] // array of zero or more completion-result dictionaries -} - -completion-result ::= -{ - : (string) // text to be displayed in code-completion window - : (UID) // UID for the declaration kind (function, class, etc.) - : (string) // text to be inserted in source - : (string) // text describing the type of the result - : (string) // brief documentation comment attached to the entity - : (UID) // semantic context of the code completion result - : (int64) // number of bytes to the left of the cursor that should be erased before inserting this completion result -} - -Testing: -$ sourcekitd-test -req=complete -cc-offset= [-- ] - - -=== Indexing === - -// If "SourceText" is provided, "SourceFile" is ignored. Not specifying either one is erroneous. -// If is provided and matches the hash of the indexed file then the -// entry will be missing from the response. -Request: -{ - : (UID) - [opt] : (string) // source contents - [opt] : (string) // absolute path to the file - [opt] [string*] // array of zero or more strings for the compiler arguments - // e.g ["-sdk", "/path/to/sdk"] - [opt] : (string) // known hash for the indexed file -} - -// If was provided in the indexing request and matches the hash in the response -// then the entry will be missing from the response. -Response: -{ - : (array) [dependency*] // array of zero or more dependencies - : (string) // Hash associated with the indexed file - [opt] : (array) [entity*] // array of zero or more top-level indexed entities -} - -entity ::= -{ - : (UID) // UID for the declaration or reference kind (function, class, etc.) - : (string) // displayed name for the entity - : (string) // USR string for the entity - : (int64) // Line of the position of the entity in source contents. - : (int64) // Column of the position of the entity in source contents. - [opt] : (array) [entity+] // one or more entities contained in the particular entity (sub-classes, references, etc.) - [opt] : (array) [entity+] // one or more entities related with the particular entity (inherited classes, protocols, etc.) -} - -dependency ::= -{ - : (UID) // UID for the kind (import of a swift module, etc.) - : (string) // displayed name for dependency - : (string) // path to the file - [opt] : (string) // Hash associated with this dependency -} - -Testing: -$ sourcekitd-test -req=index [-- ] - - -=== DocInfo === - -{ - "key.request": source.request.docinfo, - "key.modulename": "Foundation", - "key.compilerargs": ["-sdk", "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk"] -} - -This will return: - -key.sourcetext: - The pretty-printed module interface in swift source code - -key.annotations: - An array of annotations for the tokens of source text, they refer to the text via offset+length entries. This includes syntactic annotations (e.g. keywords) and semantic ones. The semantic ones include the name and USR of the referenced symbol. - -key.entities: - A structure of the symbols, similar to what the indexing request returns (a class has its methods as sub-entities, etc.). This includes the function parameters and their types as entities. - Each entity refers to the range of the original text via offset+length entries. - - -For source text (you can also pass a source filename with "key.sourcefile") - -{ - "key.request": source.request.docinfo, - "key.sourcefile": "/whatever/virtual/path", - "key.sourcetext": "import Foundation\n var s: NSString\n", - "key.compilerargs": ["/whatever/virtual/path", "-sdk", "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk"] -} - -This will return - -key.annotations -key.entities - which will refer to the original text. - -and - -key.diagnostics - for any compiler diagnostics during parsing - -=== Module interface generation === - -Request: -{ - : (UID) - : (string) // virtual name/path to associate with the interface document - : (string) // Full module name, e.g. "Foundation.NSArray" - [opt] [string*] // array of zero or more strings for the compiler arguments - // e.g ["-sdk", "/path/to/sdk"] -} - -This will return the Swift interface of the specified module. - -key.sourcetext: - The pretty-printed module interface in swift source code - -key.syntaxmap: - An array of syntactic annotations, same as the one returned for the source.request.editor.open request. - -key.annotations: - An array of semantic annotations, same as the one returned for the source.request.editor.open request. - - -All SourceKit requests that don't modify the source buffer should work on the -opened document, by passing the associated 'name' for the document. - -If pointing at a symbol which came from a clang module or the stdlib, then the -response for the cursor-info request will have an entry for the module name: - - key.modulename: "" - -Also if there is already a generated-interface document for this module -previously opened, there will be an entry with the "virtual name" associated -with this document (from the previous 'editor.open.interface' request): - - key.module_interface_name: "" - - -After 'opening' the module interface, to 'jump' to the location of a declaration -with a particular USR, use the 'find_usr' request: - -Request: -{ - : (UID) - : (string) // USR to look for. - : (string) // virtual name/path associated with the interface document -} - -This returns the byte offset if the USR is found, or an empty response otherwise: - - key.offset: - - -================================================ -Diagnostics -================================================ - -Diagnostic entries occur as part of the responses for editor requests. -If there is a diagnostic, is present and contains an array -of diagnostic entries. A diagnostic entry has this format: - -{ - : (UID) // severity of error - : (int64) // error location - : (string) // error description - [opts] : (array) [fixit+] // one or more entries for fixits - [opts] : (array) [range+] // one or more entries for ranges - [opts] : (array) [diagnostic+] // one or more sub-diagnostic entries -} - -severity can be one of: - source.diagnostic.severity.note - source.diagnostic.severity.warning - source.diagnostic.severity.error - -fixit ::= -{ - : (int64) // location of the fixit range - : (int64) // length of the fixit range - : (string) // text to replace the range with -} - -range ::= -{ - : (int64) // location of the range - : (int64) // length of the range -} - -sub-diagnostics are only diagnostic notes currently. - -================================================ -UIDs -================================================ - -=== Keys === - -key.column -key.compilerargs -key.description -key.kind -key.line -key.name -key.offset -key.results -key.request -key.sourcefile -key.sourcetext -key.typename -key.usr