stan-language-server 0.4.9 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/README.md +12 -60
  2. package/dist/__tests__/e2e/lsp-client.d.ts +6 -1
  3. package/dist/__tests__/handlers/rename.test.d.ts +1 -0
  4. package/dist/__tests__/language/ast/parser.test.d.ts +1 -0
  5. package/dist/__tests__/language/ast/symbol.test.d.ts +1 -0
  6. package/dist/__tests__/language/ast/workspace_index.test.d.ts +1 -0
  7. package/dist/__tests__/language/rename/prepare.test.d.ts +1 -0
  8. package/dist/__tests__/language/rename/provider.test.d.ts +1 -0
  9. package/dist/__tests__/language/stan-symbols/index.test.d.ts +1 -0
  10. package/dist/__tests__/server/document_state.test.d.ts +1 -0
  11. package/dist/__tests__/server/workspace_state.test.d.ts +1 -0
  12. package/dist/handlers/compilation/compilation.d.ts +3 -3
  13. package/dist/handlers/compilation/includes.d.ts +3 -3
  14. package/dist/handlers/completion.d.ts +4 -3
  15. package/dist/handlers/diagnostics.d.ts +3 -4
  16. package/dist/handlers/formatting.d.ts +3 -4
  17. package/dist/handlers/hover.d.ts +0 -1
  18. package/dist/handlers/index.d.ts +1 -0
  19. package/dist/handlers/rename.d.ts +5 -0
  20. package/dist/language/ast/semantic_index.d.ts +11 -0
  21. package/dist/language/ast/symbol.d.ts +6 -0
  22. package/dist/language/ast/types.d.ts +50 -0
  23. package/dist/language/ast/wasm-data.generated.d.ts +2 -0
  24. package/dist/language/ast/workspace_index.d.ts +9 -0
  25. package/dist/language/rename/prepare.d.ts +3 -0
  26. package/dist/language/rename/provider.d.ts +3 -0
  27. package/dist/language/rename/types.d.ts +9 -0
  28. package/dist/language/stan-symbols/index.d.ts +9 -0
  29. package/dist/server/document_state.d.ts +23 -0
  30. package/dist/server/index.js +1295 -369
  31. package/dist/server/workspace_state.d.ts +29 -0
  32. package/dist/types/common.d.ts +4 -0
  33. package/package.json +16 -17
  34. package/dist/language/treesitter/wasm-data.generated.d.ts +0 -2
  35. /package/dist/__tests__/{language/treesitter/parser.test.d.ts → e2e/rename.test.d.ts} +0 -0
  36. /package/dist/language/{treesitter → ast}/parser.d.ts +0 -0
package/README.md CHANGED
@@ -105,73 +105,25 @@ and add the following to the settings file:
105
105
 
106
106
  ### Emacs (eglot)
107
107
 
108
+ For emacs users, we recommend using [mason.el](github.com/mason-org/mason.el)
109
+ to download from the same source as neovim above.
110
+
108
111
  Assuming you are using [stan-ts-mode](https://github.com/WardBrian/stan-ts-mode),
109
112
  add the following to your `init.el`.
110
- This will download the latest release the first time you load a Stan file.
111
113
 
112
114
  ```elisp
113
- (require 'package)
114
- ;; elgot is built in to emacs 29+, but some features work better if you use the
115
- ;; latest version from GNU ELPA
116
- (add-to-list 'package-archives '("gnu-devel" . "https://elpa.gnu.org/devel/"))
117
- (package-initialize)
118
-
119
- ;; work around https://debbugs.gnu.org/cgi/bugreport.cgi?bug=69423
120
- (assq-delete-all 'eglot package--builtins)
121
- (assq-delete-all 'eglot package--builtin-versions)
122
-
123
- (defcustom bmw/stan-language-server-location
124
- (expand-file-name (concat "bin/stan-language-server" (car exec-suffixes)) user-emacs-directory)
125
- "Location to download the stan-language-server binary to."
126
- :type 'file
127
- :group 'stan)
128
-
129
- (use-package url)
130
-
131
- (defun bmw/download-stan-language-server (&optional force)
132
- "Download the latest copy of the stan-language-server.
133
- The location is determined by stan-ts-mode-language-server-location.
134
- Argument FORCE will make the download proceed even if the file exists."
135
- (interactive "P")
136
- (when (or force (not (file-exists-p bmw/stan-language-server-location)))
137
- (let*
138
- ((version
139
- (with-temp-buffer
140
- (url-insert-file-contents
141
- "https://api.github.com/repos/tomatitito/stan-language-server/releases/latest")
142
- (let ((json (json-parse-buffer)))
143
- (gethash "tag_name" json))))
144
- (os-tag
145
- (pcase system-type
146
- ((or 'windows-nt 'cygwin 'ms-dos) "windows-x86_64")
147
- ('darwin (concat "macos-"
148
- (if (string-match-p "aarch64\\|arm" system-configuration ) "aarch64" "x86_64") ))
149
- (_ (concat "linux-"
150
- (if (string-match-p "aarch64\\|arm" system-configuration ) "arm64" "x86_64")))))
151
- (url
152
- (concat
153
- "https://github.com/tomatitito/stan-language-server/releases/download/"
154
- version
155
- "/stan-ls-"
156
- version
157
- "-"
158
- os-tag
159
- (car exec-suffixes)))
160
- (file bmw/stan-language-server-location))
161
- (make-empty-file file t)
162
- (delete-file file)
163
- (url-copy-file url file)
164
- (chmod file 500))))
115
+ (use-package mason
116
+ :config
117
+ (mason-setup
118
+ (dolist (pkg '("stan-language-server"))
119
+ (unless (mason-installed-p pkg)
120
+ (ignore-errors (mason-install pkg))))) )
165
121
 
166
122
  (use-package eglot
167
- :ensure t
168
- :pin gnu-devel
169
- :hook ((stan-ts-base-mode . bmw/download-stan-language-server)
170
- (stan-ts-base-mode . eglot-ensure))
123
+ :hook (stan-ts-base-mode . eglot-ensure)
171
124
  :config
172
- (add-to-list
173
- 'eglot-server-programs
174
- `(stan-ts-base-mode . (,bmw/stan-language-server-location "--stdio"))))
125
+ (add-to-list 'eglot-server-programs '(stan-ts-base-mode
126
+ . ("stan-language-server" "--stdio")))
175
127
  ```
176
128
 
177
129
  ## For developers
@@ -1,4 +1,4 @@
1
- import type { CompletionItem, CompletionList, DocumentDiagnosticReport, Hover, InitializeResult, LSPAny, TextEdit } from "vscode-languageserver-protocol";
1
+ import type { CompletionItem, CompletionList, DidChangeTextDocumentParams, DocumentDiagnosticReport, Hover, InitializeResult, LSPAny, PrepareRenameResult, TextEdit, WorkspaceEdit } from "vscode-languageserver-protocol";
2
2
  export interface LSPMessage {
3
3
  jsonrpc: "2.0";
4
4
  id?: number | string;
@@ -22,6 +22,8 @@ export declare class LSPTestClient {
22
22
  private openDocumentUris;
23
23
  serverMessages: LSPMessage[];
24
24
  numRefreshRequest: number;
25
+ stdoutChunks: string[];
26
+ stderrChunks: string[];
25
27
  start(): Promise<void>;
26
28
  stop(): Promise<void>;
27
29
  private handleServerMessage;
@@ -40,6 +42,7 @@ export declare class LSPTestClient {
40
42
  exit(): Promise<void>;
41
43
  didOpen(uri: string, languageId: string, text: string): Promise<void>;
42
44
  didChange(uri: string, text: string, version: number): Promise<void>;
45
+ didChangeRanges(uri: string, contentChanges: DidChangeTextDocumentParams["contentChanges"], version: number): Promise<void>;
43
46
  didClose(uri: string): Promise<void>;
44
47
  closeAll(): Promise<void>;
45
48
  didChangeConfiguration(settings?: LSPAny): Promise<void>;
@@ -47,4 +50,6 @@ export declare class LSPTestClient {
47
50
  formatting(uri: string): Promise<TextEdit[]>;
48
51
  hover(uri: string, line: number, character: number): Promise<Hover | null>;
49
52
  diagnostics(uri: string): Promise<DocumentDiagnosticReport>;
53
+ prepareRename(uri: string, line: number, character: number): Promise<PrepareRenameResult | null>;
54
+ rename(uri: string, line: number, character: number, newName: string): Promise<WorkspaceEdit | null>;
50
55
  }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -1,6 +1,6 @@
1
1
  import type { TextDocument } from "vscode-languageserver-textdocument";
2
- import { type TextDocuments, type WorkspaceFolder, type RemoteConsole } from "vscode-languageserver";
3
- import type { FileSystemReader } from "../../types/common";
2
+ import { type WorkspaceFolder, type RemoteConsole } from "vscode-languageserver";
3
+ import type { FileSystemReader, TextDocumentProvider } from "../../types/common";
4
4
  import { type StancReturn } from "stanc3";
5
5
  export interface Settings {
6
6
  maxLineLength: number;
@@ -9,4 +9,4 @@ export interface Settings {
9
9
  }
10
10
  export declare const defaultSettings: Settings;
11
11
  export type Purpose = "formatting" | "linting";
12
- export declare function handleCompilation(document: TextDocument, documentManager: TextDocuments<TextDocument>, workspaceFolders: WorkspaceFolder[], settings: Settings, purpose: Purpose, logger: RemoteConsole, reader?: FileSystemReader): Promise<StancReturn>;
12
+ export declare function handleCompilation(document: TextDocument, documentManager: TextDocumentProvider, workspaceFolders: WorkspaceFolder[], settings: Settings, purpose: Purpose, logger: RemoteConsole, reader?: FileSystemReader): Promise<StancReturn>;
@@ -1,6 +1,6 @@
1
- import { TextDocuments, WorkspaceFolder, type RemoteConsole } from "vscode-languageserver";
1
+ import { WorkspaceFolder, type RemoteConsole } from "vscode-languageserver";
2
2
  import { TextDocument } from "vscode-languageserver-textdocument";
3
- import type { FileSystemReader } from "../../types";
3
+ import type { FileSystemReader, TextDocumentProvider } from "../../types";
4
4
  export type Filename = string;
5
5
  export type FileContent = string;
6
6
  export type FilePathError = {
@@ -8,4 +8,4 @@ export type FilePathError = {
8
8
  };
9
9
  export declare function getFilenames(fileContent: string): Filename[];
10
10
  export declare function isFilePathError(value: unknown): value is FilePathError;
11
- export declare function handleIncludes(document: TextDocument, documentManager: TextDocuments<TextDocument>, workspaceFolders: WorkspaceFolder[], includePaths: string[], logger: RemoteConsole, reader?: FileSystemReader, alreadyIncluded?: Set<Filename>): Promise<Record<Filename, FileContent>>;
11
+ export declare function handleIncludes(document: TextDocument, documentManager: TextDocumentProvider, workspaceFolders: WorkspaceFolder[], includePaths: string[], logger: RemoteConsole, reader?: FileSystemReader, alreadyIncluded?: Set<Filename>): Promise<Record<Filename, FileContent>>;
@@ -1,4 +1,5 @@
1
- import { type CompletionParams, TextDocuments, CompletionItem } from "vscode-languageserver";
2
- import { TextDocument, type Position } from "vscode-languageserver-textdocument";
1
+ import { type CompletionParams, CompletionItem } from "vscode-languageserver";
2
+ import { type Position } from "vscode-languageserver-textdocument";
3
+ import type { TextDocumentProvider } from "../types/common";
3
4
  export declare const getTextUpToCursor: (text: string, position: Position) => string;
4
- export declare function handleCompletion({ position, textDocument }: CompletionParams, documents: TextDocuments<TextDocument>, supportsSnippets: boolean): CompletionItem[];
5
+ export declare function handleCompletion({ position, textDocument }: CompletionParams, documents: TextDocumentProvider, supportsSnippets: boolean): CompletionItem[];
@@ -1,5 +1,4 @@
1
- import { Diagnostic, TextDocuments, WorkspaceFolder, type DocumentDiagnosticParams, type RemoteConsole } from "vscode-languageserver";
2
- import { TextDocument } from "vscode-languageserver-textdocument";
3
- import type { FileSystemReader } from "../types";
1
+ import { Diagnostic, WorkspaceFolder, type DocumentDiagnosticParams, type RemoteConsole } from "vscode-languageserver";
2
+ import type { FileSystemReader, TextDocumentProvider } from "../types";
4
3
  import { type Settings } from "./compilation/compilation";
5
- export declare function handleDiagnostics(params: DocumentDiagnosticParams, documents: TextDocuments<TextDocument>, workspaceFolders: WorkspaceFolder[], settings: Settings, logger: RemoteConsole, reader?: FileSystemReader): Promise<Diagnostic[]>;
4
+ export declare function handleDiagnostics(params: DocumentDiagnosticParams, documents: TextDocumentProvider, workspaceFolders: WorkspaceFolder[], settings: Settings, logger: RemoteConsole, reader?: FileSystemReader): Promise<Diagnostic[]>;
@@ -1,7 +1,6 @@
1
- import type { DocumentFormattingParams, RemoteConsole, TextDocuments, TextEdit, WorkspaceFolder } from "vscode-languageserver";
2
- import type { TextDocument } from "vscode-languageserver-textdocument";
1
+ import type { DocumentFormattingParams, RemoteConsole, TextEdit, WorkspaceFolder } from "vscode-languageserver";
3
2
  import { type Settings } from "./compilation/compilation";
4
- import type { FileSystemReader } from "../types";
5
- export declare function handleFormatting(params: DocumentFormattingParams, documents: TextDocuments<TextDocument>, workspaceFolders: WorkspaceFolder[], settings: Settings, logger: RemoteConsole, reader?: FileSystemReader): Promise<TextEdit[] | {
3
+ import type { FileSystemReader, TextDocumentProvider } from "../types";
4
+ export declare function handleFormatting(params: DocumentFormattingParams, documents: TextDocumentProvider, workspaceFolders: WorkspaceFolder[], settings: Settings, logger: RemoteConsole, reader?: FileSystemReader): Promise<TextEdit[] | {
6
5
  errors: string[];
7
6
  }>;
@@ -1,5 +1,4 @@
1
1
  import type { HoverParams, Hover } from "vscode-languageserver";
2
2
  import type { TextDocument } from "vscode-languageserver-textdocument";
3
- export declare const manual_functions: string[];
4
3
  declare function handleHover(document: TextDocument, params: HoverParams): Promise<Hover | null>;
5
4
  export default handleHover;
@@ -2,3 +2,4 @@ export { handleCompletion } from "./completion";
2
2
  export { handleDiagnostics } from "./diagnostics";
3
3
  export { default as handleHover } from "./hover";
4
4
  export { handleFormatting } from "./formatting";
5
+ export { handlePrepareRename, handleRename } from "./rename";
@@ -0,0 +1,5 @@
1
+ import type { PrepareRenameParams, PrepareRenameResult, RenameParams, WorkspaceEdit } from "vscode-languageserver-protocol";
2
+ import type { TextDocument } from "vscode-languageserver-textdocument";
3
+ import type { WorkspaceIndex } from "../language/ast/types";
4
+ export declare function handlePrepareRename(document: TextDocument, params: PrepareRenameParams, workspaceIndex: WorkspaceIndex): PrepareRenameResult | null;
5
+ export declare function handleRename(document: TextDocument, params: RenameParams, workspaceIndex: WorkspaceIndex): WorkspaceEdit;
@@ -0,0 +1,11 @@
1
+ import type { Node } from "web-tree-sitter";
2
+ import type { SemanticIndex, SemanticIndexEntry, SourcePosition } from "./types";
3
+ export declare const sourcePositionToTreeSitterPoint: (source: string, position: SourcePosition) => {
4
+ row: number;
5
+ column: number;
6
+ };
7
+ export declare const nodeToRange: (lines: string[], node: Node) => {
8
+ start: SourcePosition;
9
+ end: SourcePosition;
10
+ };
11
+ export declare const buildSemanticIndex: (source: string, tree: SemanticIndexEntry["tree"]) => SemanticIndex;
@@ -0,0 +1,6 @@
1
+ import type { SemanticIndexEntry, SourcePosition, SymbolId } from "./types";
2
+ import { nodeToRange } from "./semantic_index";
3
+ export declare const symbolAtPosition: (index: Pick<SemanticIndexEntry, "tree" | "semanticIndex">, source: string, position: SourcePosition) => {
4
+ symbolId: SymbolId;
5
+ range: ReturnType<typeof nodeToRange>;
6
+ } | undefined;
@@ -0,0 +1,50 @@
1
+ import type { Tree } from "web-tree-sitter";
2
+ export type SourcePosition = {
3
+ line: number;
4
+ character: number;
5
+ };
6
+ export type SourceRange = {
7
+ start: SourcePosition;
8
+ end: SourcePosition;
9
+ };
10
+ export type SymbolId = string;
11
+ export type ReferenceId = string;
12
+ export type SymbolKind = "function" | "value";
13
+ export type SymbolInfo = {
14
+ id: SymbolId;
15
+ name: string;
16
+ kind: SymbolKind;
17
+ range: SourceRange;
18
+ nodeId: number;
19
+ };
20
+ export type ReferenceInfo = {
21
+ id: ReferenceId;
22
+ symbolId: SymbolId;
23
+ range: SourceRange;
24
+ nodeId: number;
25
+ };
26
+ export type NameInfo = {
27
+ kind: "declaration";
28
+ symbolId: SymbolId;
29
+ renameable: boolean;
30
+ } | {
31
+ kind: "reference";
32
+ refId?: ReferenceId;
33
+ renameable: boolean;
34
+ };
35
+ export type SemanticIndex = {
36
+ nameInfoByNodeId: Map<number, NameInfo>;
37
+ symbolsById: Map<SymbolId, SymbolInfo>;
38
+ referencesById: Map<ReferenceId, ReferenceInfo>;
39
+ referenceIdsBySymbolId: Map<SymbolId, ReferenceId[]>;
40
+ };
41
+ export type SemanticIndexEntry = {
42
+ uri: string;
43
+ version: number;
44
+ text: string;
45
+ tree: Tree;
46
+ semanticIndex: SemanticIndex;
47
+ };
48
+ export type WorkspaceIndex = {
49
+ entries: Map<string, SemanticIndexEntry>;
50
+ };