├── .gitignore ├── .vscode ├── extensions.json ├── launch.json ├── settings.json └── tasks.json ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── SECURITY.md ├── anycode-c-sharp ├── .vscodeignore ├── LICENSE ├── azure-pipelines.yml ├── fixtures │ ├── highlights.cs │ └── outline.cs ├── package-lock.json ├── package.json └── queries │ ├── comments.scm │ ├── identifiers.scm │ ├── locals.scm │ ├── outline.scm │ └── references.scm ├── anycode-cpp ├── .vscodeignore ├── LICENSE ├── azure-pipelines.yml ├── fixtures │ └── outline.c ├── package-lock.json ├── package.json └── queries │ ├── c │ ├── comments.scm │ ├── identifiers.scm │ └── outline.scm │ └── cpp │ ├── comments.scm │ ├── identifiers.scm │ └── outline.scm ├── anycode-go ├── .vscodeignore ├── LICENSE ├── azure-pipelines.yml ├── fixtures │ ├── highlights.go │ └── outline.go ├── package-lock.json ├── package.json └── queries │ ├── comments.scm │ ├── folding.scm │ ├── identifiers.scm │ ├── locals.scm │ ├── outline.scm │ └── references.scm ├── anycode-java ├── .vscodeignore ├── LICENSE ├── azure-pipelines.yml ├── fixtures │ ├── highlights.java │ └── outline.java ├── package-lock.json ├── package.json └── queries │ ├── comments.scm │ ├── folding.scm │ ├── identifiers.scm │ ├── locals.scm │ ├── outline.scm │ └── references.scm ├── anycode-kotlin ├── LICENSE ├── azure-pipelines.yml ├── package-lock.json ├── package.json └── queries │ ├── comments.scm │ ├── folding.scm │ ├── identifiers.scm │ └── references.scm ├── anycode-php ├── .vscodeignore ├── LICENSE ├── azure-pipelines.yml ├── fixtures │ └── highlights.php ├── package-lock.json ├── package.json └── queries │ ├── comments.scm │ ├── identifiers.scm │ ├── locals.scm │ ├── outline.scm │ └── references.scm ├── anycode-python ├── .vscodeignore ├── LICENSE ├── azure-pipelines.yml ├── fixtures │ ├── highlights.py │ └── outline.py ├── package-lock.json ├── package.json └── queries │ ├── comments.scm │ ├── identifiers.scm │ ├── locals.scm │ ├── outline.scm │ └── references.scm ├── anycode-rust ├── .vscodeignore ├── LICENSE ├── azure-pipelines.yml ├── fixtures │ ├── highlights.rs │ └── outline.rs ├── index.js ├── package-lock.json ├── package.json └── queries │ ├── comments.scm │ ├── folding.scm │ ├── identifiers.scm │ ├── locals.scm │ ├── outline.scm │ └── references.scm ├── anycode-typescript ├── .vscodeignore ├── LICENSE ├── azure-pipelines.yml ├── fixtures │ ├── highlights.ts │ └── outline.ts ├── package-lock.json ├── package.json └── queries │ ├── comments.scm │ ├── identifiers.scm │ ├── locals.scm │ ├── outline.scm │ └── references.scm ├── anycode ├── .eslintrc.json ├── .vscodeignore ├── LICENSE ├── README.md ├── azure-pipelines.yml ├── client │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── browser │ │ │ └── main.ts │ │ ├── common │ │ │ ├── client.ts │ │ │ ├── supportedLanguages.ts │ │ │ ├── vscode.d.ts │ │ │ └── vscode.proposed.extensionsAny.d.ts │ │ └── node │ │ │ └── main.ts │ ├── tsconfig.browser.json │ └── tsconfig.node.json ├── esbuild.js ├── package-lock.json ├── package.json ├── server │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── browser │ │ │ ├── main.ts │ │ │ └── storage.ts │ │ ├── common │ │ │ ├── common.ts │ │ │ ├── documentStore.ts │ │ │ ├── features │ │ │ │ ├── completions.ts │ │ │ │ ├── definitions.ts │ │ │ │ ├── documentHighlights.ts │ │ │ │ ├── documentSymbols.ts │ │ │ │ ├── foldingRanges.ts │ │ │ │ ├── locals.ts │ │ │ │ ├── references.ts │ │ │ │ ├── selectionRanges.ts │ │ │ │ ├── symbolIndex.ts │ │ │ │ ├── validation.ts │ │ │ │ └── workspaceSymbols.ts │ │ │ ├── languages.ts │ │ │ ├── server.ts │ │ │ ├── test-fixture │ │ │ │ ├── client │ │ │ │ │ ├── documentHighlights.test.ts │ │ │ │ │ ├── documentSymbols.test.ts │ │ │ │ │ ├── queries.test.ts │ │ │ │ │ ├── test.all.ts │ │ │ │ │ ├── test.html │ │ │ │ │ └── utils.ts │ │ │ │ ├── jsconfig.json │ │ │ │ └── test.js │ │ │ ├── test │ │ │ │ ├── trie.test.js │ │ │ │ └── trie.test.ts │ │ │ ├── trees.ts │ │ │ └── util │ │ │ │ ├── lruMap.ts │ │ │ │ └── trie.ts │ │ └── node │ │ │ ├── main.ts │ │ │ └── storage.ts │ ├── tsconfig.browser.json │ └── tsconfig.node.json ├── shared │ └── common │ │ ├── base64.ts │ │ ├── env.d.ts │ │ ├── initOptions.ts │ │ └── messages.ts ├── tsconfig.base.json └── tsconfig.json └── scripts ├── all-npm.js ├── version-tag.js └── version-up.js /.gitignore: -------------------------------------------------------------------------------- 1 | out 2 | dist 3 | node_modules 4 | .vscode-test/ 5 | .vscode-test-web/ 6 | *.vsix 7 | tree-sitter-*.wasm 8 | */server/src/test/**/*.js 9 | **/test-fixture/**/*.js 10 | !**/test-fixture/test.js 11 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "jrieken.vscode-tree-sitter-query" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "args": [ 9 | "--extensionDevelopmentPath=${workspaceFolder}/anycode" 10 | ], 11 | "name": "Launch Extension", 12 | "preLaunchTask": "npm: watch", 13 | "request": "launch", 14 | "type": "extensionHost", 15 | "sourceMaps": true 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsserver.experimental.enableProjectDiagnostics": true, 3 | "editor.formatOnSave": true, 4 | "[typescript]": { 5 | "editor.defaultFormatter": "vscode.typescript-language-features" 6 | }, 7 | "git.branchProtection": [ 8 | "main" 9 | ], 10 | } 11 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "type": "npm", 6 | "script": "watch", 7 | "group": "build", 8 | "isBackground": true, 9 | "problemMatcher": [], 10 | "path": "anycode", 11 | "label": "npm: watch", 12 | "detail": "node esbuild.js --watch", 13 | "runOptions": { 14 | "runOn": "folderOpen" 15 | }, 16 | "presentation": { 17 | "reveal": "never", 18 | } 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Microsoft Open Source Code of Conduct 2 | 3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 4 | 5 | Resources: 6 | 7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) 8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) 9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Anycode 2 | 3 | A [Tree-sitter](https://tree-sitter.github.io/tree-sitter/)-based language extension that _inaccurately_ implements popular features like "Outline & Breadcrumbs", "Go to Symbol in Workspace", "Document Highlights" and more. This extension should be used when running in enviroments that don't allow for running actual language services, like https://github.dev or https://vscode.dev. 4 | 5 | --- 6 | 7 | This is the mono-repo for **Anycode** itself and its languages: the `anycode`-folder is a LSP client and server that implements basic language features and all `anycode-XYZ` folders are for the respective `XYZ` languages. 8 | 9 | --- 10 | 11 | ## Development 12 | 13 | To **compile** tree-sitter languages you need docker or emscripten, follow these steps: 14 | 15 | * have `emcc` on your path or `docker` running 16 | * run `node ./scripts/all-npm.js i` 17 | 18 | 19 | ## Contributing 20 | 21 | This project welcomes contributions and suggestions. Most contributions require you to agree to a 22 | Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us 23 | the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com. 24 | 25 | When you submit a pull request, a CLA bot will automatically determine whether you need to provide 26 | a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions 27 | provided by the bot. You will only need to do this once across all repos using our CLA. 28 | 29 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 30 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or 31 | contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. 32 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc751383(v=technet.10)), please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** 12 | 13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report). 14 | 15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://www.microsoft.com/en-us/msrc/pgp-key-msrc). 16 | 17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc). 18 | 19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 20 | 21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 22 | * Full paths of source file(s) related to the manifestation of the issue 23 | * The location of the affected source code (tag/branch/commit or direct URL) 24 | * Any special configuration required to reproduce the issue 25 | * Step-by-step instructions to reproduce the issue 26 | * Proof-of-concept or exploit code (if possible) 27 | * Impact of the issue, including how an attacker might exploit the issue 28 | 29 | This information will help us triage your report more quickly. 30 | 31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://microsoft.com/msrc/bounty) page for more details about our active programs. 32 | 33 | ## Preferred Languages 34 | 35 | We prefer all communications to be in English. 36 | 37 | ## Policy 38 | 39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://www.microsoft.com/en-us/msrc/cvd). 40 | 41 | -------------------------------------------------------------------------------- /anycode-c-sharp/.vscodeignore: -------------------------------------------------------------------------------- 1 | azure-pipelines.yml 2 | -------------------------------------------------------------------------------- /anycode-c-sharp/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE 22 | -------------------------------------------------------------------------------- /anycode-c-sharp/azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | name: $(Date:yyyyMMdd)$(Rev:.r) 2 | 3 | trigger: 4 | branches: 5 | include: 6 | - main 7 | paths: 8 | include: 9 | - anycode-c-sharp 10 | pr: none 11 | 12 | resources: 13 | repositories: 14 | - repository: templates 15 | type: github 16 | name: microsoft/vscode-engineering 17 | ref: main 18 | endpoint: Monaco 19 | 20 | parameters: 21 | - name: publishExtension 22 | displayName: 🚀 Publish Extension 23 | type: boolean 24 | default: false 25 | 26 | extends: 27 | template: azure-pipelines/extension/stable.yml@templates 28 | parameters: 29 | buildSteps: 30 | - script: cd anycode-c-sharp && npm install 31 | displayName: Install dependencies 32 | 33 | - script: cd anycode && npm install 34 | displayName: Install dependencies (anycode) 35 | 36 | - script: cd anycode-c-sharp && npm run test 37 | displayName: Run Test Fixtures 38 | 39 | ghCreateTag: true 40 | ghTagPrefix: anycode-c-sharp.v 41 | 42 | publishExtension: ${{ parameters.publishExtension }} 43 | 44 | tsa: 45 | config: 46 | areaPath: 'Visual Studio Code Language Extensions' 47 | serviceTreeID: 'c4cd3983-4977-4bcd-931f-a9822d2e950c' 48 | enabled: true 49 | 50 | cgSourceScanPath: $(Build.SourcesDirectory)/anycode-c-sharp 51 | workingDirectory: $(Build.SourcesDirectory)/anycode-c-sharp 52 | -------------------------------------------------------------------------------- /anycode-c-sharp/fixtures/outline.cs: -------------------------------------------------------------------------------- 1 | // ### class 2 | class YourDerivedGraphicsClass : GraphicsClass 3 | // ^ 4 | { 5 | public new void DrawRectangle() { } 6 | // ^ 7 | } 8 | 9 | // ### class 2 10 | public class Derived : Base 11 | // ^ 12 | { 13 | public override void DoWork(int param) { } 14 | // ^ 15 | public void DoWork(double param) { } 16 | // ^ 17 | } 18 | // ### static class 19 | public static class TemperatureConverter 20 | // ^ 21 | { 22 | public static double CelsiusToFahrenheit(string temperatureCelsius) 23 | // ^ 24 | { 25 | // Convert argument to double for calculations. 26 | double celsius = Double.Parse(temperatureCelsius); 27 | 28 | // Convert Celsius to Fahrenheit. 29 | double fahrenheit = (celsius * 9 / 5) + 32; 30 | 31 | return fahrenheit; 32 | } 33 | 34 | public static double FahrenheitToCelsius(string temperatureFahrenheit) 35 | // ^ 36 | { 37 | // Convert argument to double for calculations. 38 | double fahrenheit = Double.Parse(temperatureFahrenheit); 39 | 40 | // Convert Fahrenheit to Celsius. 41 | double celsius = (fahrenheit - 32) * 5 / 9; 42 | 43 | return celsius; 44 | } 45 | } 46 | // ### static members 47 | public class Automobile 48 | // ^ 49 | { 50 | public static int NumberOfWheels = 4; 51 | // ^ 52 | 53 | public static int SizeOfGasTank 54 | // ^ 55 | { 56 | get 57 | { 58 | return 15; 59 | } 60 | } 61 | 62 | public static void Drive() { } 63 | // ^ 64 | 65 | public static event EventType RunOutOfGas; 66 | // ^ 67 | } 68 | // ### class, field 69 | public class CalendarDateWithInitialization 70 | // ^ 71 | { 72 | public string Day = "Monday"; 73 | // ^ 74 | } 75 | // ### delegate 76 | delegate void Del(); 77 | // ^ 78 | -------------------------------------------------------------------------------- /anycode-c-sharp/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "anycode-c-sharp", 3 | "publisher": "ms-vscode", 4 | "displayName": "anycode-c-sharp", 5 | "description": "C# for Anycode", 6 | "license": "MIT", 7 | "version": "0.0.8", 8 | "preview": true, 9 | "repository": { 10 | "url": "https://github.com/microsoft/vscode-anycode" 11 | }, 12 | "engines": { 13 | "vscode": "^1.67.0" 14 | }, 15 | "categories": [ 16 | "Programming Languages" 17 | ], 18 | "contributes": { 19 | "anycodeLanguages": { 20 | "grammarPath": "./tree-sitter-c_sharp.wasm", 21 | "languageId": "csharp", 22 | "extensions": [ 23 | "cs" 24 | ], 25 | "queryPaths": { 26 | "comments": "./queries/comments.scm", 27 | "identifiers": "./queries/identifiers.scm", 28 | "locals": "./queries/locals.scm", 29 | "outline": "./queries/outline.scm", 30 | "references": "./queries/references.scm" 31 | }, 32 | "suppressedBy": [ 33 | "ms-dotnettools.csharp" 34 | ] 35 | } 36 | }, 37 | "scripts": { 38 | "postinstall": "npx tree-sitter build-wasm node_modules/tree-sitter-c-sharp", 39 | "deploy": "npx vsce publish", 40 | "test": "node ../anycode/server/src/common/test-fixture/test.js --outline ./fixtures/outline.cs --highlights ./fixtures/highlights.cs" 41 | }, 42 | "devDependencies": { 43 | "@playwright/test": "^1.14.1", 44 | "tree-sitter-cli": "^0.20.8", 45 | "tree-sitter-c-sharp": "^0.23.1" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /anycode-c-sharp/queries/comments.scm: -------------------------------------------------------------------------------- 1 | (comment) @comment 2 | -------------------------------------------------------------------------------- /anycode-c-sharp/queries/identifiers.scm: -------------------------------------------------------------------------------- 1 | (identifier) @identifier 2 | -------------------------------------------------------------------------------- /anycode-c-sharp/queries/locals.scm: -------------------------------------------------------------------------------- 1 | (namespace_declaration body: (_) @scope.exports) 2 | (class_declaration) @scope 3 | (interface_declaration) @scope 4 | (constructor_declaration) @scope 5 | (method_declaration) @scope 6 | (if_statement [consequence: (_) @scope alternative: (_) @scope]) 7 | (foreach_statement) @scope 8 | (for_statement) @scope 9 | (do_statement) @scope 10 | (while_statement) @scope 11 | (using_statement) @scope 12 | (block) @scope 13 | 14 | (class_declaration name: (identifier) @local.escape) 15 | (interface_declaration name: (identifier) @local.escape) 16 | (constructor_declaration name: (identifier) @local.escape) 17 | (method_declaration name: (identifier) @local.escape) 18 | (parameter name: (identifier) @local) 19 | (variable_declarator (identifier) @local) 20 | (type_parameter (identifier) @local) 21 | (foreach_statement left: (identifier) @local) 22 | (query_expression [ 23 | (from_clause . (identifier) @local) 24 | ]) 25 | 26 | (member_access_expression name: (identifier) @usage.void) 27 | (identifier) @usage 28 | -------------------------------------------------------------------------------- /anycode-c-sharp/queries/outline.scm: -------------------------------------------------------------------------------- 1 | 2 | (class_declaration 3 | name: (identifier) @class.name 4 | ) @class 5 | 6 | (interface_declaration 7 | name: (identifier) @interface.name 8 | ) @interface 9 | 10 | (record_declaration 11 | name: (identifier) @record.name 12 | ) @record 13 | 14 | (record_declaration 15 | (parameter_list 16 | (parameter 17 | name: (identifier) @property.name 18 | ) @property 19 | ) 20 | ) 21 | 22 | (constructor_declaration 23 | name: (identifier) @constructor.name 24 | ) @constructor 25 | 26 | (destructor_declaration 27 | (identifier) @method.name 28 | ) @method 29 | 30 | (indexer_declaration 31 | (bracketed_parameter_list) @method.name 32 | ) @method 33 | 34 | (method_declaration 35 | name: (identifier) @method.name 36 | ) @method 37 | 38 | (property_declaration 39 | name: (identifier) @property.name 40 | ) @property 41 | 42 | (delegate_declaration 43 | name: (identifier) @function.name 44 | ) @function 45 | 46 | (field_declaration 47 | (variable_declaration 48 | (variable_declarator 49 | (identifier) @field.name 50 | ) 51 | ) 52 | ) @field 53 | 54 | (event_field_declaration 55 | (variable_declaration 56 | (variable_declarator 57 | (identifier) @event.name 58 | ) 59 | ) 60 | ) @event 61 | 62 | (attribute_list 63 | (attribute 64 | (identifier) @constant.name 65 | ) @constant 66 | ) 67 | 68 | (global_statement 69 | (local_declaration_statement 70 | (variable_declaration 71 | (variable_declarator 72 | (identifier) @variable.name 73 | ) 74 | ) 75 | ) 76 | ) 77 | 78 | (enum_declaration name: 79 | (identifier) @enum.name 80 | ) @enum 81 | 82 | (struct_declaration 83 | (identifier) @struct.name 84 | ) @struct 85 | 86 | (namespace_declaration 87 | [ 88 | name: (identifier) @module.name 89 | name: (qualified_name) @module.name 90 | ] 91 | ) @module 92 | 93 | (enum_member_declaration 94 | (identifier) @enumMember.name 95 | ) @enumMember 96 | -------------------------------------------------------------------------------- /anycode-c-sharp/queries/references.scm: -------------------------------------------------------------------------------- 1 | (object_creation_expression 2 | type: (identifier) @ref.type) 3 | (type_parameter 4 | name: (identifier) @ref.type) 5 | (variable_declaration 6 | type: (identifier) @ref.type) 7 | (member_access_expression 8 | name: (identifier) @ref) 9 | (invocation_expression 10 | function: (identifier) @ref) 11 | (base_list (_) @ref.type) 12 | -------------------------------------------------------------------------------- /anycode-cpp/.vscodeignore: -------------------------------------------------------------------------------- 1 | azure-pipelines.yml 2 | -------------------------------------------------------------------------------- /anycode-cpp/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE 22 | -------------------------------------------------------------------------------- /anycode-cpp/azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | name: $(Date:yyyyMMdd)$(Rev:.r) 2 | 3 | trigger: 4 | branches: 5 | include: 6 | - main 7 | paths: 8 | include: 9 | - anycode-cpp 10 | pr: none 11 | 12 | resources: 13 | repositories: 14 | - repository: templates 15 | type: github 16 | name: microsoft/vscode-engineering 17 | ref: main 18 | endpoint: Monaco 19 | 20 | parameters: 21 | - name: publishExtension 22 | displayName: 🚀 Publish Extension 23 | type: boolean 24 | default: false 25 | 26 | extends: 27 | template: azure-pipelines/extension/stable.yml@templates 28 | parameters: 29 | buildSteps: 30 | - script: cd anycode-cpp && npm install 31 | displayName: Install dependencies 32 | 33 | - script: cd anycode && npm install 34 | displayName: Install dependencies (anycode) 35 | 36 | - script: cd anycode-cpp && npm run test 37 | displayName: Run Test Fixtures 38 | 39 | ghCreateTag: true 40 | ghTagPrefix: anycode-cpp.v 41 | 42 | publishExtension: ${{ parameters.publishExtension }} 43 | 44 | tsa: 45 | config: 46 | areaPath: 'Visual Studio Code Language Extensions' 47 | serviceTreeID: 'c4cd3983-4977-4bcd-931f-a9822d2e950c' 48 | enabled: true 49 | 50 | cgSourceScanPath: $(Build.SourcesDirectory)/anycode-cpp 51 | workingDirectory: $(Build.SourcesDirectory)/anycode-cpp 52 | -------------------------------------------------------------------------------- /anycode-cpp/fixtures/outline.c: -------------------------------------------------------------------------------- 1 | // ### simple function 2 | int cool_function(int i){ 3 | // ^ 4 | return i*2; 5 | } 6 | -------------------------------------------------------------------------------- /anycode-cpp/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "anycode-cpp", 3 | "publisher": "ms-vscode", 4 | "displayName": "anycode-cpp", 5 | "description": "C/C++ for Anycode", 6 | "license": "MIT", 7 | "version": "0.0.7", 8 | "preview": true, 9 | "repository": { 10 | "url": "https://github.com/microsoft/vscode-anycode" 11 | }, 12 | "engines": { 13 | "vscode": "^1.67.0" 14 | }, 15 | "categories": [ 16 | "Programming Languages" 17 | ], 18 | "contributes": { 19 | "anycodeLanguages": [ 20 | { 21 | "grammarPath": "./tree-sitter-c.wasm", 22 | "languageId": "c", 23 | "extensions": [ 24 | "c", 25 | "i" 26 | ], 27 | "queryPaths": { 28 | "comments": "./queries/c/comments.scm", 29 | "identifiers": "./queries/c/identifiers.scm", 30 | "outline": "./queries/c/outline.scm" 31 | }, 32 | "suppressedBy": [ 33 | "ms-vscode.cpptools" 34 | ] 35 | }, 36 | { 37 | "grammarPath": "./tree-sitter-cpp.wasm", 38 | "languageId": "cpp", 39 | "extensions": [ 40 | "cpp", 41 | "cc", 42 | "cxx", 43 | "c++", 44 | "hpp", 45 | "hh", 46 | "hxx", 47 | "h++", 48 | "h", 49 | "ii", 50 | "ino", 51 | "inl", 52 | "ipp", 53 | "ixx", 54 | "hpp.in", 55 | "h.in" 56 | ], 57 | "queryPaths": { 58 | "comments": "./queries/cpp/comments.scm", 59 | "identifiers": "./queries/cpp/identifiers.scm", 60 | "outline": "./queries/cpp/outline.scm" 61 | }, 62 | "suppressedBy": [ 63 | "ms-vscode.cpptools" 64 | ] 65 | } 66 | ] 67 | }, 68 | "scripts": { 69 | "postinstall": "npx tree-sitter build-wasm node_modules/tree-sitter-c && npx tree-sitter build-wasm node_modules/tree-sitter-cpp", 70 | "deploy": "npx vsce publish", 71 | "test": "node ../anycode/server/src/common/test-fixture/test.js --outline ./fixtures/outline.c" 72 | }, 73 | "devDependencies": { 74 | "@playwright/test": "^1.14.1", 75 | "tree-sitter-cli": "^0.20.8", 76 | "tree-sitter-cpp": "^0.20.5", 77 | "tree-sitter-c": "^0.20.8" 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /anycode-cpp/queries/c/comments.scm: -------------------------------------------------------------------------------- 1 | (comment) @comment 2 | -------------------------------------------------------------------------------- /anycode-cpp/queries/c/identifiers.scm: -------------------------------------------------------------------------------- 1 | (identifier) @identifier 2 | (field_identifier) @identifier 3 | (type_identifier) @identifier 4 | -------------------------------------------------------------------------------- /anycode-cpp/queries/c/outline.scm: -------------------------------------------------------------------------------- 1 | (struct_specifier 2 | name: (type_identifier) @struct.name) @struct 3 | 4 | (union_specifier 5 | name: (type_identifier) @struct.name) @struct 6 | 7 | (enum_specifier 8 | name: (type_identifier) @enum.name) @enum 9 | 10 | (enumerator 11 | name: (identifier) @enumMember.name) @enumMember 12 | 13 | (function_definition 14 | declarator: (function_declarator 15 | [ 16 | (identifier) @function.name 17 | (field_identifier) @function.name 18 | ])) @function 19 | 20 | (pointer_declarator 21 | declarator: (function_declarator 22 | declarator: (identifier) @function.name) @function) 23 | 24 | (declaration 25 | declarator: (function_declarator 26 | [ 27 | (identifier) @function.name 28 | (field_identifier) @function.name 29 | ]) @function) 30 | 31 | (declaration 32 | type: (primitive_type) 33 | declarator: (identifier) @variable.name) @variable 34 | 35 | (type_definition 36 | type: (_) 37 | declarator: (type_identifier) @struct.name) @struct 38 | 39 | (linkage_specification 40 | value: (string_literal) @struct.name) @struct 41 | 42 | (field_declaration 43 | (function_declarator 44 | [ 45 | (identifier) @function.name 46 | (field_identifier) @function.name 47 | ] 48 | )) @function 49 | 50 | 51 | (field_declaration 52 | (field_identifier) @field.name) @field 53 | 54 | (field_declaration_list 55 | (field_declaration 56 | [ 57 | declarator: (field_identifier) @field.name 58 | (array_declarator 59 | declarator: (field_identifier) @field.name 60 | ) 61 | ] 62 | ) @field) 63 | -------------------------------------------------------------------------------- /anycode-cpp/queries/cpp/comments.scm: -------------------------------------------------------------------------------- 1 | (comment) @comment 2 | -------------------------------------------------------------------------------- /anycode-cpp/queries/cpp/identifiers.scm: -------------------------------------------------------------------------------- 1 | (identifier) @identifier 2 | (field_identifier) @identifier 3 | (type_identifier) @identifier 4 | (namespace_identifier) @identifier 5 | -------------------------------------------------------------------------------- /anycode-cpp/queries/cpp/outline.scm: -------------------------------------------------------------------------------- 1 | ;; START copy of c/outline.scm 2 | 3 | (struct_specifier 4 | name: (type_identifier) @struct.name) @struct 5 | 6 | (union_specifier 7 | name: (type_identifier) @struct.name) @struct 8 | 9 | (enum_specifier 10 | name: (type_identifier) @enum.name) @enum 11 | 12 | (enumerator 13 | name: (identifier) @enumMember.name) @enumMember 14 | 15 | (function_definition 16 | declarator: (function_declarator 17 | [ 18 | (identifier) @function.name 19 | (field_identifier) @function.name 20 | ])) @function 21 | 22 | (pointer_declarator 23 | declarator: (function_declarator 24 | declarator: (identifier) @function.name) @function) 25 | 26 | (declaration 27 | declarator: (function_declarator 28 | [ 29 | (identifier) @function.name 30 | (field_identifier) @function.name 31 | ]) @function) 32 | 33 | (declaration 34 | type: (primitive_type) 35 | declarator: (identifier) @variable.name) @variable 36 | 37 | (type_definition 38 | type: (_) 39 | declarator: (type_identifier) @struct.name) @struct 40 | 41 | (linkage_specification 42 | value: (string_literal) @struct.name) @struct 43 | 44 | (field_declaration 45 | (function_declarator 46 | [ 47 | (identifier) @function.name 48 | (field_identifier) @function.name 49 | ] 50 | )) @function 51 | 52 | 53 | (field_declaration 54 | (field_identifier) @field.name) @field 55 | 56 | (field_declaration_list 57 | (field_declaration 58 | [ 59 | declarator: (field_identifier) @field.name 60 | (array_declarator 61 | declarator: (field_identifier) @field.name 62 | ) 63 | ] 64 | ) @field) 65 | 66 | ;; END copy of c/outline.scm 67 | 68 | (namespace_definition 69 | name: (namespace_identifier) @module.name) @module 70 | 71 | (friend_declaration 72 | (type_identifier) @variable.name) @variable 73 | 74 | (field_declaration 75 | (function_declarator 76 | (qualified_identifier) @function.name)) @function 77 | 78 | (declaration 79 | (function_declarator 80 | [ 81 | (qualified_identifier) @function.name 82 | (destructor_name) @function.name 83 | ]) @function) 84 | 85 | (class_specifier 86 | (type_identifier) @class.name) @class 87 | -------------------------------------------------------------------------------- /anycode-go/.vscodeignore: -------------------------------------------------------------------------------- 1 | azure-pipelines.yml 2 | -------------------------------------------------------------------------------- /anycode-go/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE 22 | -------------------------------------------------------------------------------- /anycode-go/azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | name: $(Date:yyyyMMdd)$(Rev:.r) 2 | 3 | trigger: 4 | branches: 5 | include: 6 | - main 7 | paths: 8 | include: 9 | - anycode-go 10 | pr: none 11 | 12 | resources: 13 | repositories: 14 | - repository: templates 15 | type: github 16 | name: microsoft/vscode-engineering 17 | ref: main 18 | endpoint: Monaco 19 | 20 | parameters: 21 | - name: publishExtension 22 | displayName: 🚀 Publish Extension 23 | type: boolean 24 | default: false 25 | 26 | extends: 27 | template: azure-pipelines/extension/stable.yml@templates 28 | parameters: 29 | buildSteps: 30 | - script: cd anycode-go && npm install 31 | displayName: Install dependencies 32 | 33 | - script: cd anycode && npm install 34 | displayName: Install dependencies (anycode) 35 | 36 | - script: cd anycode-go && npm run test 37 | displayName: Run Test Fixtures 38 | 39 | ghCreateTag: true 40 | ghTagPrefix: anycode-go.v 41 | 42 | publishExtension: ${{ parameters.publishExtension }} 43 | 44 | tsa: 45 | config: 46 | areaPath: 'Visual Studio Code Language Extensions' 47 | serviceTreeID: 'c4cd3983-4977-4bcd-931f-a9822d2e950c' 48 | enabled: true 49 | 50 | cgSourceScanPath: $(Build.SourcesDirectory)/anycode-go 51 | workingDirectory: $(Build.SourcesDirectory)/anycode-go 52 | -------------------------------------------------------------------------------- /anycode-go/fixtures/highlights.go: -------------------------------------------------------------------------------- 1 | // ### paramter 2 | func AbsFunc(v Vertex) float64 { 3 | // ^ 4 | return math.Sqrt(v.v*v.X + v.Y*v.Y) 5 | // ^ 6 | // ^ 7 | // ^ 8 | // ^ 9 | } 10 | // ### variable 11 | func main() { 12 | v := Vertex{3, 4} 13 | // ^ 14 | fmt.Println(v.Abs()) 15 | // ^ 16 | fmt.Println(AbsFunc(v)) 17 | // ^ 18 | p := &Vertex{4, 3} 19 | fmt.Println(p.Abs()) 20 | fmt.Println(AbsFunc(*p)) 21 | } 22 | // ### parameter/switch 23 | func do(i interface{}) { 24 | // ^ 25 | switch v := i.(type) { 26 | // ^ 27 | case int: 28 | fmt.Printf("Twice %v is %v\n", v, v*2) 29 | case string: 30 | fmt.Printf("%q is %v bytes long\n", v, len(v)) 31 | default: 32 | fmt.Printf("I don't know about type %T!\n", v) 33 | } 34 | } 35 | // ### switch-type 36 | func do(i interface{}) { 37 | switch v := i.(type) { 38 | // ^ 39 | case int: 40 | fmt.Printf("Twice %v is %v\n", v, v*2) 41 | // ^ 42 | // ^ 43 | case string: 44 | fmt.Printf("%q is %v bytes long\n", v, len(v)) 45 | // ^ 46 | // ^ 47 | default: 48 | fmt.Printf("I don't know about type %T!\n", v) 49 | // ^ 50 | } 51 | } 52 | // ### comments 53 | // Vertex 54 | type Vertex struct { 55 | // ^ 56 | X, Y float64 57 | } 58 | func (v Vertex) Abs() float64 { 59 | // ^ 60 | return math.Sqrt(v.X*v.X + v.Y*v.Y) 61 | } 62 | -------------------------------------------------------------------------------- /anycode-go/fixtures/outline.go: -------------------------------------------------------------------------------- 1 | // ### trait 2 | func (me *MySQLError) Is(err error) bool { 3 | // ^ 4 | if merr, ok := err.(*MySQLError); ok { 5 | return merr.Number == me.Number 6 | } 7 | return false 8 | } 9 | // ### struct 10 | type MySQLError struct { 11 | // ^ 12 | Number uint16 13 | // ^ 14 | Message string 15 | // ^ 16 | } 17 | // ### spread variable 18 | var ( 19 | ErrInvalidConn = errors.New("invalid connection") 20 | // ^ 21 | ErrMalformPkt = errors.New("malformed packet") 22 | // ^ 23 | ErrNoTLS = errors.New("TLS requested but server does not support TLS") 24 | // ^ 25 | ) 26 | // ### /SKIP/ multiple vars, one line 27 | var c, python, java bool 28 | // ^ 29 | // ^ 30 | // ^ 31 | // ### type alias 32 | type MyFloat float64 33 | // ^ 34 | // ### https://github.com/microsoft/vscode-anycode/issues/4 35 | func TestReverse() { 36 | // ^ 37 | for _, c := range []struct { 38 | in, want string 39 | // ^ 40 | // ^ 41 | }{ 42 | {"",""} 43 | }{ 44 | 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /anycode-go/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "anycode-go", 3 | "publisher": "ms-vscode", 4 | "displayName": "anycode-go", 5 | "description": "Go for Anycode", 6 | "license": "MIT", 7 | "version": "0.0.8", 8 | "preview": true, 9 | "repository": { 10 | "url": "https://github.com/microsoft/vscode-anycode" 11 | }, 12 | "engines": { 13 | "vscode": "^1.67.0" 14 | }, 15 | "categories": [ 16 | "Programming Languages" 17 | ], 18 | "contributes": { 19 | "anycodeLanguages": { 20 | "grammarPath": "./tree-sitter-go.wasm", 21 | "languageId": "go", 22 | "extensions": [ 23 | "go" 24 | ], 25 | "queryPaths": { 26 | "comments": "./queries/comments.scm", 27 | "identifiers": "./queries/identifiers.scm", 28 | "locals": "./queries/locals.scm", 29 | "outline": "./queries/outline.scm", 30 | "references": "./queries/references.scm" 31 | }, 32 | "suppressedBy": [ 33 | "golang.Go" 34 | ] 35 | } 36 | }, 37 | "scripts": { 38 | "postinstall": "npx tree-sitter build-wasm node_modules/tree-sitter-go", 39 | "deploy": "npx vsce publish", 40 | "test": "node ../anycode/server/src/common/test-fixture/test.js --outline ./fixtures/outline.go --highlights ./fixtures/highlights.go" 41 | }, 42 | "devDependencies": { 43 | "@playwright/test": "^1.14.1", 44 | "tree-sitter-cli": "^0.20.8", 45 | "tree-sitter-go": "^0.23.4" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /anycode-go/queries/comments.scm: -------------------------------------------------------------------------------- 1 | (comment) @comment 2 | -------------------------------------------------------------------------------- /anycode-go/queries/folding.scm: -------------------------------------------------------------------------------- 1 | (block) @scope 2 | -------------------------------------------------------------------------------- /anycode-go/queries/identifiers.scm: -------------------------------------------------------------------------------- 1 | (type_identifier) @identifier.type 2 | (field_identifier) @identifier.field 3 | (package_identifier) @identifier 4 | (identifier) @identifier 5 | -------------------------------------------------------------------------------- /anycode-go/queries/locals.scm: -------------------------------------------------------------------------------- 1 | (method_declaration) @scope 2 | (function_declaration) @scope 3 | (expression_switch_statement) @scope 4 | (for_statement) @scope 5 | (block) @scope 6 | (type_switch_statement) @scope 7 | (composite_literal body: (literal_value) @scope) 8 | 9 | (const_spec name: (identifier) @local) 10 | (var_declaration (var_spec (identifier) @local)) 11 | (parameter_declaration (identifier) @local) 12 | (short_var_declaration left: (expression_list (identifier) @local)) 13 | (range_clause left: (expression_list (identifier) @local)) 14 | (type_switch_statement (expression_list (identifier) @local)) 15 | (function_declaration name: (identifier) @local.escape) 16 | (method_declaration name: (field_identifier) @local.escape) 17 | 18 | (identifier) @usage 19 | -------------------------------------------------------------------------------- /anycode-go/queries/outline.scm: -------------------------------------------------------------------------------- 1 | 2 | (field_declaration (field_identifier) @field @field.name) 3 | 4 | (var_spec 5 | name: (identifier) @method.name 6 | ) @method 7 | 8 | (type_alias 9 | name: (type_identifier) @string.name 10 | ) @string 11 | 12 | (function_declaration 13 | name: (identifier) @function.name 14 | ) @function 15 | 16 | (method_declaration 17 | name: (field_identifier) @method.name 18 | ) @method 19 | 20 | ;; variables defined in the package 21 | (source_file 22 | (var_declaration 23 | (var_spec 24 | (identifier) @variable.name 25 | ) @variable 26 | ) 27 | ) 28 | 29 | ;; lots of type_spec, must be mutually exclusive 30 | (type_spec 31 | name: (type_identifier) @interface.name 32 | type: (interface_type) 33 | ) @interface 34 | 35 | (type_spec 36 | name: (type_identifier) @function.name 37 | type: (function_type) 38 | ) @function 39 | 40 | (type_spec 41 | name: (type_identifier) @struct.name 42 | type: (struct_type) 43 | ) @struct 44 | 45 | (type_spec 46 | name: (type_identifier) @struct.name 47 | type: (map_type) 48 | ) @struct 49 | 50 | (type_spec 51 | name: (type_identifier) @struct.name 52 | type: (pointer_type) 53 | ) @struct 54 | 55 | (type_spec 56 | name: (type_identifier) @event.name 57 | type: (channel_type) 58 | ) @event 59 | 60 | (type_spec 61 | name: (type_identifier) @class.name 62 | type: (type_identifier) 63 | ) @class 64 | -------------------------------------------------------------------------------- /anycode-go/queries/references.scm: -------------------------------------------------------------------------------- 1 | (field_identifier) @ref.field 2 | (type_identifier) @ref.type 3 | (call_expression 4 | (identifier) @ref.call) 5 | -------------------------------------------------------------------------------- /anycode-java/.vscodeignore: -------------------------------------------------------------------------------- 1 | azure-pipelines.yml 2 | -------------------------------------------------------------------------------- /anycode-java/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE 22 | -------------------------------------------------------------------------------- /anycode-java/azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | name: $(Date:yyyyMMdd)$(Rev:.r) 2 | 3 | trigger: 4 | branches: 5 | include: 6 | - main 7 | paths: 8 | include: 9 | - anycode-java 10 | pr: none 11 | 12 | resources: 13 | repositories: 14 | - repository: templates 15 | type: github 16 | name: microsoft/vscode-engineering 17 | ref: main 18 | endpoint: Monaco 19 | 20 | parameters: 21 | - name: publishExtension 22 | displayName: 🚀 Publish Extension 23 | type: boolean 24 | default: false 25 | 26 | extends: 27 | template: azure-pipelines/extension/stable.yml@templates 28 | parameters: 29 | buildSteps: 30 | - script: cd anycode-java && npm install 31 | displayName: Install dependencies 32 | 33 | - script: cd anycode && npm install 34 | displayName: Install dependencies (anycode) 35 | 36 | - script: cd anycode-java && npm run test 37 | displayName: Run Test Fixtures 38 | 39 | ghCreateTag: true 40 | ghTagPrefix: anycode-java.v 41 | 42 | publishExtension: ${{ parameters.publishExtension }} 43 | 44 | tsa: 45 | config: 46 | areaPath: 'Visual Studio Code Language Extensions' 47 | serviceTreeID: 'c4cd3983-4977-4bcd-931f-a9822d2e950c' 48 | enabled: true 49 | 50 | cgSourceScanPath: $(Build.SourcesDirectory)/anycode-java 51 | workingDirectory: $(Build.SourcesDirectory)/anycode-java 52 | -------------------------------------------------------------------------------- /anycode-java/fixtures/highlights.java: -------------------------------------------------------------------------------- 1 | // ### ctor-argument 1 2 | class Point { 3 | int x, y; 4 | Point(int x, int y) { 5 | // ^ 6 | this.x = x; 7 | // ^ 8 | this.y = y; 9 | } 10 | } 11 | // ### ctor-argument 2 12 | class Point { 13 | int x, y; 14 | Point(int x, int y) { 15 | // ^ 16 | this.x = x; 17 | this.y = y; 18 | // ^ 19 | } 20 | } 21 | // ### method args 22 | class C { 23 | void C(int C) { 24 | // ^ 25 | print(C); 26 | // ^ 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /anycode-java/fixtures/outline.java: -------------------------------------------------------------------------------- 1 | // ### module dotted-name 2 | module com.foo { } 3 | // ^ ^ 4 | // ### class, inline props, ctor 5 | class Point { 6 | // ^ 7 | int x, y; 8 | // ^ 9 | // ^ 10 | Point(int x, int y) { 11 | //^ 12 | this.x = x; 13 | this.y = y; 14 | } 15 | 16 | Point() { 17 | //^ 18 | this(0, 0); 19 | } 20 | } 21 | // ### class, static method 22 | public class Foo { 23 | // ^ 24 | public static void main(String args[]) {} 25 | // ^ 26 | } 27 | // ### interface, method 28 | interface I { 29 | // ^ 30 | String foo(); 31 | // ^ 32 | } 33 | -------------------------------------------------------------------------------- /anycode-java/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "anycode-java", 3 | "version": "0.0.8", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "anycode-java", 9 | "version": "0.0.8", 10 | "hasInstallScript": true, 11 | "license": "MIT", 12 | "devDependencies": { 13 | "tree-sitter-cli": "^0.20.8", 14 | "tree-sitter-java": "^0.23.5" 15 | }, 16 | "engines": { 17 | "vscode": "^1.67.0" 18 | } 19 | }, 20 | "node_modules/node-addon-api": { 21 | "version": "8.3.1", 22 | "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.3.1.tgz", 23 | "integrity": "sha512-lytcDEdxKjGJPTLEfW4mYMigRezMlyJY8W4wxJK8zE533Jlb8L8dRuObJFWg2P+AuOIxoCgKF+2Oq4d4Zd0OUA==", 24 | "dev": true, 25 | "engines": { 26 | "node": "^18 || ^20 || >= 21" 27 | } 28 | }, 29 | "node_modules/node-gyp-build": { 30 | "version": "4.8.4", 31 | "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", 32 | "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", 33 | "dev": true, 34 | "bin": { 35 | "node-gyp-build": "bin.js", 36 | "node-gyp-build-optional": "optional.js", 37 | "node-gyp-build-test": "build-test.js" 38 | } 39 | }, 40 | "node_modules/tree-sitter-cli": { 41 | "version": "0.20.8", 42 | "resolved": "https://registry.npmjs.org/tree-sitter-cli/-/tree-sitter-cli-0.20.8.tgz", 43 | "integrity": "sha512-XjTcS3wdTy/2cc/ptMLc/WRyOLECRYcMTrSWyhZnj1oGSOWbHLTklgsgRICU3cPfb0vy+oZCC33M43u6R1HSCA==", 44 | "dev": true, 45 | "hasInstallScript": true, 46 | "bin": { 47 | "tree-sitter": "cli.js" 48 | } 49 | }, 50 | "node_modules/tree-sitter-java": { 51 | "version": "0.23.5", 52 | "resolved": "https://registry.npmjs.org/tree-sitter-java/-/tree-sitter-java-0.23.5.tgz", 53 | "integrity": "sha512-Yju7oQ0Xx7GcUT01mUglPP+bYfvqjNCGdxqigTnew9nLGoII42PNVP3bHrYeMxswiCRM0yubWmN5qk+zsg0zMA==", 54 | "dev": true, 55 | "hasInstallScript": true, 56 | "dependencies": { 57 | "node-addon-api": "^8.2.2", 58 | "node-gyp-build": "^4.8.2" 59 | }, 60 | "peerDependencies": { 61 | "tree-sitter": "^0.21.1" 62 | }, 63 | "peerDependenciesMeta": { 64 | "tree-sitter": { 65 | "optional": true 66 | } 67 | } 68 | } 69 | }, 70 | "dependencies": { 71 | "node-addon-api": { 72 | "version": "8.3.1", 73 | "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.3.1.tgz", 74 | "integrity": "sha512-lytcDEdxKjGJPTLEfW4mYMigRezMlyJY8W4wxJK8zE533Jlb8L8dRuObJFWg2P+AuOIxoCgKF+2Oq4d4Zd0OUA==", 75 | "dev": true 76 | }, 77 | "node-gyp-build": { 78 | "version": "4.8.4", 79 | "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", 80 | "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", 81 | "dev": true 82 | }, 83 | "tree-sitter-cli": { 84 | "version": "0.20.8", 85 | "resolved": "https://registry.npmjs.org/tree-sitter-cli/-/tree-sitter-cli-0.20.8.tgz", 86 | "integrity": "sha512-XjTcS3wdTy/2cc/ptMLc/WRyOLECRYcMTrSWyhZnj1oGSOWbHLTklgsgRICU3cPfb0vy+oZCC33M43u6R1HSCA==", 87 | "dev": true 88 | }, 89 | "tree-sitter-java": { 90 | "version": "0.23.5", 91 | "resolved": "https://registry.npmjs.org/tree-sitter-java/-/tree-sitter-java-0.23.5.tgz", 92 | "integrity": "sha512-Yju7oQ0Xx7GcUT01mUglPP+bYfvqjNCGdxqigTnew9nLGoII42PNVP3bHrYeMxswiCRM0yubWmN5qk+zsg0zMA==", 93 | "dev": true, 94 | "requires": { 95 | "node-addon-api": "^8.2.2", 96 | "node-gyp-build": "^4.8.2" 97 | } 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /anycode-java/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "anycode-java", 3 | "publisher": "ms-vscode", 4 | "displayName": "anycode-java", 5 | "description": "Java for Anycode", 6 | "license": "MIT", 7 | "version": "0.0.8", 8 | "preview": true, 9 | "repository": { 10 | "url": "https://github.com/microsoft/vscode-anycode" 11 | }, 12 | "engines": { 13 | "vscode": "^1.67.0" 14 | }, 15 | "categories": [ 16 | "Programming Languages" 17 | ], 18 | "contributes": { 19 | "anycodeLanguages": { 20 | "grammarPath": "./tree-sitter-java.wasm", 21 | "languageId": "java", 22 | "extensions": [ 23 | "java" 24 | ], 25 | "queryPaths": { 26 | "comments": "./queries/comments.scm", 27 | "folding": "./queries/folding.scm", 28 | "identifiers": "./queries/identifiers.scm", 29 | "locals": "./queries/locals.scm", 30 | "outline": "./queries/outline.scm", 31 | "references": "./queries/references.scm" 32 | }, 33 | "suppressedBy": [ 34 | "redhat.java" 35 | ] 36 | } 37 | }, 38 | "scripts": { 39 | "postinstall": "npx tree-sitter build-wasm node_modules/tree-sitter-java", 40 | "deploy": "npx vsce publish", 41 | "test": "node ../anycode/server/src/common/test-fixture/test.js --outline ./fixtures/outline.java --highlights ./fixtures/highlights.java" 42 | }, 43 | "devDependencies": { 44 | "tree-sitter-cli": "^0.20.8", 45 | "tree-sitter-java": "^0.23.5" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /anycode-java/queries/comments.scm: -------------------------------------------------------------------------------- 1 | [ 2 | (line_comment) 3 | (block_comment) 4 | ] @comment 5 | -------------------------------------------------------------------------------- /anycode-java/queries/folding.scm: -------------------------------------------------------------------------------- 1 | [(line_comment) (block_comment)] @comment 2 | [(class_body) (interface_body) (enum_body)] @scope 3 | (for_statement) @scope 4 | (if_statement consequence: (_) @scope) 5 | (if_statement alternative: (_) @scope) 6 | (while_statement body: (_) @scope) 7 | (try_statement (block) @scope) 8 | (catch_clause) @scope 9 | (block) @scope 10 | -------------------------------------------------------------------------------- /anycode-java/queries/identifiers.scm: -------------------------------------------------------------------------------- 1 | (type_identifier) @identifier 2 | (identifier) @identifier 3 | -------------------------------------------------------------------------------- /anycode-java/queries/locals.scm: -------------------------------------------------------------------------------- 1 | 2 | (method_declaration) @scope 3 | (constructor_declaration) @scope 4 | [(class_body) (interface_body) (enum_body)] @scope 5 | (for_statement) @scope 6 | (if_statement consequence: (_) @scope) 7 | (if_statement alternative: (_) @scope) 8 | (while_statement body: (_) @scope) 9 | (try_statement (block) @scope) 10 | (catch_clause) @scope 11 | (block) @scope 12 | 13 | (formal_parameter name: (identifier) @local) 14 | (local_variable_declaration declarator: (variable_declarator name: (identifier) @local)) 15 | (catch_formal_parameter name: (identifier) @local) 16 | (method_declaration name: (identifier) @local.escape) 17 | (constructor_declaration name: (identifier) @local.escape) 18 | 19 | (field_access field: (identifier) @usage.void) 20 | (identifier) @usage 21 | -------------------------------------------------------------------------------- /anycode-java/queries/outline.scm: -------------------------------------------------------------------------------- 1 | 2 | (class_declaration 3 | name: (identifier) @class.name 4 | ) @class 5 | 6 | (variable_declarator 7 | name: (identifier) @class.name 8 | value: (object_creation_expression 9 | . 10 | (_)* 11 | (class_body) 12 | ) 13 | ) @class 14 | 15 | (interface_declaration 16 | name: (identifier) @interface.name 17 | ) @interface 18 | 19 | (enum_declaration 20 | name: (identifier) @enum.name 21 | ) @enum 22 | 23 | (enum_constant 24 | name: (identifier) @enumMember.name 25 | ) @enumMember 26 | 27 | (constructor_declaration 28 | name: (identifier) @constructor.name 29 | ) @constructor 30 | 31 | (method_declaration 32 | name: (identifier) @method.name 33 | ) @method 34 | 35 | (field_declaration 36 | declarator: ((variable_declarator 37 | name: (identifier) @field.name) 38 | ) @field 39 | ) 40 | 41 | (module_declaration 42 | [ 43 | (scoped_identifier) @module.name 44 | (identifier) @module.name 45 | ] 46 | ) @module 47 | -------------------------------------------------------------------------------- /anycode-java/queries/references.scm: -------------------------------------------------------------------------------- 1 | (method_invocation 2 | name: (identifier) @ref.method) 3 | (type_list 4 | (type_identifier) @ref.interface) 5 | (superclass 6 | (type_identifier) @ref.class) 7 | (object_creation_expression 8 | type: (type_identifier) @ref.class) 9 | (type_identifier) @ref.class.interface.enum 10 | (field_access 11 | field: (identifier) @ref.field) 12 | -------------------------------------------------------------------------------- /anycode-kotlin/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE 22 | -------------------------------------------------------------------------------- /anycode-kotlin/azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | name: $(Date:yyyyMMdd)$(Rev:.r) 2 | 3 | trigger: 4 | branches: 5 | include: 6 | - main 7 | paths: 8 | include: 9 | - anycode-kotlin 10 | pr: none 11 | 12 | resources: 13 | repositories: 14 | - repository: templates 15 | type: github 16 | name: microsoft/vscode-engineering 17 | ref: main 18 | endpoint: Monaco 19 | 20 | parameters: 21 | - name: publishExtension 22 | displayName: 🚀 Publish Extension 23 | type: boolean 24 | default: false 25 | 26 | extends: 27 | template: azure-pipelines/extension/stable.yml@templates 28 | parameters: 29 | buildSteps: 30 | - script: cd anycode-kotlin && npm install 31 | displayName: Install dependencies 32 | 33 | - script: cd anycode && npm install 34 | displayName: Install dependencies (anycode) 35 | 36 | - script: cd anycode-kotlin && npm run test 37 | displayName: Run Test Fixtures 38 | 39 | ghCreateTag: true 40 | ghTagPrefix: anycode-kotlin.v 41 | 42 | publishExtension: ${{ parameters.publishExtension }} 43 | 44 | tsa: 45 | config: 46 | areaPath: 'Visual Studio Code Language Extensions' 47 | serviceTreeID: 'c4cd3983-4977-4bcd-931f-a9822d2e950c' 48 | enabled: true 49 | 50 | cgSourceScanPath: $(Build.SourcesDirectory)/anycode-kotlin 51 | workingDirectory: $(Build.SourcesDirectory)/anycode-kotlin 52 | -------------------------------------------------------------------------------- /anycode-kotlin/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "anycode-kotlin", 3 | "version": "0.0.8", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "anycode-kotlin", 9 | "version": "0.0.8", 10 | "hasInstallScript": true, 11 | "license": "MIT", 12 | "devDependencies": { 13 | "@swimm/tree-sitter-kotlin": "^0.3.2", 14 | "tree-sitter-cli": "^0.20.8" 15 | }, 16 | "engines": { 17 | "vscode": "^1.67.0" 18 | } 19 | }, 20 | "node_modules/@swimm/tree-sitter-kotlin": { 21 | "version": "0.3.2", 22 | "resolved": "https://registry.npmjs.org/@swimm/tree-sitter-kotlin/-/tree-sitter-kotlin-0.3.2.tgz", 23 | "integrity": "sha512-Y4/A0Q1GZOOpKGooP97Eon53Fznlon3ceh3ba020KzrtVMKwemr9fN+fYW+mykqziQcwASS3tGCRTLm4Ut3hyA==", 24 | "dev": true, 25 | "hasInstallScript": true, 26 | "dependencies": { 27 | "nan": "^2.17.0" 28 | } 29 | }, 30 | "node_modules/nan": { 31 | "version": "2.19.0", 32 | "resolved": "https://registry.npmjs.org/nan/-/nan-2.19.0.tgz", 33 | "integrity": "sha512-nO1xXxfh/RWNxfd/XPfbIfFk5vgLsAxUR9y5O0cHMJu/AW9U95JLXqthYHjEp+8gQ5p96K9jUp8nbVOxCdRbtw==", 34 | "dev": true 35 | }, 36 | "node_modules/tree-sitter-cli": { 37 | "version": "0.20.8", 38 | "resolved": "https://registry.npmjs.org/tree-sitter-cli/-/tree-sitter-cli-0.20.8.tgz", 39 | "integrity": "sha512-XjTcS3wdTy/2cc/ptMLc/WRyOLECRYcMTrSWyhZnj1oGSOWbHLTklgsgRICU3cPfb0vy+oZCC33M43u6R1HSCA==", 40 | "dev": true, 41 | "hasInstallScript": true, 42 | "bin": { 43 | "tree-sitter": "cli.js" 44 | } 45 | } 46 | }, 47 | "dependencies": { 48 | "@swimm/tree-sitter-kotlin": { 49 | "version": "0.3.2", 50 | "resolved": "https://registry.npmjs.org/@swimm/tree-sitter-kotlin/-/tree-sitter-kotlin-0.3.2.tgz", 51 | "integrity": "sha512-Y4/A0Q1GZOOpKGooP97Eon53Fznlon3ceh3ba020KzrtVMKwemr9fN+fYW+mykqziQcwASS3tGCRTLm4Ut3hyA==", 52 | "dev": true, 53 | "requires": { 54 | "nan": "^2.17.0" 55 | } 56 | }, 57 | "nan": { 58 | "version": "2.19.0", 59 | "resolved": "https://registry.npmjs.org/nan/-/nan-2.19.0.tgz", 60 | "integrity": "sha512-nO1xXxfh/RWNxfd/XPfbIfFk5vgLsAxUR9y5O0cHMJu/AW9U95JLXqthYHjEp+8gQ5p96K9jUp8nbVOxCdRbtw==", 61 | "dev": true 62 | }, 63 | "tree-sitter-cli": { 64 | "version": "0.20.8", 65 | "resolved": "https://registry.npmjs.org/tree-sitter-cli/-/tree-sitter-cli-0.20.8.tgz", 66 | "integrity": "sha512-XjTcS3wdTy/2cc/ptMLc/WRyOLECRYcMTrSWyhZnj1oGSOWbHLTklgsgRICU3cPfb0vy+oZCC33M43u6R1HSCA==", 67 | "dev": true 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /anycode-kotlin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "anycode-kotlin", 3 | "publisher": "ms-vscode", 4 | "displayName": "anycode-kotlin", 5 | "description": "Kotlin for Anycode", 6 | "license": "MIT", 7 | "version": "0.0.8", 8 | "preview": true, 9 | "repository": { 10 | "url": "https://github.com/microsoft/vscode-anycode" 11 | }, 12 | "engines": { 13 | "vscode": "^1.67.0" 14 | }, 15 | "categories": [ 16 | "Programming Languages" 17 | ], 18 | "contributes": { 19 | "languages": [ 20 | { 21 | "id": "kotlin", 22 | "extensions": [ 23 | "kt" 24 | ], 25 | "aliases": [ 26 | "kotlin" 27 | ] 28 | } 29 | ], 30 | "anycodeLanguages": { 31 | "grammarPath": "./tree-sitter-kotlin.wasm", 32 | "languageId": "kotlin", 33 | "extensions": [ 34 | "kt" 35 | ], 36 | "queryPaths": { 37 | "comments": "./queries/comments.scm", 38 | "folding": "./queries/folding.scm", 39 | "identifiers": "./queries/identifiers.scm", 40 | "references": "./queries/references.scm" 41 | } 42 | } 43 | }, 44 | "scripts": { 45 | "postinstall": "npx tree-sitter build-wasm node_modules/@swimm/tree-sitter-kotlin", 46 | "deploy": "npx vsce publish", 47 | "test": "node ../anycode/server/src/common/test-fixture/test.js" 48 | }, 49 | "devDependencies": { 50 | "tree-sitter-cli": "^0.20.8", 51 | "@swimm/tree-sitter-kotlin": "^0.3.2" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /anycode-kotlin/queries/comments.scm: -------------------------------------------------------------------------------- 1 | (line_comment) @comment 2 | (multiline_comment) @comment 3 | -------------------------------------------------------------------------------- /anycode-kotlin/queries/folding.scm: -------------------------------------------------------------------------------- 1 | (multiline_comment) @comment 2 | [(class_body) (function_body) (enum_class_body) (control_structure_body)] @scope 3 | (if_expression (control_structure_body) @scope) 4 | (while_statement) @scope 5 | (for_statement) @scope 6 | (do_while_statement) @scope 7 | (try_expression (_) @scope) 8 | (catch_block) @scope 9 | (finally_block) @scope 10 | (when_entry (control_structure_body) @scope) 11 | -------------------------------------------------------------------------------- /anycode-kotlin/queries/identifiers.scm: -------------------------------------------------------------------------------- 1 | (identifier) @identifier 2 | (type_identifier) @identifier 3 | (simple_identifier) @identifier 4 | (interpolated_identifier) @identifier -------------------------------------------------------------------------------- /anycode-kotlin/queries/references.scm: -------------------------------------------------------------------------------- 1 | (call_expression (simple_identifier) @ref.method) 2 | 3 | (delegation_specifier (user_type (type_identifier) @ref.interface)) 4 | (delegation_specifier (constructor_invocation (user_type (type_identifier) @ref.class))) 5 | 6 | (navigation_expression (simple_identifier) @ref) 7 | 8 | (navigation_suffix (simple_identifier)@ref) 9 | 10 | (assignment (directly_assignable_expression) (simple_identifier) @ref) 11 | 12 | (call_suffix (value_arguments (value_argument (simple_identifier) @ref))) 13 | -------------------------------------------------------------------------------- /anycode-php/.vscodeignore: -------------------------------------------------------------------------------- 1 | azure-pipelines.yml 2 | -------------------------------------------------------------------------------- /anycode-php/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE 22 | -------------------------------------------------------------------------------- /anycode-php/azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | name: $(Date:yyyyMMdd)$(Rev:.r) 2 | 3 | trigger: 4 | branches: 5 | include: 6 | - main 7 | paths: 8 | include: 9 | - anycode-php 10 | pr: none 11 | 12 | resources: 13 | repositories: 14 | - repository: templates 15 | type: github 16 | name: microsoft/vscode-engineering 17 | ref: main 18 | endpoint: Monaco 19 | 20 | parameters: 21 | - name: publishExtension 22 | displayName: 🚀 Publish Extension 23 | type: boolean 24 | default: false 25 | 26 | extends: 27 | template: azure-pipelines/extension/stable.yml@templates 28 | parameters: 29 | buildSteps: 30 | - script: cd anycode-php && npm install 31 | displayName: Install dependencies 32 | 33 | - script: cd anycode && npm install 34 | displayName: Install dependencies (anycode) 35 | 36 | - script: cd anycode-php && npm run test 37 | displayName: Run Test Fixtures 38 | 39 | ghCreateTag: true 40 | ghTagPrefix: anycode-php.v 41 | 42 | publishExtension: ${{ parameters.publishExtension }} 43 | 44 | tsa: 45 | config: 46 | areaPath: 'Visual Studio Code Language Extensions' 47 | serviceTreeID: 'c4cd3983-4977-4bcd-931f-a9822d2e950c' 48 | enabled: true 49 | 50 | cgSourceScanPath: $(Build.SourcesDirectory)/anycode-php 51 | workingDirectory: $(Build.SourcesDirectory)/anycode-php 52 | -------------------------------------------------------------------------------- /anycode-php/fixtures/highlights.php: -------------------------------------------------------------------------------- 1 | 2 | x = $x; 10 | $this->y = $y; 11 | // ^ 12 | } 13 | } 14 | ?> 15 | 16 | 22 | 23 | 34 | -------------------------------------------------------------------------------- /anycode-php/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "anycode-php", 3 | "version": "0.0.8", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "anycode-php", 9 | "version": "0.0.8", 10 | "hasInstallScript": true, 11 | "license": "MIT", 12 | "devDependencies": { 13 | "@playwright/test": "^1.14.1", 14 | "tree-sitter-cli": "^0.20.8", 15 | "tree-sitter-php": "^0.20.0" 16 | }, 17 | "engines": { 18 | "vscode": "^1.67.0" 19 | } 20 | }, 21 | "node_modules/@playwright/test": { 22 | "version": "1.23.2", 23 | "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.23.2.tgz", 24 | "integrity": "sha512-umaEAIwQGfbezixg3raSOraqbQGSqZP988sOaMdpA2wj3Dr6ykOscrMukyK3U6edxhpS0N8kguAFZoHwCEfTig==", 25 | "dev": true, 26 | "dependencies": { 27 | "@types/node": "*", 28 | "playwright-core": "1.23.2" 29 | }, 30 | "bin": { 31 | "playwright": "cli.js" 32 | }, 33 | "engines": { 34 | "node": ">=14" 35 | } 36 | }, 37 | "node_modules/@types/node": { 38 | "version": "18.0.3", 39 | "resolved": "https://registry.npmjs.org/@types/node/-/node-18.0.3.tgz", 40 | "integrity": "sha512-HzNRZtp4eepNitP+BD6k2L6DROIDG4Q0fm4x+dwfsr6LGmROENnok75VGw40628xf+iR24WeMFcHuuBDUAzzsQ==", 41 | "dev": true 42 | }, 43 | "node_modules/nan": { 44 | "version": "2.19.0", 45 | "resolved": "https://registry.npmjs.org/nan/-/nan-2.19.0.tgz", 46 | "integrity": "sha512-nO1xXxfh/RWNxfd/XPfbIfFk5vgLsAxUR9y5O0cHMJu/AW9U95JLXqthYHjEp+8gQ5p96K9jUp8nbVOxCdRbtw==", 47 | "dev": true 48 | }, 49 | "node_modules/playwright-core": { 50 | "version": "1.23.2", 51 | "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.23.2.tgz", 52 | "integrity": "sha512-UGbutIr0nBALDHWW/HcXfyK6ZdmefC99Moo4qyTr89VNIkYZuDrW8Sw554FyFUamcFSdKOgDPk6ECSkofGIZjQ==", 53 | "dev": true, 54 | "bin": { 55 | "playwright": "cli.js" 56 | }, 57 | "engines": { 58 | "node": ">=14" 59 | } 60 | }, 61 | "node_modules/tree-sitter-cli": { 62 | "version": "0.20.8", 63 | "resolved": "https://registry.npmjs.org/tree-sitter-cli/-/tree-sitter-cli-0.20.8.tgz", 64 | "integrity": "sha512-XjTcS3wdTy/2cc/ptMLc/WRyOLECRYcMTrSWyhZnj1oGSOWbHLTklgsgRICU3cPfb0vy+oZCC33M43u6R1HSCA==", 65 | "dev": true, 66 | "hasInstallScript": true, 67 | "bin": { 68 | "tree-sitter": "cli.js" 69 | } 70 | }, 71 | "node_modules/tree-sitter-php": { 72 | "version": "0.20.0", 73 | "resolved": "https://registry.npmjs.org/tree-sitter-php/-/tree-sitter-php-0.20.0.tgz", 74 | "integrity": "sha512-di7d1jjAu05Hj9AufXlUQzTHGaThemU2HV9MjE17HnbW8TfuwNzH0Q0BQuJLrIJipjK9bhqhNe1fS9wtkyUkYg==", 75 | "dev": true, 76 | "hasInstallScript": true, 77 | "dependencies": { 78 | "nan": "^2.18.0" 79 | } 80 | } 81 | }, 82 | "dependencies": { 83 | "@playwright/test": { 84 | "version": "1.23.2", 85 | "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.23.2.tgz", 86 | "integrity": "sha512-umaEAIwQGfbezixg3raSOraqbQGSqZP988sOaMdpA2wj3Dr6ykOscrMukyK3U6edxhpS0N8kguAFZoHwCEfTig==", 87 | "dev": true, 88 | "requires": { 89 | "@types/node": "*", 90 | "playwright-core": "1.23.2" 91 | } 92 | }, 93 | "@types/node": { 94 | "version": "18.0.3", 95 | "resolved": "https://registry.npmjs.org/@types/node/-/node-18.0.3.tgz", 96 | "integrity": "sha512-HzNRZtp4eepNitP+BD6k2L6DROIDG4Q0fm4x+dwfsr6LGmROENnok75VGw40628xf+iR24WeMFcHuuBDUAzzsQ==", 97 | "dev": true 98 | }, 99 | "nan": { 100 | "version": "2.19.0", 101 | "resolved": "https://registry.npmjs.org/nan/-/nan-2.19.0.tgz", 102 | "integrity": "sha512-nO1xXxfh/RWNxfd/XPfbIfFk5vgLsAxUR9y5O0cHMJu/AW9U95JLXqthYHjEp+8gQ5p96K9jUp8nbVOxCdRbtw==", 103 | "dev": true 104 | }, 105 | "playwright-core": { 106 | "version": "1.23.2", 107 | "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.23.2.tgz", 108 | "integrity": "sha512-UGbutIr0nBALDHWW/HcXfyK6ZdmefC99Moo4qyTr89VNIkYZuDrW8Sw554FyFUamcFSdKOgDPk6ECSkofGIZjQ==", 109 | "dev": true 110 | }, 111 | "tree-sitter-cli": { 112 | "version": "0.20.8", 113 | "resolved": "https://registry.npmjs.org/tree-sitter-cli/-/tree-sitter-cli-0.20.8.tgz", 114 | "integrity": "sha512-XjTcS3wdTy/2cc/ptMLc/WRyOLECRYcMTrSWyhZnj1oGSOWbHLTklgsgRICU3cPfb0vy+oZCC33M43u6R1HSCA==", 115 | "dev": true 116 | }, 117 | "tree-sitter-php": { 118 | "version": "0.20.0", 119 | "resolved": "https://registry.npmjs.org/tree-sitter-php/-/tree-sitter-php-0.20.0.tgz", 120 | "integrity": "sha512-di7d1jjAu05Hj9AufXlUQzTHGaThemU2HV9MjE17HnbW8TfuwNzH0Q0BQuJLrIJipjK9bhqhNe1fS9wtkyUkYg==", 121 | "dev": true, 122 | "requires": { 123 | "nan": "^2.18.0" 124 | } 125 | } 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /anycode-php/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "anycode-php", 3 | "publisher": "ms-vscode", 4 | "displayName": "anycode-php", 5 | "description": "PHP for Anycode", 6 | "license": "MIT", 7 | "version": "0.0.8", 8 | "preview": true, 9 | "repository": { 10 | "url": "https://github.com/microsoft/vscode-anycode" 11 | }, 12 | "engines": { 13 | "vscode": "^1.67.0" 14 | }, 15 | "categories": [ 16 | "Programming Languages" 17 | ], 18 | "contributes": { 19 | "anycodeLanguages": { 20 | "grammarPath": "./tree-sitter-php.wasm", 21 | "languageId": "php", 22 | "extensions": [ 23 | "php", 24 | "php4", 25 | "php5", 26 | "phtml", 27 | "ctp" 28 | ], 29 | "queryPaths": { 30 | "comments": "./queries/comments.scm", 31 | "identifiers": "./queries/identifiers.scm", 32 | "locals": "./queries/locals.scm", 33 | "outline": "./queries/outline.scm", 34 | "references": "./queries/references.scm" 35 | }, 36 | "suppressedBy": [ 37 | "bmewburn.vscode-intelephense-client" 38 | ] 39 | } 40 | }, 41 | "scripts": { 42 | "postinstall": "npx tree-sitter build-wasm node_modules/tree-sitter-php", 43 | "deploy": "npx vsce publish", 44 | "test": "node ../anycode/server/src/common/test-fixture/test.js --highlights ./fixtures/highlights.php" 45 | }, 46 | "devDependencies": { 47 | "@playwright/test": "^1.14.1", 48 | "tree-sitter-cli": "^0.20.8", 49 | "tree-sitter-php": "^0.20.0" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /anycode-php/queries/comments.scm: -------------------------------------------------------------------------------- 1 | (comment) @comment 2 | -------------------------------------------------------------------------------- /anycode-php/queries/identifiers.scm: -------------------------------------------------------------------------------- 1 | (name) @identifier 2 | -------------------------------------------------------------------------------- /anycode-php/queries/locals.scm: -------------------------------------------------------------------------------- 1 | (method_declaration) @scope 2 | (function_definition) @scope 3 | (compound_statement) @scope 4 | (declaration_list) @scope 5 | 6 | (function_definition 7 | name: (name) @local.escape) 8 | (method_declaration 9 | name: (name) @local.escape) 10 | (assignment_expression 11 | left: (variable_name) @local) 12 | (augmented_assignment_expression 13 | left: (variable_name) @local) 14 | (static_variable_declaration 15 | name: (variable_name) @local) 16 | (simple_parameter 17 | name: (variable_name) @local) 18 | 19 | (variable_name) @usage 20 | -------------------------------------------------------------------------------- /anycode-php/queries/outline.scm: -------------------------------------------------------------------------------- 1 | (class_declaration 2 | name: (name) @class.name 3 | ) @class 4 | 5 | (method_declaration 6 | name: (name) @method.name 7 | ) @method 8 | 9 | (property_element 10 | (variable_name) @property.name 11 | ) @property 12 | 13 | (function_definition 14 | name: (name) @function.name 15 | ) @function 16 | 17 | (trait_declaration 18 | name: (name) @property.name 19 | ) @property 20 | -------------------------------------------------------------------------------- /anycode-php/queries/references.scm: -------------------------------------------------------------------------------- 1 | (object_creation_expression [ 2 | (qualified_name (name) @ref) 3 | (variable_name (name) @ref)]) 4 | 5 | (function_call_expression function: [ 6 | (qualified_name (name) @ref) 7 | (variable_name (name)) @ref]) 8 | 9 | (member_access_expression name: (name) @ref) 10 | 11 | (scoped_call_expression 12 | name: (name) @ref) 13 | 14 | (member_call_expression 15 | name: (name) @ref) 16 | -------------------------------------------------------------------------------- /anycode-python/.vscodeignore: -------------------------------------------------------------------------------- 1 | azure-pipelines.yml 2 | -------------------------------------------------------------------------------- /anycode-python/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE 22 | -------------------------------------------------------------------------------- /anycode-python/azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | name: $(Date:yyyyMMdd)$(Rev:.r) 2 | 3 | trigger: 4 | branches: 5 | include: 6 | - main 7 | paths: 8 | include: 9 | - anycode-python 10 | pr: none 11 | 12 | resources: 13 | repositories: 14 | - repository: templates 15 | type: github 16 | name: microsoft/vscode-engineering 17 | ref: main 18 | endpoint: Monaco 19 | 20 | parameters: 21 | - name: publishExtension 22 | displayName: 🚀 Publish Extension 23 | type: boolean 24 | default: false 25 | 26 | extends: 27 | template: azure-pipelines/extension/stable.yml@templates 28 | parameters: 29 | buildSteps: 30 | - script: cd anycode-python && npm install 31 | displayName: Install dependencies 32 | 33 | - script: cd anycode && npm install 34 | displayName: Install dependencies (anycode) 35 | 36 | - script: cd anycode-python && npm run test 37 | displayName: Run Test Fixtures 38 | 39 | ghCreateTag: true 40 | ghTagPrefix: anycode-python.v 41 | 42 | publishExtension: ${{ parameters.publishExtension }} 43 | 44 | tsa: 45 | config: 46 | areaPath: 'Visual Studio Code Language Extensions' 47 | serviceTreeID: 'c4cd3983-4977-4bcd-931f-a9822d2e950c' 48 | enabled: true 49 | 50 | cgSourceScanPath: $(Build.SourcesDirectory)/anycode-python 51 | workingDirectory: $(Build.SourcesDirectory)/anycode-python 52 | -------------------------------------------------------------------------------- /anycode-python/fixtures/highlights.py: -------------------------------------------------------------------------------- 1 | # ### variable 2 | fooo = 123 3 | #^ 4 | bar = 2*fooo 5 | # ^ 6 | # ### function args 7 | def _sum(arr, brr): 8 | # ^ 9 | a = b = arr; 10 | # ^ 11 | return(arr) 12 | # ^ 13 | -------------------------------------------------------------------------------- /anycode-python/fixtures/outline.py: -------------------------------------------------------------------------------- 1 | # ### simple function 2 | def print_pattern(): 3 | # ^ 4 | size = 4 5 | for i in range(size): 6 | print("*" * size) 7 | # ### async function 8 | async def c(a: str): 9 | # ^ 10 | a 11 | # ### Class, ctor, method 12 | class Dog: 13 | # ^ 14 | def __init__(self, name, age): 15 | # ^ 16 | self.name = name # Public attribute 17 | self._age = age # Non-Public attribute 18 | def bark(self): 19 | # ^ 20 | print(f"woof-woof. I'm {self.name}") 21 | # ### variable 22 | def hello(): 23 | # ^ 24 | b = 123 25 | b * 11 26 | 27 | aaa = 123 28 | #^ 29 | aa = b = c = 999 30 | #^ 31 | -------------------------------------------------------------------------------- /anycode-python/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "anycode-python", 3 | "version": "0.0.7", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "anycode-python", 9 | "version": "0.0.7", 10 | "hasInstallScript": true, 11 | "license": "MIT", 12 | "devDependencies": { 13 | "@playwright/test": "^1.14.1", 14 | "tree-sitter-cli": "^0.20.8", 15 | "tree-sitter-python": "^0.20.4" 16 | }, 17 | "engines": { 18 | "vscode": "^1.67.0" 19 | } 20 | }, 21 | "node_modules/@playwright/test": { 22 | "version": "1.23.2", 23 | "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.23.2.tgz", 24 | "integrity": "sha512-umaEAIwQGfbezixg3raSOraqbQGSqZP988sOaMdpA2wj3Dr6ykOscrMukyK3U6edxhpS0N8kguAFZoHwCEfTig==", 25 | "dev": true, 26 | "dependencies": { 27 | "@types/node": "*", 28 | "playwright-core": "1.23.2" 29 | }, 30 | "bin": { 31 | "playwright": "cli.js" 32 | }, 33 | "engines": { 34 | "node": ">=14" 35 | } 36 | }, 37 | "node_modules/@types/node": { 38 | "version": "18.0.3", 39 | "resolved": "https://registry.npmjs.org/@types/node/-/node-18.0.3.tgz", 40 | "integrity": "sha512-HzNRZtp4eepNitP+BD6k2L6DROIDG4Q0fm4x+dwfsr6LGmROENnok75VGw40628xf+iR24WeMFcHuuBDUAzzsQ==", 41 | "dev": true 42 | }, 43 | "node_modules/nan": { 44 | "version": "2.19.0", 45 | "resolved": "https://registry.npmjs.org/nan/-/nan-2.19.0.tgz", 46 | "integrity": "sha512-nO1xXxfh/RWNxfd/XPfbIfFk5vgLsAxUR9y5O0cHMJu/AW9U95JLXqthYHjEp+8gQ5p96K9jUp8nbVOxCdRbtw==", 47 | "dev": true 48 | }, 49 | "node_modules/playwright-core": { 50 | "version": "1.23.2", 51 | "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.23.2.tgz", 52 | "integrity": "sha512-UGbutIr0nBALDHWW/HcXfyK6ZdmefC99Moo4qyTr89VNIkYZuDrW8Sw554FyFUamcFSdKOgDPk6ECSkofGIZjQ==", 53 | "dev": true, 54 | "bin": { 55 | "playwright": "cli.js" 56 | }, 57 | "engines": { 58 | "node": ">=14" 59 | } 60 | }, 61 | "node_modules/tree-sitter-cli": { 62 | "version": "0.20.8", 63 | "resolved": "https://registry.npmjs.org/tree-sitter-cli/-/tree-sitter-cli-0.20.8.tgz", 64 | "integrity": "sha512-XjTcS3wdTy/2cc/ptMLc/WRyOLECRYcMTrSWyhZnj1oGSOWbHLTklgsgRICU3cPfb0vy+oZCC33M43u6R1HSCA==", 65 | "dev": true, 66 | "hasInstallScript": true, 67 | "bin": { 68 | "tree-sitter": "cli.js" 69 | } 70 | }, 71 | "node_modules/tree-sitter-python": { 72 | "version": "0.20.4", 73 | "resolved": "https://registry.npmjs.org/tree-sitter-python/-/tree-sitter-python-0.20.4.tgz", 74 | "integrity": "sha512-F+94q/t9+4J5yaQnmfAqEf4OZFjuhuyniRtb9P2jPaBwHrbyJL44RKFALovZxhF0syLFKpTQ7ODywyiGeB1YMg==", 75 | "dev": true, 76 | "hasInstallScript": true, 77 | "dependencies": { 78 | "nan": "^2.17.0" 79 | } 80 | } 81 | }, 82 | "dependencies": { 83 | "@playwright/test": { 84 | "version": "1.23.2", 85 | "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.23.2.tgz", 86 | "integrity": "sha512-umaEAIwQGfbezixg3raSOraqbQGSqZP988sOaMdpA2wj3Dr6ykOscrMukyK3U6edxhpS0N8kguAFZoHwCEfTig==", 87 | "dev": true, 88 | "requires": { 89 | "@types/node": "*", 90 | "playwright-core": "1.23.2" 91 | } 92 | }, 93 | "@types/node": { 94 | "version": "18.0.3", 95 | "resolved": "https://registry.npmjs.org/@types/node/-/node-18.0.3.tgz", 96 | "integrity": "sha512-HzNRZtp4eepNitP+BD6k2L6DROIDG4Q0fm4x+dwfsr6LGmROENnok75VGw40628xf+iR24WeMFcHuuBDUAzzsQ==", 97 | "dev": true 98 | }, 99 | "nan": { 100 | "version": "2.19.0", 101 | "resolved": "https://registry.npmjs.org/nan/-/nan-2.19.0.tgz", 102 | "integrity": "sha512-nO1xXxfh/RWNxfd/XPfbIfFk5vgLsAxUR9y5O0cHMJu/AW9U95JLXqthYHjEp+8gQ5p96K9jUp8nbVOxCdRbtw==", 103 | "dev": true 104 | }, 105 | "playwright-core": { 106 | "version": "1.23.2", 107 | "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.23.2.tgz", 108 | "integrity": "sha512-UGbutIr0nBALDHWW/HcXfyK6ZdmefC99Moo4qyTr89VNIkYZuDrW8Sw554FyFUamcFSdKOgDPk6ECSkofGIZjQ==", 109 | "dev": true 110 | }, 111 | "tree-sitter-cli": { 112 | "version": "0.20.8", 113 | "resolved": "https://registry.npmjs.org/tree-sitter-cli/-/tree-sitter-cli-0.20.8.tgz", 114 | "integrity": "sha512-XjTcS3wdTy/2cc/ptMLc/WRyOLECRYcMTrSWyhZnj1oGSOWbHLTklgsgRICU3cPfb0vy+oZCC33M43u6R1HSCA==", 115 | "dev": true 116 | }, 117 | "tree-sitter-python": { 118 | "version": "0.20.4", 119 | "resolved": "https://registry.npmjs.org/tree-sitter-python/-/tree-sitter-python-0.20.4.tgz", 120 | "integrity": "sha512-F+94q/t9+4J5yaQnmfAqEf4OZFjuhuyniRtb9P2jPaBwHrbyJL44RKFALovZxhF0syLFKpTQ7ODywyiGeB1YMg==", 121 | "dev": true, 122 | "requires": { 123 | "nan": "^2.17.0" 124 | } 125 | } 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /anycode-python/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "anycode-python", 3 | "publisher": "ms-vscode", 4 | "displayName": "anycode-python", 5 | "description": "Python for Anycode", 6 | "license": "MIT", 7 | "version": "0.0.7", 8 | "preview": true, 9 | "repository": { 10 | "url": "https://github.com/microsoft/vscode-anycode" 11 | }, 12 | "engines": { 13 | "vscode": "^1.67.0" 14 | }, 15 | "categories": [ 16 | "Programming Languages" 17 | ], 18 | "contributes": { 19 | "anycodeLanguages": { 20 | "grammarPath": "./tree-sitter-python.wasm", 21 | "languageId": "python", 22 | "extensions": [ 23 | "py", 24 | "rpy", 25 | "pyw", 26 | "cpy", 27 | "gyp", 28 | "gypi", 29 | "pyi", 30 | "ipy" 31 | ], 32 | "queryPaths": { 33 | "comments": "./queries/comments.scm", 34 | "identifiers": "./queries/identifiers.scm", 35 | "locals": "./queries/locals.scm", 36 | "outline": "./queries/outline.scm", 37 | "references": "./queries/references.scm" 38 | }, 39 | "suppressedBy": [ 40 | "ms-python.python" 41 | ] 42 | } 43 | }, 44 | "scripts": { 45 | "postinstall": "npx tree-sitter build-wasm node_modules/tree-sitter-python", 46 | "deploy": "npx vsce publish", 47 | "test": "node ../anycode/server/src/common/test-fixture/test.js --outline ./fixtures/outline.ts --highlights ./fixtures/highlights.ts" 48 | }, 49 | "devDependencies": { 50 | "@playwright/test": "^1.14.1", 51 | "tree-sitter-cli": "^0.20.8", 52 | "tree-sitter-python": "^0.20.4" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /anycode-python/queries/comments.scm: -------------------------------------------------------------------------------- 1 | (comment) @comment 2 | -------------------------------------------------------------------------------- /anycode-python/queries/identifiers.scm: -------------------------------------------------------------------------------- 1 | (identifier) @identifier 2 | -------------------------------------------------------------------------------- /anycode-python/queries/locals.scm: -------------------------------------------------------------------------------- 1 | (class_definition) @scope 2 | (function_definition) @scope 3 | (for_statement) @scope 4 | 5 | (parameters (identifier) @local) 6 | (assignment left: (identifier) @local) 7 | (function_definition name: (identifier) @local.escape) 8 | (class_definition name: (identifier) @local.escape) 9 | (for_statement left: (identifier) @local) 10 | 11 | (identifier) @usage 12 | -------------------------------------------------------------------------------- /anycode-python/queries/outline.scm: -------------------------------------------------------------------------------- 1 | (class_definition 2 | name: (identifier) @class.name) @class 3 | 4 | (function_definition 5 | name: (identifier) @function.name) @function 6 | 7 | (module 8 | (expression_statement 9 | (assignment left: (identifier) @var))) 10 | -------------------------------------------------------------------------------- /anycode-python/queries/references.scm: -------------------------------------------------------------------------------- 1 | (call function: [ 2 | (identifier) @ref 3 | (attribute 4 | attribute: (identifier) @ref)]) 5 | -------------------------------------------------------------------------------- /anycode-rust/.vscodeignore: -------------------------------------------------------------------------------- 1 | azure-pipelines.yml 2 | -------------------------------------------------------------------------------- /anycode-rust/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE 22 | -------------------------------------------------------------------------------- /anycode-rust/azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | name: $(Date:yyyyMMdd)$(Rev:.r) 2 | 3 | trigger: 4 | branches: 5 | include: 6 | - main 7 | paths: 8 | include: 9 | - anycode-rust 10 | pr: none 11 | 12 | resources: 13 | repositories: 14 | - repository: templates 15 | type: github 16 | name: microsoft/vscode-engineering 17 | ref: main 18 | endpoint: Monaco 19 | 20 | parameters: 21 | - name: publishExtension 22 | displayName: 🚀 Publish Extension 23 | type: boolean 24 | default: false 25 | 26 | extends: 27 | template: azure-pipelines/extension/stable.yml@templates 28 | parameters: 29 | buildSteps: 30 | - script: cd anycode-rust && npm install 31 | displayName: Install dependencies 32 | 33 | - script: cd anycode && npm install 34 | displayName: Install dependencies (anycode) 35 | 36 | - script: cd anycode-rust && npm run test 37 | displayName: Run Test Fixtures 38 | 39 | ghCreateTag: true 40 | ghTagPrefix: anycode-rust.v 41 | 42 | publishExtension: ${{ parameters.publishExtension }} 43 | 44 | tsa: 45 | config: 46 | areaPath: 'Visual Studio Code Language Extensions' 47 | serviceTreeID: 'c4cd3983-4977-4bcd-931f-a9822d2e950c' 48 | enabled: true 49 | 50 | cgSourceScanPath: $(Build.SourcesDirectory)/anycode-rust 51 | workingDirectory: $(Build.SourcesDirectory)/anycode-rust 52 | -------------------------------------------------------------------------------- /anycode-rust/fixtures/highlights.rs: -------------------------------------------------------------------------------- 1 | // ### variable 2 | fn main() { 3 | let x = 5; 4 | // ^ 5 | println!("The value of x is: {}", x); 6 | // ^ 7 | x = 6; 8 | // ^ 9 | println!("The value of x is: {}", x); 10 | // ^ 11 | } 12 | // ### shadow variable 13 | fn main() { 14 | let x = 5; 15 | // ^ 16 | let x = x + 1; 17 | // ^ 18 | // ^ 19 | let x = x * 2; 20 | // ^ 21 | // ^ 22 | println!("The value of x is: {}", x); 23 | // ^ 24 | } 25 | // ### mutable variable 26 | let mut spaces = " "; 27 | // ^ 28 | spaces = spaces.len(); 29 | //^ 30 | // ^ 31 | // ### variable vs field 32 | let mut spaces = " "; 33 | // ^ 34 | spaces = spaces.spaces; 35 | //^ 36 | // ^ 37 | // ### const-def/usage 38 | const MAX_POINTS: u32 = 100_000; 39 | // ^ 40 | fn foo() { 41 | foo(MAX_POINTS) 42 | // ^ 43 | } 44 | // ### function-def/usage 45 | fn main() { 46 | println!("Hello, world!"); 47 | another_function(); 48 | // ^ 49 | } 50 | fn another_function() { 51 | // ^ 52 | println!("Another function."); 53 | } 54 | // ### mod defines scope 55 | mod foo { 56 | fn foobar(_x: i32) -> () {} 57 | // ^ 58 | } 59 | fn main() { 60 | foobar(23) 61 | } 62 | // ### args 63 | fn another_function(x: i32) { 64 | // ^ 65 | println!("The value of x is: {}", x); 66 | // ^ 67 | } 68 | // ### let expression 1 69 | fn main() { 70 | let x = 5; 71 | // ^ 72 | let y = { 73 | let x = 3; 74 | x + 1 75 | }; 76 | println!("The value of y is: {}", y); 77 | } 78 | // ### let expression 2 79 | fn main() { 80 | let x = 5; 81 | let y = { 82 | // ^ 83 | let x = 3; 84 | x + 1 85 | }; 86 | println!("The value of y is: {}", y); 87 | // ^ 88 | } 89 | // ### let expression 3 90 | fn main() { 91 | let x = 5; 92 | let y = { 93 | let x = 3; 94 | // ^ 95 | x + 1 96 | // ^ 97 | }; 98 | println!("The value of y is: {}", y); 99 | } 100 | // ### if-else-else 101 | fn main() { 102 | let number = 6; 103 | // ^ 104 | if number % 4 == 0 { 105 | // ^ 106 | println!("number is divisible by 4"); 107 | } else if number % 3 == 0 { 108 | // ^ 109 | println!("number is divisible by 3"); 110 | } else if number % 2 == 0 { 111 | // ^ 112 | println!("number is divisible by 2"); 113 | } else { 114 | println!("number is not divisible by 4, 3, or 2"); 115 | } 116 | } 117 | // ### loop-expression 118 | fn main() { 119 | let mut counter = 0; 120 | // ^ 121 | let result = loop { 122 | counter += 1; 123 | // ^ 124 | if counter == 10 { 125 | // ^ 126 | break counter * 2; 127 | // ^ 128 | } 129 | }; 130 | println!("The result is {}", result); 131 | } 132 | // ### for 133 | fn main() { 134 | let a = [10, 20, 30, 40]; 135 | for element in a.iter() { 136 | // ^ 137 | println!("the value is: {}", element); 138 | // ^ 139 | } 140 | } 141 | // ### /SKIP/ for-shadow 142 | fn main() { 143 | let a = [10, 20, 30, 40]; 144 | for a in a.iter() { 145 | // ^ 146 | println!("the value is: {}", a); 147 | // ^ 148 | } 149 | } 150 | // ### struct assign 151 | fn build_user(email: String, username: String) -> User { 152 | // ^ 153 | User { 154 | email: email, 155 | // ^ 156 | username: username, 157 | } 158 | } 159 | // ### struct assign shorthand 160 | fn build_user(email: String, username: String) -> User { 161 | // ^ 162 | User { 163 | email, 164 | // ^ 165 | username, 166 | } 167 | } 168 | // ### if-let 169 | let some_u8_value = Some(0u8); 170 | // ^ 171 | if let Some(3) = some_u8_value { 172 | // ^ 173 | println!("three"); 174 | } 175 | // ### match 176 | let some_u8_value = Some(0u8); 177 | // ^ 178 | match some_u8_value { 179 | // ^ 180 | Some(3) => println!("three"), 181 | _ => (), 182 | } 183 | // ### tuple-pattern 184 | fn main() { 185 | let (x, y, z) = tup; 186 | // ^ 187 | println!("The value of y is: {}", y); 188 | // ^ 189 | } 190 | // ### self-parameter 191 | impl Encode { 192 | pub fn as_str(&self) -> &str { 193 | // ^ 194 | str::from_utf8(&self.buf).unwrap() 195 | // ^ 196 | } 197 | } 198 | -------------------------------------------------------------------------------- /anycode-rust/fixtures/outline.rs: -------------------------------------------------------------------------------- 1 | // ### globals 2 | static LANGUAGE: &str = "Rust"; 3 | // ^ 4 | const THRESHOLD: i32 = 10; 5 | // ^ 6 | // ### function 7 | fn is_big(n: i32) -> bool { 8 | // ^ 9 | // Access constant in some function 10 | n > THRESHOLD 11 | } 12 | // ### impl with default function 13 | impl Foo { 14 | // ^ 15 | const default fn bar() -> i32 { 16 | // ^ 17 | default.bar(); 18 | } 19 | } 20 | // ### trait with function 21 | impl Show for i32 { 22 | // ^ 23 | fn show(&self) -> String { 24 | // ^ 25 | format!("four-byte signed {}", self) 26 | format!("four-byte signed {}", self) 27 | } 28 | } 29 | // ### trait 2 30 | impl Drop for Tree { 31 | // ^ 32 | fn drop(&mut self) { 33 | // ^ 34 | unsafe { ffi::ts_tree_delete(self.0.as_ptr()) } 35 | } 36 | } 37 | // ### trait w/ generics 38 | impl From for Value { 39 | // ^ ^ 40 | fn from(value: GraphNodeRef) -> Value { 41 | // ^ 42 | Value::GraphNode(value) 43 | } 44 | } 45 | // ### extern 46 | extern "system" { 47 | // ^ ^ 48 | pub fn fff() -> i32 49 | // ^ 50 | } 51 | -------------------------------------------------------------------------------- /anycode-rust/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/vscode-anycode/54d3bb922acbaf6e18650bf29a6c1198b963c000/anycode-rust/index.js -------------------------------------------------------------------------------- /anycode-rust/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "anycode-rust", 3 | "version": "0.0.8", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "anycode-rust", 9 | "version": "0.0.8", 10 | "hasInstallScript": true, 11 | "license": "MIT", 12 | "devDependencies": { 13 | "tree-sitter-cli": "^0.20.8", 14 | "tree-sitter-rust": "^0.20.4" 15 | }, 16 | "engines": { 17 | "vscode": "^1.67.0" 18 | } 19 | }, 20 | "node_modules/nan": { 21 | "version": "2.19.0", 22 | "resolved": "https://registry.npmjs.org/nan/-/nan-2.19.0.tgz", 23 | "integrity": "sha512-nO1xXxfh/RWNxfd/XPfbIfFk5vgLsAxUR9y5O0cHMJu/AW9U95JLXqthYHjEp+8gQ5p96K9jUp8nbVOxCdRbtw==", 24 | "dev": true 25 | }, 26 | "node_modules/tree-sitter-cli": { 27 | "version": "0.20.8", 28 | "resolved": "https://registry.npmjs.org/tree-sitter-cli/-/tree-sitter-cli-0.20.8.tgz", 29 | "integrity": "sha512-XjTcS3wdTy/2cc/ptMLc/WRyOLECRYcMTrSWyhZnj1oGSOWbHLTklgsgRICU3cPfb0vy+oZCC33M43u6R1HSCA==", 30 | "dev": true, 31 | "hasInstallScript": true, 32 | "bin": { 33 | "tree-sitter": "cli.js" 34 | } 35 | }, 36 | "node_modules/tree-sitter-rust": { 37 | "version": "0.20.4", 38 | "resolved": "https://registry.npmjs.org/tree-sitter-rust/-/tree-sitter-rust-0.20.4.tgz", 39 | "integrity": "sha512-pgqPgw/vmx3LGjsfOXHJ+YrIx/Xg0NYVPbUWwlonoQMHD0Jxd1i/Fgq6N0ANOu9Wmb188MN9dVRLHPotF+IW5g==", 40 | "dev": true, 41 | "hasInstallScript": true, 42 | "dependencies": { 43 | "nan": "^2.17.0" 44 | } 45 | } 46 | }, 47 | "dependencies": { 48 | "nan": { 49 | "version": "2.19.0", 50 | "resolved": "https://registry.npmjs.org/nan/-/nan-2.19.0.tgz", 51 | "integrity": "sha512-nO1xXxfh/RWNxfd/XPfbIfFk5vgLsAxUR9y5O0cHMJu/AW9U95JLXqthYHjEp+8gQ5p96K9jUp8nbVOxCdRbtw==", 52 | "dev": true 53 | }, 54 | "tree-sitter-cli": { 55 | "version": "0.20.8", 56 | "resolved": "https://registry.npmjs.org/tree-sitter-cli/-/tree-sitter-cli-0.20.8.tgz", 57 | "integrity": "sha512-XjTcS3wdTy/2cc/ptMLc/WRyOLECRYcMTrSWyhZnj1oGSOWbHLTklgsgRICU3cPfb0vy+oZCC33M43u6R1HSCA==", 58 | "dev": true 59 | }, 60 | "tree-sitter-rust": { 61 | "version": "0.20.4", 62 | "resolved": "https://registry.npmjs.org/tree-sitter-rust/-/tree-sitter-rust-0.20.4.tgz", 63 | "integrity": "sha512-pgqPgw/vmx3LGjsfOXHJ+YrIx/Xg0NYVPbUWwlonoQMHD0Jxd1i/Fgq6N0ANOu9Wmb188MN9dVRLHPotF+IW5g==", 64 | "dev": true, 65 | "requires": { 66 | "nan": "^2.17.0" 67 | } 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /anycode-rust/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "anycode-rust", 3 | "publisher": "ms-vscode", 4 | "displayName": "anycode-rust", 5 | "description": "Rust for Anycode", 6 | "license": "MIT", 7 | "version": "0.0.8", 8 | "preview": true, 9 | "repository": { 10 | "url": "https://github.com/microsoft/vscode-anycode" 11 | }, 12 | "engines": { 13 | "vscode": "^1.67.0" 14 | }, 15 | "categories": [ 16 | "Programming Languages" 17 | ], 18 | "contributes": { 19 | "anycodeLanguages": { 20 | "grammarPath": "./tree-sitter-rust.wasm", 21 | "languageId": "rust", 22 | "extensions": [ 23 | "rs" 24 | ], 25 | "queryPaths": { 26 | "comments": "./queries/comments.scm", 27 | "folding": "./queries/folding.scm", 28 | "identifiers": "./queries/identifiers.scm", 29 | "locals": "./queries/locals.scm", 30 | "outline": "./queries/outline.scm", 31 | "references": "./queries/references.scm" 32 | }, 33 | "suppressedBy": [ 34 | "rust-lang.rust-analyzer" 35 | ] 36 | } 37 | }, 38 | "scripts": { 39 | "postinstall": "npx tree-sitter build-wasm node_modules/tree-sitter-rust", 40 | "deploy": "npx vsce publish", 41 | "test": "node ../anycode/server/src/common/test-fixture/test.js --outline ./fixtures/outline.rs --highlights ./fixtures/highlights.rs" 42 | }, 43 | "devDependencies": { 44 | "tree-sitter-cli": "^0.20.8", 45 | "tree-sitter-rust": "^0.20.4" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /anycode-rust/queries/comments.scm: -------------------------------------------------------------------------------- 1 | (line_comment) @comment 2 | (block_comment) @comment 3 | -------------------------------------------------------------------------------- /anycode-rust/queries/folding.scm: -------------------------------------------------------------------------------- 1 | (block_comment) @comment 2 | (block) @scope 3 | (_) body: (_) @fold 4 | -------------------------------------------------------------------------------- /anycode-rust/queries/identifiers.scm: -------------------------------------------------------------------------------- 1 | (scoped_identifier) @identifier 2 | (type_identifier) @identifier 3 | (field_identifier) @identifier 4 | (identifier) @identifier 5 | -------------------------------------------------------------------------------- /anycode-rust/queries/locals.scm: -------------------------------------------------------------------------------- 1 | (mod_item body: (declaration_list) @scope.exports) 2 | (for_expression) @scope 3 | (function_item) @scope 4 | (block) @scope 5 | 6 | (function_item name: (identifier) @local.escape) 7 | (const_item name: (identifier) @local) 8 | (static_item name: (identifier) @local) 9 | (let_declaration pattern: (identifier) @local) 10 | (parameter pattern: (identifier) @local) 11 | (for_expression pattern: (identifier) @local) 12 | (reference_pattern (identifier) @local) 13 | (tuple_pattern (identifier) @local) 14 | (self_parameter (self) @local) 15 | 16 | (scoped_identifier name: (identifier) @usage.void) 17 | (identifier) @usage 18 | (self) @usage 19 | -------------------------------------------------------------------------------- /anycode-rust/queries/outline.scm: -------------------------------------------------------------------------------- 1 | (mod_item 2 | name: (identifier) @module.name) @module 3 | 4 | (function_item 5 | name: (identifier) @function.name) @function 6 | 7 | (union_item 8 | name: (type_identifier) @struct.name) @struct 9 | 10 | (field_declaration 11 | name: (field_identifier) @field.name) @field 12 | 13 | (struct_item 14 | name: (type_identifier) @struct.name) @struct 15 | 16 | (enum_item 17 | name: (type_identifier) @enum.name) @enum 18 | 19 | (enum_variant 20 | name: (identifier) @enumMember.name) @enumMember 21 | 22 | (trait_item 23 | name: (type_identifier) @interface.name) @interface 24 | 25 | (function_signature_item 26 | name: (identifier) @function.name) @function 27 | 28 | (const_item 29 | name: (identifier) @constant.name) @constant 30 | 31 | (static_item 32 | name: (identifier) @constant.name) @constant 33 | 34 | (type_item 35 | name: (type_identifier) @interface.name) @interface 36 | 37 | (impl_item 38 | . [(generic_type) (type_identifier)] @class.name) @class 39 | 40 | (foreign_mod_item 41 | (extern_modifier (string_literal) @namespace.name)) @namespace 42 | -------------------------------------------------------------------------------- /anycode-rust/queries/references.scm: -------------------------------------------------------------------------------- 1 | (field_identifier) @ref.field.method 2 | (type_identifier) @ref.interface.struct.class 3 | (call_expression (identifier) @ref.function) 4 | (scoped_identifier name: (identifier) @ref) 5 | (macro_invocation macro: (identifier) @ref) 6 | ((macro_invocation (token_tree (identifier) @ref))) 7 | -------------------------------------------------------------------------------- /anycode-typescript/.vscodeignore: -------------------------------------------------------------------------------- 1 | azure-pipelines.yml 2 | -------------------------------------------------------------------------------- /anycode-typescript/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE 22 | -------------------------------------------------------------------------------- /anycode-typescript/azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | name: $(Date:yyyyMMdd)$(Rev:.r) 2 | 3 | trigger: 4 | branches: 5 | include: 6 | - main 7 | paths: 8 | include: 9 | - anycode-typescript 10 | pr: none 11 | 12 | resources: 13 | repositories: 14 | - repository: templates 15 | type: github 16 | name: microsoft/vscode-engineering 17 | ref: main 18 | endpoint: Monaco 19 | 20 | parameters: 21 | - name: publishExtension 22 | displayName: 🚀 Publish Extension 23 | type: boolean 24 | default: false 25 | 26 | extends: 27 | template: azure-pipelines/extension/stable.yml@templates 28 | parameters: 29 | buildSteps: 30 | - script: | 31 | export npm_config_build_from_source=true 32 | cd anycode-typescript && npm install 33 | displayName: Install dependencies 34 | 35 | - script: cd anycode && npm install 36 | displayName: Install dependencies (anycode) 37 | 38 | - script: cd anycode-typescript && npm run test 39 | displayName: Run Test Fixtures 40 | 41 | ghCreateTag: true 42 | ghTagPrefix: anycode-typescript.v 43 | 44 | publishExtension: ${{ parameters.publishExtension }} 45 | 46 | tsa: 47 | config: 48 | areaPath: 'Visual Studio Code Language Extensions' 49 | serviceTreeID: 'c4cd3983-4977-4bcd-931f-a9822d2e950c' 50 | enabled: true 51 | 52 | cgSourceScanPath: $(Build.SourcesDirectory)/anycode-typescript 53 | workingDirectory: $(Build.SourcesDirectory)/anycode-typescript 54 | -------------------------------------------------------------------------------- /anycode-typescript/fixtures/highlights.ts: -------------------------------------------------------------------------------- 1 | // ### function, argument -> same name 2 | function foo(foo: number) { 3 | // ^ 4 | console.log(foo) 5 | // ^ 6 | } 7 | // ### function, argument -> same name, 2 8 | function foo(foo:number) { 9 | // ^ 10 | console.log(foo) 11 | } 12 | foo(1); 13 | //^ 14 | // ### generic type argument 15 | let E = 1; 16 | function bar(foo: E):E { 17 | // ^ 18 | // ^ 19 | // ^ 20 | 21 | } 22 | -------------------------------------------------------------------------------- /anycode-typescript/fixtures/outline.ts: -------------------------------------------------------------------------------- 1 | // ### declared modules 2 | declare module 'fff' { 3 | // ^ ^ 4 | export namespace env { 5 | // ^ 6 | export const foo: number; 7 | // ^ 8 | export function openExternal(target: Uri): Thenable; 9 | // ^ 10 | } 11 | } 12 | // ### type alias 13 | type FooDooBarBazz = number; 14 | // ^ 15 | // ### class types 16 | const nullReporter = new class NullTelemetryReporter implements TelemetryReporter { 17 | // ^ 18 | // ^ 19 | sendTelemetryEvent() { /** noop */ } 20 | // ^ 21 | dispose() { /** noop */ } 22 | // ^ 23 | }; 24 | -------------------------------------------------------------------------------- /anycode-typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "anycode-typescript", 3 | "publisher": "ms-vscode", 4 | "displayName": "anycode-typescript", 5 | "description": "TypeScript for Anycode", 6 | "license": "MIT", 7 | "version": "0.0.7", 8 | "preview": true, 9 | "repository": { 10 | "url": "https://github.com/microsoft/vscode-anycode" 11 | }, 12 | "engines": { 13 | "vscode": "^1.67.0" 14 | }, 15 | "categories": [ 16 | "Programming Languages" 17 | ], 18 | "contributes": { 19 | "anycodeLanguages": { 20 | "grammarPath": "./tree-sitter-typescript.wasm", 21 | "languageId": "typescript", 22 | "extensions": [ 23 | "ts" 24 | ], 25 | "queryPaths": { 26 | "comments": "./queries/comments.scm", 27 | "identifiers": "./queries/identifiers.scm", 28 | "locals": "./queries/locals.scm", 29 | "outline": "./queries/outline.scm", 30 | "references": "./queries/references.scm" 31 | }, 32 | "suppressedBy": [ 33 | "vscode.typescript-language-features" 34 | ] 35 | } 36 | }, 37 | "scripts": { 38 | "postinstall": "npx tree-sitter build-wasm node_modules/tree-sitter-typescript/typescript", 39 | "deploy": "npx vsce publish", 40 | "test": "node ../anycode/server/src/common/test-fixture/test.js --outline ./fixtures/outline.ts --highlights ./fixtures/highlights.ts" 41 | }, 42 | "devDependencies": { 43 | "@playwright/test": "^1.14.1", 44 | "tree-sitter-cli": "^0.20.8", 45 | "tree-sitter-typescript": "^0.20.3" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /anycode-typescript/queries/comments.scm: -------------------------------------------------------------------------------- 1 | (comment) @comment 2 | -------------------------------------------------------------------------------- /anycode-typescript/queries/identifiers.scm: -------------------------------------------------------------------------------- 1 | (identifier) @identifier 2 | (property_identifier) @identifier 3 | (type_identifier) @identifier 4 | -------------------------------------------------------------------------------- /anycode-typescript/queries/locals.scm: -------------------------------------------------------------------------------- 1 | (method_definition) @scope 2 | (function_declaration) @scope 3 | (function_expression) @scope 4 | (arrow_function) @scope 5 | [(class_body) (enum_body)] @scope 6 | (interface_declaration body: (interface_body) @scope) 7 | (for_statement) @scope 8 | (if_statement consequence: (_) @scope) 9 | (if_statement alternative: (_) @scope) 10 | (while_statement body: (_) @scope) 11 | (try_statement (statement_block) @scope) 12 | (catch_clause) @scope 13 | (statement_block) @scope 14 | 15 | (function_declaration name: (identifier) @local.escape) 16 | (function_expression name: (identifier) @local.escape) 17 | (required_parameter (identifier) @local) 18 | (optional_parameter (identifier) @local) 19 | (catch_clause parameter: (identifier) @local) 20 | (variable_declarator (identifier) @local) 21 | (type_parameter (type_identifier) @local) 22 | 23 | (enum_declaration name: (identifier) @usage.void) 24 | (identifier) @usage 25 | (type_identifier) @usage 26 | -------------------------------------------------------------------------------- /anycode-typescript/queries/outline.scm: -------------------------------------------------------------------------------- 1 | (interface_declaration 2 | name: (type_identifier) @interface.name) @interface 3 | 4 | (property_signature 5 | name: (property_identifier) @field.name) @field 6 | 7 | (method_signature 8 | name: (property_identifier) @method.name) @method 9 | 10 | (class_declaration 11 | name: (type_identifier) @class.name) @class 12 | 13 | (new_expression 14 | constructor: (class 15 | name: (type_identifier)? @class.name 16 | body: (class_body)) @class) 17 | 18 | (method_definition 19 | name: [ 20 | (property_identifier) @method.name 21 | (computed_property_name (string) @method.name) 22 | ]) @method 23 | 24 | (public_field_definition 25 | name: [ 26 | (property_identifier) @field.name 27 | (computed_property_name (string) @field.name) 28 | ]) @field 29 | 30 | (enum_declaration 31 | name: (identifier) @enum.name) @enum 32 | 33 | (enum_body [ 34 | (property_identifier) @enumMember 35 | (enum_assignment (property_identifier) @enumMember)]) 36 | 37 | (function_declaration 38 | name: (identifier) @function.name) @function 39 | 40 | (function_signature 41 | name: (identifier) @function.name) @function 42 | 43 | (variable_declarator 44 | name: (identifier) @variable.name) @variable 45 | 46 | (module 47 | name: [(identifier)@module.name (string) @module.name]) @module 48 | 49 | (internal_module 50 | name: (identifier) @module.name) @module 51 | 52 | (type_alias_declaration 53 | name: (type_identifier) @interface.name) @interface 54 | -------------------------------------------------------------------------------- /anycode-typescript/queries/references.scm: -------------------------------------------------------------------------------- 1 | (type_identifier) @ref.class.interface.enum 2 | (new_expression 3 | constructor: (identifier) @ref.class) 4 | (call_expression [ 5 | (identifier) @ref.function 6 | (member_expression property: (property_identifier) @ref.function)]) 7 | (property_identifier) @ref.field.method 8 | (import_specifier 9 | name: (identifier) @ref.import) 10 | -------------------------------------------------------------------------------- /anycode/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "@typescript-eslint/parser", 4 | "parserOptions": { 5 | "ecmaVersion": 6, 6 | "sourceType": "module" 7 | }, 8 | "plugins": [ 9 | "@typescript-eslint" 10 | ], 11 | "rules": { 12 | "@typescript-eslint/semi": "warn", 13 | "curly": "warn", 14 | "eqeqeq": "warn", 15 | "no-throw-literal": "warn", 16 | "semi": "off" 17 | }, 18 | "ignorePatterns": [ 19 | "**/*.d.ts", 20 | "**/*.js", 21 | "**/fixtures" 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /anycode/.vscodeignore: -------------------------------------------------------------------------------- 1 | esbuild.js 2 | azure-pipelines.yml 3 | .gitignore 4 | .vscode/** 5 | .vscode-test/** 6 | .github/** 7 | server/tree-sitter/*.js 8 | src/** 9 | **/tsconfig.json 10 | **/.eslintrc.json 11 | **/*.map 12 | **/*.ts 13 | **/node_modules/** 14 | !server/node_modules/web-tree-sitter/tree-sitter.wasm 15 | **/test/** 16 | -------------------------------------------------------------------------------- /anycode/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE 22 | -------------------------------------------------------------------------------- /anycode/azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | name: $(Date:yyyyMMdd)$(Rev:.r) 2 | 3 | trigger: 4 | branches: 5 | include: 6 | - main 7 | paths: 8 | include: 9 | - anycode 10 | pr: none 11 | 12 | resources: 13 | repositories: 14 | - repository: templates 15 | type: github 16 | name: microsoft/vscode-engineering 17 | ref: main 18 | endpoint: Monaco 19 | 20 | parameters: 21 | - name: publishExtension 22 | displayName: 🚀 Publish Extension 23 | type: boolean 24 | default: false 25 | 26 | extends: 27 | template: azure-pipelines/extension/stable.yml@templates 28 | parameters: 29 | cgSourceScanPath: $(Build.SourcesDirectory)/anycode 30 | workingDirectory: $(Build.SourcesDirectory)/anycode 31 | buildSteps: 32 | - script: cd anycode && npm install 33 | displayName: Install All dependencies 34 | 35 | - script: cd anycode && npm run compile 36 | displayName: Compile extension 37 | 38 | - script: cd anycode && npm run test-server 39 | displayName: Compile extension 40 | 41 | ghCreateTag: true 42 | ghTagPrefix: anycode.v 43 | 44 | tsa: 45 | config: 46 | areaPath: 'Visual Studio Code Language Extensions' 47 | serviceTreeID: 'c4cd3983-4977-4bcd-931f-a9822d2e950c' 48 | enabled: true 49 | 50 | publishExtension: ${{ parameters.publishExtension }} 51 | -------------------------------------------------------------------------------- /anycode/client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "anycode-client", 3 | "license": "MIT", 4 | "publisher": "ms-vscode", 5 | "dependencies": { 6 | "@vscode/extension-telemetry": "0.8.5", 7 | "vscode-languageclient": "^8.0.0-next.5" 8 | }, 9 | "devDependencies": { 10 | "@types/node": "17.0.25", 11 | "assert": "~2.0.0" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /anycode/client/src/browser/main.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | import * as vscode from 'vscode'; 7 | import { CommonLanguageClient, LanguageClientOptions } from 'vscode-languageclient'; 8 | import { LanguageClient } from 'vscode-languageclient/browser'; 9 | import { startClient, LanguageClientFactory } from '../common/client'; 10 | 11 | export async function activate(context: vscode.ExtensionContext) { 12 | 13 | const factory = new class implements LanguageClientFactory { 14 | 15 | private readonly _map = new Map(); 16 | 17 | createLanguageClient(id: string, name: string, clientOptions: LanguageClientOptions): CommonLanguageClient { 18 | const serverMain = vscode.Uri.joinPath(context.extensionUri, 'dist/anycode.server.browser.js'); 19 | const worker = new Worker(serverMain.toString()); 20 | const result = new LanguageClient(id, name, clientOptions, worker); 21 | this._map.set(result, worker); 22 | return result; 23 | } 24 | destoryLanguageClient(client: CommonLanguageClient): void { 25 | const worker = this._map.get(client); 26 | if (worker) { 27 | worker.terminate(); 28 | this._map.delete(client); 29 | } 30 | } 31 | }; 32 | 33 | return startClient(factory, context); 34 | } 35 | -------------------------------------------------------------------------------- /anycode/client/src/common/vscode.proposed.extensionsAny.d.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | declare module 'vscode' { 7 | 8 | // https://github.com/microsoft/vscode/issues/145307 9 | 10 | export interface Extension { 11 | 12 | /** 13 | * `true` when the extension is associated to another extension host. 14 | * 15 | * *Note* that an extension from another extension host cannot export 16 | * API, e.g {@link Extension.exports its exports} are always `undefined`. 17 | */ 18 | readonly isFromDifferentExtensionHost: boolean; 19 | } 20 | 21 | export namespace extensions { 22 | 23 | /** 24 | * Get an extension by its full identifier in the form of: `publisher.name`. 25 | * 26 | * @param extensionId An extension identifier. 27 | * @param includeDifferentExtensionHosts Include extensions from different extension host 28 | * @return An extension or `undefined`. 29 | */ 30 | export function getExtension(extensionId: string, includeDifferentExtensionHosts: boolean): Extension | undefined; 31 | 32 | /** 33 | * All extensions across all extension hosts. 34 | * 35 | * @see {@link Extension.isFromDifferentExtensionHost} 36 | */ 37 | export const allAcrossExtensionHosts: readonly Extension[]; 38 | 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /anycode/client/src/node/main.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | import * as vscode from 'vscode'; 7 | import { CommonLanguageClient, LanguageClientOptions } from 'vscode-languageclient'; 8 | import { LanguageClient, ServerOptions, TransportKind } from 'vscode-languageclient/node'; 9 | import { startClient, LanguageClientFactory } from '../common/client'; 10 | 11 | export async function activate(context: vscode.ExtensionContext) { 12 | 13 | const factory = new class implements LanguageClientFactory { 14 | 15 | createLanguageClient(id: string, name: string, clientOptions: LanguageClientOptions): CommonLanguageClient { 16 | const serverModule = vscode.Uri.joinPath(context.extensionUri, 'dist/anycode.server.node.js').fsPath; 17 | 18 | 19 | // The debug options for the server 20 | const debugOptions = { execArgv: ['--nolazy', '--inspect=' + (7000 + Math.round(Math.random() * 999))] }; 21 | 22 | // If the extension is launch in debug mode the debug server options are use 23 | // Otherwise the run options are used 24 | const serverOptions: ServerOptions = { 25 | run: { module: serverModule, transport: TransportKind.ipc }, 26 | debug: { module: serverModule, transport: TransportKind.ipc, options: debugOptions } 27 | }; 28 | 29 | const client = new LanguageClient(id, serverOptions, clientOptions); 30 | 31 | // support file-based symbol storage 32 | client.onReady().then(() => { 33 | const persistUri = context.storageUri && vscode.Uri.joinPath(context.storageUri, 'anycode.db'); 34 | const encoder = new TextEncoder(); 35 | const decoder = new TextDecoder(); 36 | 37 | client.onRequest('persisted/read', async (): Promise => { 38 | if (!persistUri) { 39 | return ''; 40 | } 41 | try { 42 | const data = await vscode.workspace.fs.readFile(persistUri); 43 | return decoder.decode(data); 44 | } catch { 45 | return ''; 46 | } 47 | }); 48 | client.onRequest('persisted/write', async (json: string) => { 49 | if (persistUri) { 50 | const data = encoder.encode(json); 51 | await vscode.workspace.fs.writeFile(persistUri, new Uint8Array(data)); 52 | } 53 | }); 54 | }); 55 | 56 | return client; 57 | } 58 | destoryLanguageClient(client: CommonLanguageClient): void { 59 | if (client instanceof LanguageClient) { 60 | client.stop(); 61 | } 62 | } 63 | }; 64 | 65 | return startClient(factory, context); 66 | } 67 | -------------------------------------------------------------------------------- /anycode/client/tsconfig.browser.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.base.json", 3 | "compilerOptions": { 4 | "lib": [ 5 | "ES2020", 6 | "WebWorker" 7 | ] 8 | }, 9 | "include": [ 10 | "src/common/*", 11 | "src/browser/*", 12 | "../shared/common/*" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /anycode/client/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.base.json", 3 | "include": [ 4 | "src/common/*", 5 | "src/node/*", 6 | "../shared/common/*" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /anycode/esbuild.js: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | const esbuild = require('esbuild') 7 | 8 | 9 | let watch; 10 | if (process.argv.includes('--watch')) { 11 | watch = { 12 | onRebuild(error, result) { 13 | if (error) { 14 | console.error('watch build failed:', error); 15 | } else { 16 | console.log('watch build succeeded'); 17 | } 18 | } 19 | } 20 | } 21 | 22 | // --- extension 23 | 24 | const clientBuildOptions = { 25 | bundle: true, 26 | external: ['vscode'], 27 | target: 'es2020', 28 | format: 'cjs', 29 | sourcemap: 'external', 30 | watch 31 | } 32 | 33 | const browserClient = esbuild.build({ 34 | ...clientBuildOptions, 35 | entryPoints: ['client/src/browser/main.ts'], 36 | outfile: 'dist/anycode.extension.browser.js', 37 | }).catch((e) => { 38 | console.error(e) 39 | }); 40 | 41 | const nodeClient = esbuild.build({ 42 | ...clientBuildOptions, 43 | platform: 'node', 44 | entryPoints: ['client/src/node/main.ts'], 45 | outfile: 'dist/anycode.extension.node.js', 46 | }).catch((e) => { 47 | console.error(e) 48 | }); 49 | 50 | // --- server 51 | 52 | const serverBuildOptions = { 53 | bundle: true, 54 | external: ['fs', 'path'], // not ideal but because of treesitter/emcc 55 | target: 'es2020', 56 | format: 'iife', 57 | sourcemap: 'external', 58 | watch 59 | } 60 | 61 | const browserServer = esbuild.build({ 62 | ...serverBuildOptions, 63 | entryPoints: ['server/src/browser/main.ts'], 64 | outfile: 'dist/anycode.server.browser.js', 65 | }).catch((e) => { 66 | console.error(e) 67 | }); 68 | 69 | const nodeServer = esbuild.build({ 70 | ...serverBuildOptions, 71 | platform: 'node', 72 | entryPoints: ['server/src/node/main.ts'], 73 | outfile: 'dist/anycode.server.node.js', 74 | }).catch((e) => { 75 | console.error(e) 76 | }); 77 | 78 | const serverTests = esbuild.build({ 79 | entryPoints: ['server/src/common/test/trie.test.ts'], 80 | outfile: 'server/src/common/test/trie.test.js', 81 | bundle: true, 82 | external: ['fs', 'path'], // not ideal but because of treesitter/emcc 83 | target: 'es2020', 84 | format: 'iife', 85 | watch 86 | }).catch((e) => { 87 | console.error(e) 88 | }); 89 | 90 | // --- tests-fixtures 91 | 92 | const testFixture = esbuild.build({ 93 | entryPoints: ['server/src/common/test-fixture/client/test.all.ts'], 94 | outfile: 'server/src/common/test-fixture/client/test.all.js', 95 | bundle: true, 96 | define: { process: '{"env":{}}' }, // assert-lib 97 | external: ['fs', 'path'], // not ideal but because of treesitter/emcc 98 | target: 'es2020', 99 | watch 100 | }).catch((e) => { 101 | console.error(e) 102 | }); 103 | 104 | Promise.all([ 105 | browserClient, browserServer, // client 106 | nodeClient, nodeServer, // server 107 | serverTests, testFixture // testing 108 | ]).then(() => { 109 | if (watch) { 110 | console.log('done building, watching for file changes') 111 | } else { 112 | console.log('done building') 113 | } 114 | }) 115 | -------------------------------------------------------------------------------- /anycode/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "anycode", 3 | "displayName": "anycode", 4 | "publisher": "ms-vscode", 5 | "description": "", 6 | "version": "0.0.74", 7 | "license": "MIT", 8 | "aiKey": "0c6ae279ed8443289764825290e4f9e2-1a736e7c-1324-4338-be46-fc2a58ae4d14-7255", 9 | "preview": true, 10 | "repository": { 11 | "url": "https://github.com/microsoft/vscode-anycode" 12 | }, 13 | "engines": { 14 | "vscode": "^1.80.0" 15 | }, 16 | "categories": [ 17 | "Programming Languages" 18 | ], 19 | "activationEvents": [ 20 | "onStartupFinished", 21 | "onCommand:workbench.action.showAllSymbols" 22 | ], 23 | "enabledApiProposals": [ 24 | "extensionsAny" 25 | ], 26 | "capabilities": { 27 | "untrustedWorkspaces": { 28 | "supported": true 29 | }, 30 | "virtualWorkspaces": true 31 | }, 32 | "browser": "./dist/anycode.extension.browser.js", 33 | "main": "./dist/anycode.extension.node.js", 34 | "contributes": { 35 | "configuration": { 36 | "title": "Anycode", 37 | "properties": { 38 | "anycode.symbolIndexSize": { 39 | "type": "number", 40 | "default": 500, 41 | "minimum": 0, 42 | "markdownDescription": "Size of the index that is used for features like symbol search and go to definition." 43 | }, 44 | "anycode.language.features": { 45 | "markdownDescription": "Control the language features that anycode offers. This can be configured for each supported language: [Learn How to Do That](https://code.visualstudio.com/docs/getstarted/settings#_languagespecific-editor-settings)", 46 | "type": "object", 47 | "scope": "language-overridable", 48 | "additionalProperties": false, 49 | "properties": { 50 | "definitions": { 51 | "type": "boolean", 52 | "description": "Go to Definition based on identifiers and local variables" 53 | }, 54 | "references": { 55 | "type": "boolean", 56 | "description": "Find References based on identifiers and local variables" 57 | }, 58 | "workspaceSymbols": { 59 | "type": "boolean", 60 | "description": "Add symbols to workspace symbol search" 61 | }, 62 | "highlights": { 63 | "type": "boolean", 64 | "description": "Highlight Occurrences of identifiers and local variables" 65 | }, 66 | "outline": { 67 | "type": "boolean", 68 | "description": "Populate Outline, Quick-outline, and Breadcrumbs" 69 | }, 70 | "completions": { 71 | "type": "boolean", 72 | "description": "Completions based on identifiers and symbol names" 73 | }, 74 | "folding": { 75 | "type": "boolean", 76 | "description": "Fold sections of codes to a single line" 77 | }, 78 | "diagnostics": { 79 | "type": "boolean", 80 | "description": "(experimental) Parse errors show as problems" 81 | } 82 | }, 83 | "default": { 84 | "completions": true, 85 | "definitions": true, 86 | "references": true, 87 | "highlights": true, 88 | "outline": true, 89 | "workspaceSymbols": true, 90 | "folding": false, 91 | "diagnostics": false 92 | } 93 | } 94 | } 95 | } 96 | }, 97 | "extensionPack": [ 98 | "ms-vscode.anycode-c-sharp", 99 | "ms-vscode.anycode-cpp", 100 | "ms-vscode.anycode-go", 101 | "ms-vscode.anycode-java", 102 | "ms-vscode.anycode-kotlin", 103 | "ms-vscode.anycode-php", 104 | "ms-vscode.anycode-python", 105 | "ms-vscode.anycode-rust", 106 | "ms-vscode.anycode-typescript" 107 | ], 108 | "scripts": { 109 | "vscode:prepublish": "npm run compile", 110 | "compile": "tsc -b tsconfig.json && node esbuild.js", 111 | "watch": "node esbuild.js --watch", 112 | "postinstall": "cd client && npm install && cd ../server && npm install && cd .. && node esbuild.js", 113 | "lint": "eslint client server --ext ts", 114 | "deploy": "npx vsce publish --noVerify", 115 | "pretest-extension": "npx esbuild client/src/test/suite/index.ts --bundle --external:vscode --target=es2020 --format=cjs --outfile=dist/extension.test.js --define:process=\"{\\\"env\\\":{}}\"", 116 | "test-server": "cd server && npm run test" 117 | }, 118 | "devDependencies": { 119 | "@types/node": "^22.10.5", 120 | "@typescript-eslint/eslint-plugin": "^8.19.1", 121 | "@typescript-eslint/parser": "^8.19.1", 122 | "@vscode/test-web": "^0.0.65", 123 | "esbuild": "^0.15.12", 124 | "eslint": "^9.18.0", 125 | "typescript": "^5.7.3", 126 | "@vscode/vsce": "^3.2.1" 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /anycode/server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "anycode-client", 3 | "license": "MIT", 4 | "publisher": "ms-vscode", 5 | "scripts": { 6 | "postinstall": "npx playwright install-deps", 7 | "test": "npx mocha --ui tdd src/**/test/*.test.js" 8 | }, 9 | "dependencies": { 10 | "vscode-languageserver": "^8.0.0-next.4", 11 | "vscode-languageserver-textdocument": "^1.0.4" 12 | }, 13 | "devDependencies": { 14 | "@playwright/test": "^1.14.1", 15 | "@types/assert": "^1.5.6", 16 | "@types/chai": "^4.2.21", 17 | "@types/mocha": "~10.0.10", 18 | "assert": "~2.0.0", 19 | "mocha": "~11.1.0", 20 | "web-tree-sitter": "0.20.8", 21 | "yargs": "^17.3.1" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /anycode/server/src/browser/main.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | import { BrowserMessageReader, BrowserMessageWriter, createConnection } from 'vscode-languageserver/browser'; 7 | import { MemorySymbolStorage, SymbolInfoStorage } from '../common/features/symbolIndex'; 8 | import { IStorageFactory, startServer } from '../common/server'; 9 | import { IndexedDBSymbolStorage } from './storage'; 10 | 11 | const messageReader = new BrowserMessageReader(self); 12 | const messageWriter = new BrowserMessageWriter(self); 13 | 14 | const connection = createConnection(messageReader, messageWriter); 15 | 16 | const factory: IStorageFactory = { 17 | async create(name) { 18 | try { 19 | const result = new IndexedDBSymbolStorage(name); 20 | await result.open(); 21 | return result; 22 | } catch (e) { 23 | console.error('FAILED to create indexedDB-based storage, using volatile in-memory storage INSTEAD'); 24 | return new MemorySymbolStorage(); 25 | } 26 | }, 27 | async destroy(obj: SymbolInfoStorage) { 28 | if (obj instanceof IndexedDBSymbolStorage) { 29 | await obj.close(); 30 | } 31 | } 32 | }; 33 | 34 | startServer(connection, factory); 35 | -------------------------------------------------------------------------------- /anycode/server/src/common/documentStore.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | import * as lsp from 'vscode-languageserver'; 7 | import { TextDocuments } from 'vscode-languageserver'; 8 | import { TextDocument } from 'vscode-languageserver-textdocument'; 9 | import { CustomMessages } from '../../../shared/common/messages'; 10 | import Languages from './languages'; 11 | import { LRUMap } from './util/lruMap'; 12 | 13 | export interface TextDocumentChange2 { 14 | document: TextDocument, 15 | changes: { 16 | range: lsp.Range; 17 | rangeOffset: number; 18 | rangeLength: number; 19 | text: string; 20 | }[] 21 | } 22 | 23 | export class DocumentStore extends TextDocuments { 24 | 25 | private readonly _onDidChangeContent2 = new lsp.Emitter(); 26 | readonly onDidChangeContent2 = this._onDidChangeContent2.event; 27 | 28 | private readonly _decoder = new TextDecoder(); 29 | private readonly _fileDocuments: LRUMap>; 30 | 31 | constructor(private readonly _connection: lsp.Connection) { 32 | super({ 33 | create: TextDocument.create, 34 | update: (doc, changes, version) => { 35 | let result: TextDocument; 36 | let incremental = true; 37 | let event: TextDocumentChange2 = { document: doc, changes: [] }; 38 | 39 | for (const change of changes) { 40 | if (!lsp.TextDocumentContentChangeEvent.isIncremental(change)) { 41 | incremental = false; 42 | break; 43 | } 44 | const rangeOffset = doc.offsetAt(change.range.start); 45 | event.changes.push({ 46 | text: change.text, 47 | range: change.range, 48 | rangeOffset, 49 | rangeLength: change.rangeLength ?? doc.offsetAt(change.range.end) - rangeOffset, 50 | }); 51 | } 52 | result = TextDocument.update(doc, changes, version); 53 | if (incremental) { 54 | this._onDidChangeContent2.fire(event); 55 | } 56 | return result; 57 | } 58 | }); 59 | 60 | this._fileDocuments = new LRUMap>({ 61 | size: 200, 62 | dispose: _entries => { } 63 | }); 64 | 65 | super.listen(_connection); 66 | } 67 | 68 | async retrieve(uri: string): Promise { 69 | let result = this.get(uri); 70 | if (result) { 71 | return result; 72 | } 73 | let promise = this._fileDocuments.get(uri); 74 | if (!promise) { 75 | promise = this._requestDocument(uri); 76 | this._fileDocuments.set(uri, promise); 77 | } 78 | return promise; 79 | } 80 | 81 | private async _requestDocument(uri: string): Promise { 82 | const reply = await this._connection.sendRequest(CustomMessages.FileRead, uri); 83 | const bytes = new Uint8Array(reply); 84 | return TextDocument.create(uri, Languages.getLanguageIdByUri(uri), 1, this._decoder.decode(bytes)); 85 | } 86 | 87 | // remove "file document", e.g one that has been retrieved from "disk" 88 | // and not one that is sync'd by LSP 89 | removeFile(uri: string) { 90 | return this._fileDocuments.delete(uri); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /anycode/server/src/common/features/completions.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | import * as lsp from 'vscode-languageserver'; 7 | import { DocumentStore } from '../documentStore'; 8 | import Languages from '../languages'; 9 | import { Trees } from '../trees'; 10 | import { nodeAtPosition } from '../common'; 11 | import { SymbolIndex } from './symbolIndex'; 12 | 13 | export class CompletionItemProvider { 14 | 15 | constructor( 16 | private readonly _documents: DocumentStore, 17 | private readonly _trees: Trees, 18 | private _symbols: SymbolIndex 19 | ) { } 20 | 21 | register(connection: lsp.Connection) { 22 | connection.client.register(lsp.CompletionRequest.type, { documentSelector: Languages.getSupportedLanguages('completions', ['identifiers', 'outline']) }); 23 | connection.onRequest(lsp.CompletionRequest.type, this.provideCompletionItems.bind(this)); 24 | } 25 | 26 | async provideCompletionItems(params: lsp.CompletionParams): Promise { 27 | 28 | const document = await this._documents.retrieve(params.textDocument.uri); 29 | const tree = await this._trees.getParseTree(document); 30 | if (!tree) { 31 | return []; 32 | } 33 | 34 | const result = new Map(); 35 | 36 | // (1) all identifiers that are used in this file 37 | const query = Languages.getQuery(tree.getLanguage(), 'identifiers'); 38 | const captures = query.captures(tree.rootNode); 39 | for (const capture of captures) { 40 | const text = capture.node.text; 41 | result.set(text, { label: text }); 42 | } 43 | 44 | 45 | // (2) all definitions that are known in this project (override less specific local identifiers) 46 | 47 | // don't wait for the whole index to be updated but use what we have right now, 48 | // it is very likely that the current file has changed and that we have it already processed 49 | // await this._symbols.update(); 50 | 51 | for (const [name, map] of this._symbols.index) { 52 | for (const [, info] of map) { 53 | if (info.definitions.size > 0) { 54 | const [firstDefinitionKind] = info.definitions; 55 | result.set(name, { 56 | label: name, 57 | kind: CompletionItemProvider._kindMapping.get(firstDefinitionKind) 58 | }); 59 | break; 60 | } 61 | } 62 | } 63 | 64 | // remove current identifier (the one that's being typed) 65 | const current = nodeAtPosition(tree.rootNode, params.position, true); 66 | const currentCaptures = query.captures(current); 67 | if (currentCaptures.length === 1) { 68 | result.delete(currentCaptures[0].node.text); 69 | } 70 | 71 | return Array.from(result.values()); 72 | } 73 | 74 | private static _kindMapping = new Map([ 75 | [lsp.SymbolKind.Class, lsp.CompletionItemKind.Class], 76 | [lsp.SymbolKind.Interface, lsp.CompletionItemKind.Interface], 77 | [lsp.SymbolKind.Field, lsp.CompletionItemKind.Field], 78 | [lsp.SymbolKind.Property, lsp.CompletionItemKind.Property], 79 | [lsp.SymbolKind.Event, lsp.CompletionItemKind.Event], 80 | [lsp.SymbolKind.Constructor, lsp.CompletionItemKind.Constructor], 81 | [lsp.SymbolKind.Method, lsp.CompletionItemKind.Method], 82 | [lsp.SymbolKind.Enum, lsp.CompletionItemKind.Enum], 83 | [lsp.SymbolKind.EnumMember, lsp.CompletionItemKind.EnumMember], 84 | [lsp.SymbolKind.Function, lsp.CompletionItemKind.Function], 85 | [lsp.SymbolKind.Variable, lsp.CompletionItemKind.Variable], 86 | ]); 87 | } 88 | -------------------------------------------------------------------------------- /anycode/server/src/common/features/definitions.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | import * as lsp from 'vscode-languageserver'; 7 | import { identifierAtPosition } from '../common'; 8 | import { DocumentStore } from '../documentStore'; 9 | import Languages from '../languages'; 10 | import { Trees } from '../trees'; 11 | import { Locals } from './locals'; 12 | import { SymbolIndex } from './symbolIndex'; 13 | 14 | export class DefinitionProvider { 15 | 16 | constructor( 17 | private readonly _documents: DocumentStore, 18 | private readonly _trees: Trees, 19 | private readonly _symbols: SymbolIndex 20 | ) { } 21 | 22 | register(connection: lsp.Connection) { 23 | connection.client.register(lsp.DefinitionRequest.type, { documentSelector: Languages.getSupportedLanguages('definitions', ['locals', 'outline']) }); 24 | connection.onRequest(lsp.DefinitionRequest.type, this.provideDefinitions.bind(this)); 25 | } 26 | 27 | async provideDefinitions(params: lsp.DefinitionParams): Promise { 28 | const document = await this._documents.retrieve(params.textDocument.uri); 29 | 30 | // find definition in file 31 | const info = await Locals.create(document, this._trees); 32 | const anchor = info.root.findDefinitionOrUsage(params.position); 33 | if (anchor) { 34 | // find definition inside this file 35 | const definitions = anchor.scope.findDefinitions(anchor.name); 36 | if (definitions.length > 0) { 37 | return definitions.map(def => lsp.Location.create(document.uri, def.range)); 38 | } 39 | } 40 | 41 | // find definition globally 42 | const tree = await this._trees.getParseTree(document); 43 | if (!tree) { 44 | return []; 45 | } 46 | 47 | const query = Languages.getQuery(tree.getLanguage(), 'identifiers'); 48 | const ident = identifierAtPosition(query, tree.rootNode, params.position)?.text; 49 | if (!ident) { 50 | // not an identifier 51 | return []; 52 | } 53 | 54 | const symbols = await this._symbols.getDefinitions(ident, document); 55 | return symbols.map(s => s.location); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /anycode/server/src/common/features/documentHighlights.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | import * as lsp from 'vscode-languageserver'; 7 | import { Trees } from '../trees'; 8 | import { DocumentStore } from '../documentStore'; 9 | import { Locals } from './locals'; 10 | import Languages from '../languages'; 11 | import { TextDocument } from 'vscode-languageserver-textdocument'; 12 | import { asLspRange, identifierAtPosition } from '../common'; 13 | 14 | export class DocumentHighlightsProvider { 15 | 16 | constructor( 17 | private readonly _documents: DocumentStore, 18 | private readonly _trees: Trees, 19 | ) { } 20 | 21 | register(connection: lsp.Connection) { 22 | connection.client.register(lsp.DocumentHighlightRequest.type, { documentSelector: Languages.getSupportedLanguages('highlights', ['locals', 'identifiers']) }); 23 | connection.onRequest(lsp.DocumentHighlightRequest.type, this.provideDocumentHighlights.bind(this)); 24 | } 25 | 26 | async provideDocumentHighlights(params: lsp.DocumentHighlightParams): Promise { 27 | const document = await this._documents.retrieve(params.textDocument.uri); 28 | 29 | const info = await Locals.create(document, this._trees); 30 | const anchor = info.root.findDefinitionOrUsage(params.position); 31 | if (!anchor) { 32 | return this._identifierBasedHighlights(document, params.position); 33 | } 34 | const result: lsp.DocumentHighlight[] = []; 35 | for (let def of anchor.scope.findDefinitions(anchor.name)) { 36 | result.push(lsp.DocumentHighlight.create(def.range, lsp.DocumentHighlightKind.Write)); 37 | } 38 | if (result.length === 0) { 39 | // needs a definition 40 | return this._identifierBasedHighlights(document, params.position); 41 | } 42 | for (let usage of anchor.scope.findUsages(anchor.name)) { 43 | result.push(lsp.DocumentHighlight.create(usage.range, lsp.DocumentHighlightKind.Read)); 44 | } 45 | return result; 46 | } 47 | 48 | private async _identifierBasedHighlights(document: TextDocument, position: lsp.Position): Promise { 49 | const result: lsp.DocumentHighlight[] = []; 50 | const tree = await this._trees.getParseTree(document); 51 | if (!tree) { 52 | return result; 53 | } 54 | 55 | const query = Languages.getQuery(tree.getLanguage(), 'identifiers'); 56 | const candidate = identifierAtPosition(query, tree.rootNode, position); 57 | if (!candidate) { 58 | // not on an identifier 59 | return result; 60 | } 61 | 62 | for (let capture of query.captures(tree.rootNode)) { 63 | // same node text, e.g foo vs bar 64 | if (capture.node.text === candidate.text) { 65 | result.push(lsp.DocumentHighlight.create(asLspRange(capture.node), lsp.DocumentHighlightKind.Text)); 66 | } 67 | } 68 | 69 | return result; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /anycode/server/src/common/features/documentSymbols.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | import * as lsp from 'vscode-languageserver'; 7 | import { TextDocument } from 'vscode-languageserver-textdocument'; 8 | import { QueryCapture } from 'web-tree-sitter'; 9 | import { asLspRange, containsRange, symbolMapping } from '../common'; 10 | import { DocumentStore } from '../documentStore'; 11 | import Languages from '../languages'; 12 | import { Trees } from '../trees'; 13 | 14 | export class DocumentSymbols { 15 | 16 | constructor(private readonly _documents: DocumentStore, private readonly _trees: Trees) { } 17 | 18 | register(connection: lsp.Connection) { 19 | connection.client.register(lsp.DocumentSymbolRequest.type, { documentSelector: Languages.getSupportedLanguages('outline', ['outline']) }); 20 | connection.onRequest(lsp.DocumentSymbolRequest.type, this.provideDocumentSymbols.bind(this)); 21 | } 22 | 23 | async provideDocumentSymbols(params: lsp.DocumentSymbolParams): Promise { 24 | const document = await this._documents.retrieve(params.textDocument.uri); 25 | return getDocumentSymbols(document, this._trees, false); 26 | } 27 | } 28 | 29 | export async function getDocumentSymbols(document: TextDocument, trees: Trees, flat: boolean): Promise { 30 | 31 | class Node { 32 | readonly range: lsp.Range; 33 | readonly children: Node[] = []; 34 | constructor(readonly capture: QueryCapture) { 35 | this.range = asLspRange(capture.node); 36 | } 37 | } 38 | 39 | const tree = await trees.getParseTree(document); 40 | if (!tree) { 41 | return []; 42 | } 43 | const query = Languages.getQuery(tree.getLanguage(), 'outline'); 44 | const captures = query.captures(tree.rootNode); 45 | 46 | 47 | // build a Node-tree that is based on range containment. This includes true 48 | // children as well as the "name-child" 49 | const roots: Node[] = []; 50 | const stack: Node[] = []; 51 | for (const capture of captures) { 52 | const node = new Node(capture); 53 | let parent = stack.pop(); 54 | while (true) { 55 | if (!parent) { 56 | roots.push(node); 57 | stack.push(node); 58 | break; 59 | } 60 | if (containsRange(parent.range, node.range)) { 61 | parent.children.push(node); 62 | stack.push(parent); 63 | stack.push(node); 64 | break; 65 | } 66 | parent = stack.pop(); 67 | } 68 | } 69 | 70 | // build DocumentSymbol-tree from Node-tree. Children of nodes that match 71 | // the `.name` capture name are used as identifier/name and aren't producing 72 | // a dedicated document symbol 73 | function build(node: Node, bucket: lsp.DocumentSymbol[]): void { 74 | let children: lsp.DocumentSymbol[] = []; 75 | let nameNode: Node | undefined; 76 | for (let child of node.children) { 77 | if (!nameNode && child.capture.name.endsWith('.name') && child.capture.name.startsWith(node.capture.name)) { 78 | nameNode = child; 79 | } else { 80 | build(child, children); 81 | } 82 | } 83 | if (!nameNode) { 84 | nameNode = node; 85 | } 86 | const symbol = lsp.DocumentSymbol.create(nameNode.capture.node.text, '', symbolMapping.getSymbolKind(node.capture.name), node.range, nameNode.range); 87 | symbol.children = children; 88 | 89 | bucket.push(symbol); 90 | } 91 | 92 | 93 | const result: lsp.DocumentSymbol[] = []; 94 | for (let node of roots) { 95 | build(node, result); 96 | } 97 | 98 | if (!flat) { 99 | return result; 100 | } 101 | 102 | const flatResult: lsp.DocumentSymbol[] = []; 103 | (function flatten(all: lsp.DocumentSymbol[]) { 104 | for (let item of all) { 105 | flatResult.push(item); 106 | if (item.children) { 107 | flatten(item.children); 108 | } 109 | } 110 | })(result); 111 | return flatResult; 112 | } 113 | -------------------------------------------------------------------------------- /anycode/server/src/common/features/foldingRanges.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | import * as lsp from 'vscode-languageserver'; 7 | import { Trees } from '../trees'; 8 | import { DocumentStore } from '../documentStore'; 9 | import Languages from '../languages'; 10 | 11 | export class FoldingRangeProvider { 12 | 13 | constructor(private _documents: DocumentStore, private _trees: Trees) { } 14 | 15 | register(connection: lsp.Connection) { 16 | connection.client.register(lsp.FoldingRangeRequest.type, { documentSelector: Languages.getSupportedLanguages('folding', ['comments', 'folding']) }); 17 | connection.onRequest(lsp.FoldingRangeRequest.type, this.provideFoldingRanges.bind(this)); 18 | } 19 | 20 | async provideFoldingRanges(params: lsp.FoldingRangeParams) { 21 | 22 | const document = await this._documents.retrieve(params.textDocument.uri); 23 | const tree = await this._trees.getParseTree(document); 24 | if (!tree) { 25 | return []; 26 | } 27 | 28 | const result: lsp.FoldingRange[] = []; 29 | const commentQuery = Languages.getQuery(tree.getLanguage(), 'comments'); 30 | const commentCaptures = commentQuery.captures(tree.rootNode); 31 | 32 | const foldingQuery = Languages.getQuery(tree.getLanguage(), 'folding'); 33 | const foldingCaptures = foldingQuery.captures(tree.rootNode); 34 | 35 | for (const capture of [commentCaptures, foldingCaptures].flat()) { 36 | result.push(lsp.FoldingRange.create( 37 | capture.node.startPosition.row, 38 | capture.node.endPosition.row, 39 | capture.node.startPosition.column, 40 | capture.node.endPosition.column, 41 | capture.name 42 | )); 43 | } 44 | return result; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /anycode/server/src/common/features/references.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | import * as lsp from 'vscode-languageserver'; 7 | import { TextDocument } from 'vscode-languageserver-textdocument'; 8 | import { asLspRange, containsPosition, identifierAtPosition } from '../common'; 9 | import { DocumentStore } from '../documentStore'; 10 | import Languages from '../languages'; 11 | import { Trees } from '../trees'; 12 | import { Locals } from './locals'; 13 | import { SymbolIndex } from './symbolIndex'; 14 | 15 | export class ReferencesProvider { 16 | 17 | constructor( 18 | private readonly _documents: DocumentStore, 19 | private readonly _trees: Trees, 20 | private readonly _symbols: SymbolIndex 21 | ) { } 22 | 23 | register(connection: lsp.Connection) { 24 | connection.client.register(lsp.ReferencesRequest.type, { documentSelector: Languages.getSupportedLanguages('references', ['locals', 'identifiers', 'references']) }); 25 | connection.onRequest(lsp.ReferencesRequest.type, this.provideReferences.bind(this)); 26 | } 27 | 28 | async provideReferences(params: lsp.ReferenceParams): Promise { 29 | const document = await this._documents.retrieve(params.textDocument.uri); 30 | 31 | // find references inside file 32 | const info = await Locals.create(document, this._trees); 33 | const anchor = info.root.findDefinitionOrUsage(params.position); 34 | 35 | if (anchor && !anchor.scope.likelyExports) { 36 | const definitions = anchor.scope.findDefinitions(anchor.name); 37 | if (definitions.length > 0) { 38 | const result: lsp.Location[] = []; 39 | for (let def of definitions) { 40 | if (params.context.includeDeclaration) { 41 | result.push(lsp.Location.create(document.uri, def.range)); 42 | } 43 | } 44 | const usages = anchor.scope.findUsages(anchor.name); 45 | for (let usage of usages) { 46 | result.push(lsp.Location.create(document.uri, usage.range)); 47 | } 48 | return result; 49 | } 50 | } 51 | 52 | // find references globally 53 | return await this._findGlobalReferences(document, params.position, params.context.includeDeclaration); 54 | 55 | } 56 | 57 | private async _findGlobalReferences(document: TextDocument, position: lsp.Position, includeDeclaration: boolean): Promise { 58 | const tree = await this._trees.getParseTree(document); 59 | if (!tree) { 60 | return []; 61 | } 62 | 63 | const query = Languages.getQuery(tree.getLanguage(), 'identifiers'); 64 | const ident = identifierAtPosition(query, tree.rootNode, position)?.text; 65 | if (!ident) { 66 | // not an identifier 67 | return []; 68 | } 69 | 70 | const result: lsp.Location[] = []; 71 | let seenAsUsage = false; 72 | let seenAsDef = false; 73 | 74 | const usages = await this._symbols.getUsages(ident, document); 75 | for (let usage of usages) { 76 | seenAsUsage = seenAsUsage || containsPosition(usage.range, position); 77 | result.push(usage); 78 | } 79 | 80 | const definitions = await this._symbols.getDefinitions(ident, document); 81 | for (const { location } of definitions) { 82 | seenAsDef = seenAsDef || containsPosition(location.range, position); 83 | if (includeDeclaration) { 84 | result.push(location); 85 | } 86 | } 87 | 88 | if (!seenAsUsage && !seenAsDef) { 89 | // flishy results because we didn't see the location at which we requested references 90 | return []; 91 | } 92 | 93 | return result; 94 | } 95 | } 96 | 97 | export interface IUsage { 98 | name: string; 99 | range: lsp.Range; 100 | kind: lsp.SymbolKind; 101 | } 102 | 103 | export async function getDocumentUsages(document: TextDocument, trees: Trees): Promise { 104 | const tree = await trees.getParseTree(document); 105 | if (!tree) { 106 | return []; 107 | } 108 | 109 | const query = Languages.getQuery(tree.getLanguage(), 'references'); 110 | const captures = query.captures(tree.rootNode); 111 | 112 | const result: IUsage[] = []; 113 | 114 | for (let capture of captures) { 115 | const name = capture.node.text; 116 | const range = asLspRange(capture.node); 117 | result.push({ 118 | name, 119 | range, 120 | kind: lsp.SymbolKind.File 121 | }); 122 | } 123 | 124 | return result; 125 | } 126 | -------------------------------------------------------------------------------- /anycode/server/src/common/features/selectionRanges.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | import type Parser from 'web-tree-sitter'; 7 | import * as lsp from 'vscode-languageserver'; 8 | import { asLspRange as asLspRange } from '../common'; 9 | import { Trees } from '../trees'; 10 | import { DocumentStore } from '../documentStore'; 11 | import Languages from '../languages'; 12 | 13 | export class SelectionRangesProvider { 14 | 15 | constructor(private _documents: DocumentStore, private _trees: Trees) { } 16 | 17 | register(connection: lsp.Connection) { 18 | connection.client.register(lsp.SelectionRangeRequest.type, { documentSelector: Languages.allAsSelector() }); 19 | connection.onRequest(lsp.SelectionRangeRequest.type, this.provideSelectionRanges.bind(this)); 20 | } 21 | 22 | async provideSelectionRanges(params: lsp.SelectionRangeParams) { 23 | 24 | const document = await this._documents.retrieve(params.textDocument.uri); 25 | const tree = await this._trees.getParseTree(document); 26 | if (!tree) { 27 | return []; 28 | } 29 | 30 | const result: lsp.SelectionRange[] = []; 31 | 32 | for (const position of params.positions) { 33 | const stack: Parser.SyntaxNode[] = []; 34 | const offset = document.offsetAt(position); 35 | 36 | let node = tree.rootNode; 37 | stack.push(node); 38 | 39 | while (true) { 40 | let child = node.namedChildren.find(candidate => { 41 | return candidate.startIndex <= offset && candidate.endIndex > offset; 42 | }); 43 | 44 | if (child) { 45 | stack.push(child); 46 | node = child; 47 | continue; 48 | } 49 | break; 50 | } 51 | 52 | let parent: lsp.SelectionRange | undefined; 53 | for (let node of stack) { 54 | let range = lsp.SelectionRange.create(asLspRange(node), parent); 55 | parent = range; 56 | } 57 | if (parent) { 58 | result.push(parent); 59 | } 60 | } 61 | 62 | return result; 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /anycode/server/src/common/features/validation.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | import { CancellationTokenSource, Connection, Diagnostic, DiagnosticSeverity } from 'vscode-languageserver'; 7 | import { TextDocument } from 'vscode-languageserver-textdocument'; 8 | import { asLspRange, isInteresting } from '../common'; 9 | import { DocumentStore } from '../documentStore'; 10 | import { Trees } from '../trees'; 11 | 12 | export class Validation { 13 | 14 | private readonly _currentValidation = new Map(); 15 | 16 | constructor( 17 | private readonly _connection: Connection, 18 | documents: DocumentStore, 19 | private readonly _trees: Trees 20 | ) { 21 | documents.all().forEach(this._triggerValidation, this); 22 | documents.onDidChangeContent(e => this._triggerValidation(e.document)); 23 | documents.onDidOpen(e => this._triggerValidation(e.document)); 24 | 25 | documents.onDidClose(e => { 26 | _connection.sendDiagnostics({ uri: e.document.uri, diagnostics: [] }); 27 | }); 28 | } 29 | 30 | private async _triggerValidation(document: TextDocument): Promise { 31 | if (!isInteresting(document.uri)) { 32 | // unsupported 33 | return; 34 | } 35 | 36 | const config: { diagnostics: boolean } = await this._connection.workspace.getConfiguration({ section: 'anycode', scopeUri: document.uri }); 37 | if (!config.diagnostics) { 38 | return; 39 | } 40 | 41 | // cancel pending validation 42 | let cts = this._currentValidation.get(document); 43 | cts?.cancel(); 44 | cts?.dispose(); 45 | 46 | // schedule new validation 47 | cts = new CancellationTokenSource(); 48 | this._currentValidation.set(document, cts); 49 | const handle = setTimeout(() => this._createDiagnostics(document), 500); 50 | cts.token.onCancellationRequested(() => clearTimeout(handle)); 51 | } 52 | 53 | private async _createDiagnostics(document: TextDocument): Promise { 54 | const tree = await this._trees.getParseTree(document); 55 | const diagnostics: Diagnostic[] = []; 56 | if (tree) { 57 | // find MISSING nodes (those that got auto-inserted) 58 | const cursor = tree.walk(); 59 | const seen = new Set(); 60 | try { 61 | let visitedChildren = false; 62 | while (true) { 63 | if (cursor.nodeIsMissing && !seen.has(cursor.nodeId)) { 64 | diagnostics.push({ 65 | range: asLspRange(cursor.currentNode()), 66 | message: `Expected '${cursor.nodeType}'`, 67 | severity: DiagnosticSeverity.Error, 68 | source: 'anycode', 69 | code: 'missing', 70 | }); 71 | seen.add(cursor.nodeId); 72 | } 73 | 74 | // depth first search 75 | if (!visitedChildren) { 76 | if (!cursor.gotoFirstChild()) { 77 | visitedChildren = true; 78 | } 79 | } 80 | if (visitedChildren) { 81 | if (cursor.gotoNextSibling()) { 82 | visitedChildren = false; 83 | } else if (cursor.gotoParent()) { 84 | visitedChildren = true; 85 | } else { 86 | break; 87 | } 88 | } 89 | } 90 | } finally { 91 | cursor.delete(); 92 | } 93 | 94 | // // find "generic" error nodes 95 | // let query: Parser.Query | undefined; 96 | // try { 97 | // query = tree.getLanguage().query('(ERROR) @error'); 98 | // const captures = query.captures(tree.rootNode); 99 | // for (let capture of captures) { 100 | // diags.push({ 101 | // range: asCodeRange(capture.node), 102 | // message: 'Error', 103 | // severity: vscode.DiagnosticSeverity.Error, 104 | // source: 'anycode', 105 | // code: 'error', 106 | // }); 107 | // } 108 | // } catch { 109 | // // ignore - parsing the query might fail 110 | // } finally { 111 | // query?.delete(); 112 | // } 113 | } 114 | 115 | this._connection.sendDiagnostics({ uri: document.uri, diagnostics }); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /anycode/server/src/common/features/workspaceSymbols.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | import * as lsp from 'vscode-languageserver'; 7 | import { DocumentStore } from '../documentStore'; 8 | import { Trees } from '../trees'; 9 | import { getDocumentSymbols } from './documentSymbols'; 10 | import { SymbolIndex } from './symbolIndex'; 11 | 12 | export class WorkspaceSymbol { 13 | 14 | constructor( 15 | private readonly _documents: DocumentStore, 16 | private readonly _trees: Trees, 17 | private readonly _symbols: SymbolIndex 18 | ) { } 19 | 20 | register(connection: lsp.Connection) { 21 | connection.client.register(lsp.WorkspaceSymbolRequest.type, { resolveProvider: true }); 22 | connection.onRequest(lsp.WorkspaceSymbolRequest.type, this.provideWorkspaceSymbols.bind(this)); 23 | connection.onRequest(lsp.WorkspaceSymbolResolveRequest.type, this.resolveWorkspaceSymbol.bind(this)); 24 | } 25 | 26 | async provideWorkspaceSymbols(params: lsp.WorkspaceSymbolParams): Promise { 27 | const result: lsp.WorkspaceSymbol[] = []; 28 | 29 | await Promise.race([ 30 | this._symbols.update(), 31 | new Promise(resolve => setTimeout(resolve, 250)) 32 | ]); 33 | 34 | const all = this._symbols.index.query(params.query); 35 | 36 | out: for (const [name, map] of all) { 37 | for (const [uri, info] of map) { 38 | for (const kind of info.definitions) { 39 | const newLen = result.push(lsp.WorkspaceSymbol.create(name, kind, uri, lsp.Range.create(0, 0, 0, 0))); 40 | if (newLen > 20_000) { 41 | break out; 42 | } 43 | } 44 | } 45 | } 46 | 47 | return result; 48 | } 49 | 50 | async resolveWorkspaceSymbol(item: lsp.WorkspaceSymbol): Promise { 51 | // TODO@jrieken handle the case where a file has multiple symbols with the same name _and_ kind 52 | const document = await this._documents.retrieve(item.location.uri); 53 | const symbols = await getDocumentSymbols(document, this._trees, true); 54 | for (let candidate of symbols) { 55 | if (candidate.name === item.name && candidate.kind === item.kind) { 56 | return lsp.SymbolInformation.create(item.name, item.kind, candidate.selectionRange, item.location.uri); 57 | } 58 | } 59 | return item; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /anycode/server/src/common/languages.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | import Parser, { Language } from 'web-tree-sitter'; 7 | import { decodeBase64 } from '../../../shared/common/base64'; 8 | import { FeatureConfig, LanguageConfiguration, LanguageData } from '../../../shared/common/initOptions'; 9 | 10 | export type QueryModule = { 11 | outline?: string; 12 | comments?: string; 13 | folding?: string; 14 | locals?: string; 15 | identifiers?: string; 16 | references?: string; 17 | }; 18 | 19 | export type QueryType = keyof QueryModule; 20 | 21 | const _queryModules = new Map(); 22 | 23 | interface LanguageFuture { 24 | promise: Promise; 25 | resolve(language: Promise): void; 26 | } 27 | 28 | export default abstract class Languages { 29 | 30 | private static readonly _languageInstances = new Map(); 31 | private static readonly _languageIdByLanguage = new Map(); 32 | 33 | private static readonly _queryInstances = new Map(); 34 | 35 | private static readonly _configurations = new Map(); 36 | private static _langConfiguration: LanguageConfiguration; 37 | 38 | static init(langConfiguration: LanguageConfiguration): void { 39 | this._langConfiguration = langConfiguration; 40 | for (const [entry, config] of langConfiguration) { 41 | this._configurations.set(entry.languageId, config); 42 | 43 | let resolve: (p: Promise) => void = () => { }; 44 | let promise = new Promise((_resolve) => { 45 | resolve = async p => { 46 | let language: Language | undefined; 47 | try { 48 | language = await p; 49 | } catch (err) { 50 | console.error(`FAILED to load grammar for language ${entry.languageId}`); 51 | console.error(err); 52 | } 53 | 54 | if (language) { 55 | this._languageIdByLanguage.set(language, entry.languageId); 56 | _resolve(language); 57 | } else { 58 | this._languageInstances.delete(entry.languageId); 59 | _resolve(undefined); 60 | } 61 | }; 62 | }); 63 | this._languageInstances.set(entry.languageId, { promise, resolve }); 64 | } 65 | } 66 | 67 | static setLanguageData(languageId: string, data: LanguageData) { 68 | 69 | // set language instance 70 | const future = this._languageInstances.get(languageId); 71 | future?.resolve(Parser.Language.load(decodeBase64(data.grammarBase64))); 72 | 73 | // set queries 74 | _queryModules.set(languageId, data.queries); 75 | } 76 | 77 | static async getLanguage(languageId: string): Promise { 78 | let infoOrLanguage = this._languageInstances.get(languageId); 79 | if (infoOrLanguage === undefined) { 80 | console.warn(`UNKNOWN languages: '${languageId}'`); 81 | return undefined; 82 | } 83 | return infoOrLanguage.promise; 84 | } 85 | 86 | static allAsSelector(): string[] { 87 | return [...this._languageInstances.keys()]; 88 | } 89 | 90 | static getQuery(language: Language, type: QueryType, strict = false): Parser.Query { 91 | 92 | const languageId = this._languageIdByLanguage.get(language)!; 93 | const module = _queryModules.get(languageId); 94 | if (!module) { 95 | // unknown language or invalid query (deleted after failed parse attempt) 96 | return language.query(''); 97 | } 98 | 99 | const source = module[type] ?? ''; 100 | const key = `${languageId}/${type}`; 101 | 102 | let query = this._queryInstances.get(key); 103 | if (!query) { 104 | try { 105 | query = language.query(source); 106 | } catch (e) { 107 | query = language.query(''); 108 | console.error(languageId, e); 109 | console.log(language); 110 | if (strict) { 111 | throw e; 112 | } 113 | } 114 | this._queryInstances.set(key, query); 115 | } 116 | return query; 117 | } 118 | 119 | static getSupportedLanguages(feature: keyof FeatureConfig, types: QueryType[]): string[] { 120 | const result: string[] = []; 121 | for (const [info] of this._langConfiguration) { 122 | for (const type of types) { 123 | if (info.queryInfo[type] && this._configurations.get(info.languageId)?.[feature]) { 124 | result.push(info.languageId); 125 | break; 126 | } 127 | } 128 | } 129 | return result; 130 | } 131 | 132 | static getLanguageIdByUri(uri: string): string { 133 | let end = uri.lastIndexOf('?'); 134 | if (end < 0) { 135 | end = uri.lastIndexOf('#'); 136 | } 137 | if (end > 0) { 138 | uri = uri.substring(0, end); 139 | } 140 | const start = uri.lastIndexOf('.'); 141 | const suffix = uri.substring(start + 1); 142 | for (let [info] of this._langConfiguration) { 143 | for (let candidate of info.suffixes) { 144 | if (candidate === suffix) { 145 | return info.languageId; 146 | } 147 | } 148 | } 149 | return `unknown/${uri}`; 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /anycode/server/src/common/server.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | import { Connection, FileChangeType, InitializeParams, InitializeResult, TextDocumentSyncKind } from 'vscode-languageserver'; 7 | import Parser from 'web-tree-sitter'; 8 | import type { InitOptions, LanguageData, LanguageInfo } from '../../../shared/common/initOptions'; 9 | import { CustomMessages } from '../../../shared/common/messages'; 10 | import { DocumentStore } from './documentStore'; 11 | import { CompletionItemProvider } from './features/completions'; 12 | import { DefinitionProvider } from './features/definitions'; 13 | import { DocumentHighlightsProvider } from './features/documentHighlights'; 14 | import { DocumentSymbols } from './features/documentSymbols'; 15 | import { FoldingRangeProvider } from './features/foldingRanges'; 16 | import { ReferencesProvider } from './features/references'; 17 | import { SelectionRangesProvider } from './features/selectionRanges'; 18 | import { SymbolInfoStorage, SymbolIndex } from './features/symbolIndex'; 19 | import { Validation } from './features/validation'; 20 | import { WorkspaceSymbol } from './features/workspaceSymbols'; 21 | import Languages from './languages'; 22 | import { Trees } from './trees'; 23 | 24 | export interface IStorageFactory { 25 | create(name: string): Promise 26 | destroy(index: SymbolInfoStorage): Promise 27 | } 28 | 29 | export function startServer(connection: Connection, factory: IStorageFactory) { 30 | 31 | // patch console.log/warn/error calls 32 | console.log = connection.console.log.bind(connection.console); 33 | console.warn = connection.console.warn.bind(connection.console); 34 | console.error = connection.console.error.bind(connection.console); 35 | 36 | const features: { register(connection: Connection): any }[] = []; 37 | 38 | connection.onInitialize(async (params: InitializeParams): Promise => { 39 | 40 | const initData = params.initializationOptions; 41 | 42 | // init tree sitter and languages before doing anything else 43 | const options: object | undefined = { 44 | locateFile() { 45 | return initData.treeSitterWasmUri; 46 | } 47 | }; 48 | try { 49 | await Parser.init(options); 50 | } catch (e) { 51 | console.error('FAILED to initialize tree-sitter'); 52 | console.error(typeof e); 53 | console.error(e); 54 | throw e; 55 | } 56 | Languages.init(initData.supportedLanguages); 57 | 58 | // setup features 59 | const documents = new DocumentStore(connection); 60 | const trees = new Trees(documents); 61 | 62 | // caching 63 | const symbolStorage = await factory.create(initData.databaseName); 64 | connection.onExit(() => factory.destroy(symbolStorage)); 65 | 66 | const symbolIndex = new SymbolIndex(trees, documents, symbolStorage); 67 | 68 | features.push(new WorkspaceSymbol(documents, trees, symbolIndex)); 69 | features.push(new DefinitionProvider(documents, trees, symbolIndex)); 70 | features.push(new ReferencesProvider(documents, trees, symbolIndex)); 71 | features.push(new CompletionItemProvider(documents, trees, symbolIndex)); 72 | features.push(new DocumentHighlightsProvider(documents, trees)); 73 | features.push(new DocumentSymbols(documents, trees)); 74 | features.push(new SelectionRangesProvider(documents, trees)); 75 | features.push(new FoldingRangeProvider(documents, trees)); 76 | new Validation(connection, documents, trees); 77 | 78 | // manage symbol index. add/remove files as they are disovered and edited 79 | documents.all().forEach(doc => symbolIndex.addFile(doc.uri)); 80 | documents.onDidOpen(event => symbolIndex.addFile(event.document.uri)); 81 | documents.onDidChangeContent(event => symbolIndex.addFile(event.document.uri)); 82 | 83 | connection.onRequest(CustomMessages.QueueInit, uris => { 84 | symbolIndex.initFiles(uris); 85 | }); 86 | 87 | connection.onRequest(CustomMessages.QueueUnleash, async (arg: [LanguageInfo, LanguageData]) => { 88 | const [info, data] = arg; 89 | console.log(`[index] unleashed files matching: ${info.languageId}`); 90 | Languages.setLanguageData(info.languageId, data); 91 | symbolIndex.unleashFiles(info.suffixes); 92 | }); 93 | 94 | connection.onDidChangeWatchedFiles(e => { 95 | for (const { type, uri } of e.changes) { 96 | switch (type) { 97 | case FileChangeType.Created: 98 | symbolIndex.addFile(uri); 99 | break; 100 | case FileChangeType.Deleted: 101 | symbolIndex.removeFile(uri); 102 | documents.removeFile(uri); 103 | break; 104 | case FileChangeType.Changed: 105 | symbolIndex.addFile(uri); 106 | documents.removeFile(uri); 107 | break; 108 | } 109 | } 110 | }); 111 | 112 | return { 113 | capabilities: { textDocumentSync: TextDocumentSyncKind.Incremental } 114 | }; 115 | }); 116 | 117 | connection.onInitialized(() => { 118 | for (let feature of features) { 119 | feature.register(connection); 120 | } 121 | }); 122 | 123 | connection.listen(); 124 | } 125 | -------------------------------------------------------------------------------- /anycode/server/src/common/test-fixture/client/documentHighlights.test.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | import assert from 'assert'; 7 | import { DocumentHighlight } from 'vscode-languageserver-types'; 8 | import { compareRangeByStart } from '../../common'; 9 | import { DocumentHighlightsProvider } from '../../features/documentHighlights'; 10 | import { Trees } from '../../trees'; 11 | import { Fixture, TestDocumentStore } from './utils'; 12 | 13 | export async function init(fixture: string, langId: string) { 14 | 15 | const fixtures = await Fixture.parse(fixture, langId); 16 | 17 | suite(`DocumentHighlights - Fixtures: ${langId}`, function () { 18 | // debugger; 19 | const store = new TestDocumentStore(...fixtures.map(f => f.document)); 20 | 21 | for (let item of fixtures) { 22 | test(item.name, async function () { 23 | const trees = new Trees(store); 24 | const symbols = new DocumentHighlightsProvider(store, trees); 25 | const result = await symbols.provideDocumentHighlights({ 26 | textDocument: { uri: item.document.uri }, 27 | position: item.document.positionAt(item.marks[0].start) 28 | }); 29 | assertDocumentHighlights(item, result); 30 | trees.dispose(); 31 | }); 32 | } 33 | }); 34 | } 35 | 36 | function assertDocumentHighlights(fixture: Fixture, actual: DocumentHighlight[]) { 37 | 38 | actual.sort((a, b) => compareRangeByStart(a.range, b.range)); 39 | 40 | if (actual.length === 0) { 41 | assert.fail('NO symbols found: ' + fixture.name); 42 | } 43 | 44 | for (let highlight of actual) { 45 | const e = fixture.marks.shift(); 46 | assert.ok(e, `${fixture.name}: MISSING hightlight`); 47 | assert.strictEqual(fixture.document.offsetAt(highlight.range.start), e.start, `${fixture.name}: BAD start range`); 48 | } 49 | 50 | if (fixture.marks.length > 0) { 51 | assert.fail('not ALL MARKS seen: ' + fixture.name); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /anycode/server/src/common/test-fixture/client/documentSymbols.test.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | import assert from 'assert'; 7 | import { DocumentSymbol } from 'vscode-languageserver-types'; 8 | import { DocumentSymbols } from '../../features/documentSymbols'; 9 | import { Trees } from '../../trees'; 10 | import { Fixture, TestDocumentStore } from './utils'; 11 | 12 | export async function init(fixture: string, langId: string) { 13 | 14 | const fixtures = await Fixture.parse(fixture, langId); 15 | 16 | suite(`DocumentSymbols - Fixtures: ${langId}`, function () { 17 | 18 | const store = new TestDocumentStore(...fixtures.map(f => f.document)); 19 | 20 | for (let item of fixtures) { 21 | test(item.name, async function () { 22 | const trees = new Trees(store); 23 | const symbols = new DocumentSymbols(store, trees); 24 | const result = await symbols.provideDocumentSymbols({ textDocument: { uri: item.document.uri } }); 25 | assertDocumentSymbols(item, result); 26 | trees.dispose(); 27 | }); 28 | } 29 | }); 30 | } 31 | 32 | 33 | function assertDocumentSymbols(fixture: Fixture, actual: DocumentSymbol[]) { 34 | 35 | if (actual.length === 0) { 36 | assert.fail('NO symbols found'); 37 | } 38 | 39 | (function walk(symbols: DocumentSymbol[]) { 40 | for (let symbol of symbols) { 41 | const expected = fixture.marks.shift(); 42 | assert.ok(expected, `symbol NOT expected: ${symbol.name}@${symbol.range.start.line},${symbol.range.start.character}`); 43 | assert.strictEqual(symbol.name, expected.text); 44 | assert.strictEqual(fixture.document.offsetAt(symbol.selectionRange.start), expected.start); 45 | if (symbol.children) { 46 | walk(symbol.children); 47 | } 48 | } 49 | })(actual); 50 | 51 | if (fixture.marks.length > 0) { 52 | assert.fail(`also EXPECTED ${fixture.marks.map(e => e.text)}`); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /anycode/server/src/common/test-fixture/client/queries.test.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | import assert from 'assert'; 7 | import { LanguageInfo } from '../../../../../shared/common/initOptions'; 8 | import Languages, { QueryType } from '../../languages'; 9 | 10 | export function init(info: LanguageInfo) { 11 | if (!info.queryInfo) { 12 | return; 13 | } 14 | 15 | suite(`Queries ${info.languageId}`, function () { 16 | const types: QueryType[] = ['comments', 'folding', 'identifiers', 'locals', 'outline', 'references']; 17 | for (let type of types) { 18 | test(type, async function () { 19 | 20 | if (!info.queryInfo![type]) { 21 | this.skip(); 22 | } 23 | 24 | try { 25 | const language = await Languages.getLanguage(info.languageId); 26 | const q = Languages.getQuery(language, type, true); 27 | assert.ok(q); 28 | } catch (err) { 29 | assert.fail(`INVALID ${info.languageId} -> ${err}`); 30 | } 31 | }); 32 | } 33 | }); 34 | } 35 | -------------------------------------------------------------------------------- /anycode/server/src/common/test-fixture/client/test.all.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | import * as documentHighlights from './documentHighlights.test'; 7 | import * as documentSymbols from './documentSymbols.test'; 8 | import * as queries from './queries.test'; 9 | import Parser from 'web-tree-sitter'; 10 | import Languages from '../../languages'; 11 | import { FeatureConfig, LanguageData, LanguageInfo } from '../../../../../shared/common/initOptions'; 12 | import { encodeBase64 } from '../../../../../shared/common/base64'; 13 | 14 | (async function () { 15 | 16 | try { 17 | 18 | await Parser.init({ 19 | locateFile() { 20 | return '/anycode/server/node_modules/web-tree-sitter/tree-sitter.wasm'; 21 | } 22 | }); 23 | 24 | const config: [LanguageInfo, FeatureConfig][] = []; 25 | 26 | // @ts-expect-error 27 | const target = new URL(window.location); 28 | const langInfo: LanguageInfo[] = JSON.parse(target.searchParams.get('languages') ?? ""); 29 | 30 | for (let info of langInfo) { 31 | config.push([info, {}]); 32 | queries.init(info); 33 | } 34 | 35 | Languages.init(config); 36 | 37 | for (let info of langInfo) { 38 | const data = await fetch((info).wasmUri); 39 | const base64 = encodeBase64(new Uint8Array(await data.arrayBuffer())); 40 | Languages.setLanguageData(info.languageId, new LanguageData(base64, info.queryInfo)); 41 | } 42 | 43 | const outline = target.searchParams.get('outline'); 44 | if (outline) { 45 | const langId = Languages.getLanguageIdByUri(outline); 46 | await documentSymbols.init(outline, langId); 47 | } 48 | 49 | const highlights = target.searchParams.get('highlights'); 50 | if (highlights) { 51 | const langId = Languages.getLanguageIdByUri(highlights); 52 | await documentHighlights.init(highlights, langId); 53 | } 54 | 55 | run(); // MOCHA-delayed run 56 | 57 | } catch (err) { 58 | // @ts-expect-error 59 | window.report_mocha_done(err); 60 | console.error(err); 61 | } 62 | })(); 63 | -------------------------------------------------------------------------------- /anycode/server/src/common/test-fixture/client/test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Mocha Tests 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 21 | 22 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /anycode/server/src/common/test-fixture/client/utils.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | import Languages from '../../languages'; 7 | import * as lsp from "vscode-languageserver"; 8 | import { DocumentStore } from "../../documentStore"; 9 | import { TextDocument } from 'vscode-languageserver-textdocument'; 10 | import { Trees } from '../../trees'; 11 | 12 | export function mock(): { new(): T } { 13 | return function () { } as any; 14 | } 15 | 16 | export class TestDocumentStore extends DocumentStore { 17 | 18 | constructor(...docs: TextDocument[]) { 19 | super( 20 | new class extends mock() { 21 | onDidOpenTextDocument(handler: lsp.NotificationHandler) { 22 | for (let doc of docs) { 23 | handler({ 24 | textDocument: { 25 | languageId: doc.languageId, 26 | uri: doc.uri, 27 | text: doc.getText(), 28 | version: doc.version 29 | } 30 | }); 31 | } 32 | } 33 | onDidChangeTextDocument() { } 34 | onDidCloseTextDocument() { } 35 | onWillSaveTextDocument() { } 36 | onWillSaveTextDocumentWaitUntil() { } 37 | onDidSaveTextDocument() { } 38 | onNotification() { } 39 | } 40 | ); 41 | } 42 | } 43 | 44 | export class FixtureMarks { 45 | 46 | static readonly pattern = /\[\[[^\]]+\]\]/g; 47 | 48 | constructor( 49 | readonly start: number, 50 | readonly text: string 51 | ) { } 52 | } 53 | 54 | export class Fixture { 55 | 56 | static async parse(uri: string, languageId: string) { 57 | 58 | const res = await fetch(uri); 59 | const text = await res.text(); 60 | 61 | const r = /.+###.*/gu; 62 | const names = text.match(r); 63 | const documents = text.split(r) 64 | .filter(Boolean) 65 | .map((value, i) => TextDocument.create(`${uri}#${i}`, languageId, 1, value)); 66 | 67 | const store = new TestDocumentStore(...documents); 68 | const trees = new Trees(store); 69 | 70 | const fixtures: Fixture[] = []; 71 | 72 | for (const doc of documents) { 73 | const tree = await trees.getParseTree(doc); 74 | if (!tree) { 75 | throw new Error(); 76 | } 77 | const query = Languages.getQuery(tree.getLanguage(), 'comments', true); 78 | 79 | const name = names?.shift()?.replace(/^.+###/, '').trim() ?? doc.uri; 80 | if (name.includes('/SKIP/')) { 81 | continue; 82 | } 83 | 84 | const marks: FixtureMarks[] = []; 85 | const captures = query.captures(tree.rootNode); 86 | 87 | for (const capture of captures) { 88 | const start = capture.node.text.indexOf('^'); 89 | if (start < 0) { 90 | continue; 91 | } 92 | 93 | const end = capture.node.text.lastIndexOf('^'); 94 | 95 | for (let row = capture.node.startPosition.row - 1; row >= 0; row--) { 96 | let node = tree.rootNode.descendantForPosition({ row, column: start }, { row, column: end }); 97 | if (query.captures(node).length > 0) { 98 | // skip stacked comments 99 | continue; 100 | } 101 | marks.push(new FixtureMarks(node.startIndex, node.text)); 102 | break; 103 | } 104 | } 105 | 106 | fixtures.push(new Fixture(name, doc, marks)); 107 | } 108 | 109 | trees.dispose(); 110 | return fixtures; 111 | } 112 | 113 | constructor( 114 | readonly name: string, 115 | readonly document: TextDocument, 116 | readonly marks: FixtureMarks[] 117 | ) { } 118 | }; 119 | -------------------------------------------------------------------------------- /anycode/server/src/common/test-fixture/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2021", 4 | "types": [ 5 | "node" 6 | ] 7 | }, 8 | "include": [ 9 | "test.js" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /anycode/server/src/common/test-fixture/test.js: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | //@ts-check 7 | 8 | const { readFileSync } = require('fs'); 9 | const http = require('http'); 10 | const { join, relative } = require('path') 11 | const { chromium } = require('playwright'); 12 | 13 | const args = (function () { 14 | const result = Object.create(null) 15 | let key = '' 16 | for (let arg of process.argv.slice(2)) { 17 | 18 | if (arg.startsWith('--')) { 19 | key = arg.slice(2) 20 | result[key] = true; 21 | } else if (key) { 22 | let value = result[key]; 23 | if (value === true) { 24 | result[key] = arg; 25 | } else if (Array.isArray(value)) { 26 | value.push(arg) 27 | } else { 28 | result[key] = [value, arg]; 29 | } 30 | key = '' 31 | 32 | } else { 33 | console.warn(`INVALID arg ${arg}`) 34 | } 35 | } 36 | 37 | 38 | return result; 39 | })() 40 | 41 | const base = join(__dirname, '../../../../..'); 42 | const port = 3000 + Math.ceil(Math.random() * 5080); 43 | 44 | /** 45 | * @param {string} candidate 46 | * @returns {any[]} 47 | */ 48 | function readAnycodeExtension(candidate) { 49 | let data; 50 | try { 51 | data = JSON.parse(readFileSync(candidate).toString()); 52 | } catch (err) { 53 | console.warn(err) 54 | return []; 55 | } 56 | 57 | let languages = data?.contributes?.['anycodeLanguages'] 58 | if (!languages) { 59 | return []; 60 | } 61 | 62 | if (!Array.isArray(languages)) { 63 | languages = [languages] 64 | } 65 | const bucket = [] 66 | 67 | for (let lang of languages) { 68 | let queryInfo = {}; 69 | for (let prop in lang.queryPaths) { 70 | const query = join(candidate, '../', lang.queryPaths[prop]) 71 | queryInfo[prop] = readFileSync(query).toString(); 72 | } 73 | 74 | bucket.push({ 75 | languageId: lang.languageId, 76 | wasmUri: `/${relative(base, join(candidate, '../', lang.grammarPath))}`, 77 | suffixes: lang.extensions, 78 | queryInfo 79 | }) 80 | } 81 | return bucket; 82 | } 83 | 84 | const requestListener = function (req, res) { 85 | const relative = req.url.replace(/\?.*$/, '') 86 | const path = join(base, relative); 87 | 88 | try { 89 | const buffer = readFileSync(path) 90 | res.writeHead(200); 91 | res.end(buffer); 92 | } catch (err) { 93 | // console.error(err); 94 | res.writeHead(404); 95 | res.end(); 96 | } 97 | }; 98 | 99 | async function runTests() { 100 | 101 | const target = new URL(`http://localhost:${port}/anycode/server/src/common/test-fixture/client/test.html`); 102 | 103 | const languages = readAnycodeExtension(join(process.cwd(), 'package.json')) 104 | target.searchParams.set('languages', JSON.stringify(languages)); 105 | 106 | if (typeof args['outline'] === 'string') { 107 | const outlinePath = join(process.cwd(), args['outline']) 108 | target.searchParams.set('outline', `/${relative(base, outlinePath)}`); 109 | } 110 | if (typeof args['highlights'] === 'string') { 111 | const highlightsPath = join(process.cwd(), args['highlights']) 112 | target.searchParams.set('highlights', `/${relative(base, highlightsPath)}`); 113 | } 114 | 115 | const server = http.createServer(requestListener); 116 | server.on('error', (err) => { 117 | console.error(err) 118 | process.exit(1) 119 | }) 120 | 121 | await new Promise(resolve => server.listen(port, undefined, undefined, () => resolve())); 122 | 123 | console.log(`test server LISTENS on port ${port}`) 124 | 125 | const browser = await chromium.launch({ 126 | headless: !args.debug, 127 | devtools: !!args.debug, 128 | args: [ 129 | '--disable-web-security', 130 | ] 131 | }); 132 | 133 | const context = await browser.newContext(); 134 | const page = await context.newPage(); 135 | 136 | const mochaDone = new Promise((resolve, reject) => { 137 | page.exposeFunction('report_mocha_done', (/** @type {number|string} */ failCount) => { 138 | resolve(failCount) 139 | }) 140 | if (!args.debug) { 141 | setTimeout(() => reject('TIMEOUT'), 15000); 142 | } 143 | }) 144 | 145 | await page.goto(target.href); 146 | 147 | const failCount = await mochaDone; 148 | 149 | if (args.debug) { 150 | return; 151 | } 152 | 153 | if (failCount > 0) { 154 | console.error(`${failCount} FAILURES`) 155 | } else { 156 | console.log('all good') 157 | } 158 | page.close(); 159 | server.close(); 160 | process.exit(failCount) 161 | 162 | }; 163 | 164 | runTests().catch(err => { 165 | console.error('FAIL', err); 166 | process.exit(1) 167 | }); 168 | -------------------------------------------------------------------------------- /anycode/server/src/common/test/trie.test.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | import assert from 'assert'; 7 | import { Trie } from '../util/trie'; 8 | 9 | suite('Trie', function () { 10 | 11 | function assertKeys(trie: Trie, keys: string[]) { 12 | const actual: string[] = []; 13 | for (let item of trie) { 14 | actual.push(item[0]); 15 | } 16 | assert.deepStrictEqual(actual, keys); 17 | } 18 | 19 | test('set/get/delete', function () { 20 | const trie = Trie.create(); 21 | trie.set('aa', true); 22 | trie.set('aaa', true); 23 | trie.set('foo', true); 24 | 25 | assertKeys(trie, ['aa', 'aaa', 'foo']); 26 | 27 | trie.set('Foo', true); 28 | trie.set('Foooo', true); 29 | assertKeys(trie, ['aa', 'aaa', 'foo', 'Foo', 'Foooo']); 30 | 31 | trie.delete('aa'); 32 | assertKeys(trie, ['aaa', 'foo', 'Foo', 'Foooo']); 33 | 34 | trie.delete('Foooo'); 35 | assertKeys(trie, ['aaa', 'foo', 'Foo']); 36 | }); 37 | 38 | test('depth', function () { 39 | 40 | const trie = Trie.create(); 41 | 42 | trie.set('aa', true); 43 | assert.strictEqual(trie.depth, 2); 44 | 45 | trie.set('foo', true); 46 | assert.strictEqual(trie.depth, 3); 47 | 48 | assert.ok(trie.delete('foo')); 49 | assert.strictEqual(trie.depth, 2); 50 | 51 | trie.set('aaaa', true); 52 | assert.strictEqual(trie.depth, 4); 53 | 54 | assert.ok(trie.delete('aa')); 55 | assert.strictEqual(trie.depth, 4); 56 | 57 | trie.set('aaa', true); 58 | assert.strictEqual(trie.depth, 4); 59 | 60 | assert.ok(trie.delete('aaaa')); 61 | assert.strictEqual(trie.depth, 3); 62 | 63 | assertKeys(trie, ['aaa']); 64 | }); 65 | 66 | test('query', function () { 67 | const trie = Trie.create(); 68 | trie.set('foo', true); 69 | trie.set('Foo', true); 70 | trie.set('barFoo', true); 71 | 72 | let arr = Array.from(trie.query(Array.from('fo'))); 73 | assert.strictEqual(arr.length, 3); 74 | assert.strictEqual(arr[0][0], 'foo'); 75 | assert.strictEqual(arr[1][0], 'Foo'); 76 | assert.strictEqual(arr[2][0], 'barFoo'); 77 | 78 | arr = Array.from(trie.query(Array.from('b'))); 79 | assert.strictEqual(arr.length, 1); 80 | 81 | arr = Array.from(trie.query(Array.from('foobar'))); 82 | assert.strictEqual(arr.length, 0); 83 | }); 84 | }); 85 | -------------------------------------------------------------------------------- /anycode/server/src/common/trees.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | import { LRUMap } from "./util/lruMap"; 7 | import Parser, { Language } from 'web-tree-sitter'; 8 | import { Disposable, Position } from 'vscode-languageserver'; 9 | import { TextDocument } from 'vscode-languageserver-textdocument'; 10 | import { DocumentStore, TextDocumentChange2 } from './documentStore'; 11 | import Languages from "./languages"; 12 | 13 | class Entry { 14 | constructor( 15 | public version: number, 16 | public tree: Parser.Tree, 17 | public edits: Parser.Edit[][] 18 | ) { } 19 | } 20 | 21 | export class Trees { 22 | 23 | private readonly _cache = new LRUMap({ 24 | size: 100, 25 | dispose(entries) { 26 | for (let [, value] of entries) { 27 | value.tree.delete(); 28 | } 29 | } 30 | }); 31 | 32 | private readonly _listener: Disposable[] = []; 33 | private readonly _parser = new Parser(); 34 | 35 | constructor(private readonly _documents: DocumentStore) { 36 | 37 | // build edits when document changes 38 | this._listener.push(_documents.onDidChangeContent2(e => { 39 | const info = this._cache.get(e.document.uri); 40 | if (info) { 41 | info.edits.push(Trees._asEdits(e)); 42 | } 43 | })); 44 | } 45 | 46 | dispose(): void { 47 | this._parser.delete(); 48 | for (let item of this._cache.values()) { 49 | item.tree.delete(); 50 | } 51 | for (let item of this._listener) { 52 | item.dispose(); 53 | } 54 | } 55 | 56 | // --- tree/parse 57 | 58 | async getParseTree(documentOrUri: TextDocument | string): Promise { 59 | if (typeof documentOrUri === 'string') { 60 | documentOrUri = await this._documents.retrieve(documentOrUri); 61 | } 62 | const language = await Languages.getLanguage(documentOrUri.languageId); 63 | if (!language) { 64 | return undefined; 65 | } 66 | return this._parse(documentOrUri, language); 67 | } 68 | 69 | private _parse(documentOrUri: TextDocument, language: Language): Parser.Tree | undefined { 70 | 71 | let info = this._cache.get(documentOrUri.uri); 72 | if (info?.version === documentOrUri.version) { 73 | return info.tree; 74 | } 75 | 76 | this._parser.setLanguage(language); 77 | this._parser.setTimeoutMicros(1000 * 1000); // parse max 1sec 78 | 79 | try { 80 | const version = documentOrUri.version; 81 | const text = documentOrUri.getText(); 82 | 83 | if (!info) { 84 | // never seen before, parse fresh 85 | const tree = this._parser.parse(text); 86 | info = new Entry(version, tree, []); 87 | this._cache.set(documentOrUri.uri, info); 88 | 89 | } else { 90 | // existing entry, apply deltas and parse incremental 91 | const oldTree = info.tree; 92 | const deltas = info.edits.flat(); 93 | deltas.forEach(delta => oldTree.edit(delta)); 94 | info.edits.length = 0; 95 | 96 | info.tree = this._parser.parse(text, oldTree); 97 | info.version = version; 98 | oldTree.delete(); 99 | } 100 | 101 | return info.tree; 102 | 103 | } catch (e) { 104 | this._cache.delete(documentOrUri.uri); 105 | return undefined; 106 | } 107 | } 108 | 109 | private static _asEdits(event: TextDocumentChange2): Parser.Edit[] { 110 | return event.changes.map(change => ({ 111 | startPosition: this._asTsPoint(change.range.start), 112 | oldEndPosition: this._asTsPoint(change.range.end), 113 | newEndPosition: this._asTsPoint(event.document.positionAt(change.rangeOffset + change.text.length)), 114 | startIndex: change.rangeOffset, 115 | oldEndIndex: change.rangeOffset + change.rangeLength, 116 | newEndIndex: change.rangeOffset + change.text.length 117 | })); 118 | } 119 | 120 | private static _asTsPoint(position: Position): Parser.Point { 121 | const { line: row, character: column } = position; 122 | return { row, column }; 123 | } 124 | }; 125 | -------------------------------------------------------------------------------- /anycode/server/src/common/util/lruMap.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | // ghetto LRU that utilizes the fact that Map keeps things in insertion order 7 | export class LRUMap extends Map { 8 | 9 | constructor(private readonly _options: { size: number, dispose: (entries: [K, V][]) => void }) { 10 | super(); 11 | } 12 | 13 | set(key: K, value: V) { 14 | super.set(key, value); 15 | this._checkSize(); 16 | return this; 17 | } 18 | 19 | get(key: K): V | undefined { 20 | if (!this.has(key)) { 21 | return undefined; 22 | } 23 | const result = super.get(key); 24 | this.delete(key); 25 | this.set(key, result!); 26 | return result; 27 | } 28 | 29 | private _checkSize(): void { 30 | setTimeout(() => { 31 | 32 | const slack = Math.ceil(this._options.size * .3); 33 | 34 | if (this.size < this._options.size + slack) { 35 | return; 36 | } 37 | const result = Array.from(this.entries()).slice(0, slack); 38 | for (let [key] of result) { 39 | this.delete(key); 40 | } 41 | this._options.dispose(result); 42 | }, 0); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /anycode/server/src/common/util/trie.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | 7 | class Entry { 8 | constructor(readonly key: string, public value: E) { } 9 | } 10 | 11 | export interface ReadonlyTrie { 12 | size: number; 13 | get(str: string): E | undefined; 14 | query(str: string[]): IterableIterator<[string, E]>; 15 | [Symbol.iterator](): IterableIterator<[string, E]>; 16 | } 17 | 18 | export class Trie implements ReadonlyTrie { 19 | 20 | static create(): Trie { 21 | return new Trie('', undefined); 22 | } 23 | 24 | private _size: number = 0; 25 | private _depth: number = 0; 26 | private readonly _children = new Map>(); 27 | 28 | private constructor(readonly ch: string, public element: Entry | undefined) { } 29 | 30 | get size() { 31 | return this._size; 32 | } 33 | 34 | get depth() { 35 | return this._depth; 36 | } 37 | 38 | set(str: string, element: E): void { 39 | let chars = Array.from(str); 40 | let node: Trie = this; 41 | for (let pos = 0; pos < chars.length; pos++) { 42 | node._depth = Math.max(chars.length - pos, node._depth); 43 | const ch = chars[pos]; 44 | let child = node._children.get(ch); 45 | if (!child) { 46 | child = new Trie(ch, undefined); 47 | node._children.set(ch, child); 48 | } 49 | node = child; 50 | } 51 | if (!node.element) { 52 | this._size += 1; 53 | node.element = new Entry(str, element); 54 | } else { 55 | node.element.value = element; 56 | } 57 | } 58 | 59 | get(str: string): E | undefined { 60 | let chars = Array.from(str); 61 | let node: Trie = this; 62 | for (let pos = 0; pos < chars.length; pos++) { 63 | const ch = chars[pos]; 64 | let child = node._children.get(ch); 65 | if (!child) { 66 | return undefined; 67 | } 68 | node = child; 69 | } 70 | return node.element?.value; 71 | } 72 | 73 | delete(str: string): boolean { 74 | let chars = Array.from(str); 75 | let node: Trie = this; 76 | let path: [string, Trie][] = []; 77 | for (let pos = 0; pos < chars.length; pos++) { 78 | const ch = chars[pos]; 79 | let child = node._children.get(ch); 80 | if (!child) { 81 | return false; 82 | } 83 | path.push([ch, node]); 84 | node = child; 85 | } 86 | 87 | if (!node.element) { 88 | return false; 89 | } 90 | 91 | // unset element 92 | node.element = undefined; 93 | this._size -= 1; 94 | 95 | // cleanup parents and update depths 96 | while (path.length > 0) { 97 | // parent 98 | const [nodeCh, parent] = path.pop()!; 99 | if (node._children.size === 0 && !node.element) { 100 | parent._children.delete(nodeCh); 101 | } 102 | node = parent; 103 | 104 | if (node._children.size === 0) { 105 | node._depth = 0; 106 | } else { 107 | let newDepth = 0; 108 | for (let child of node._children.values()) { 109 | newDepth = Math.max(newDepth, child.depth); 110 | } 111 | node._depth = 1 + newDepth; 112 | } 113 | } 114 | 115 | return true; 116 | } 117 | 118 | *query(str: string[]): IterableIterator<[string, E]> { 119 | 120 | const bucket = new Set>(); 121 | const cache = new Map, Map>(); 122 | 123 | const _query = (node: Trie, str: string[], pos: number, skipped: number, lastCh: string) => { 124 | 125 | if (bucket.has(node)) { 126 | return; 127 | } 128 | 129 | if (skipped > 12) { 130 | return; 131 | } 132 | 133 | const map = cache.get(node); 134 | if (map?.get(pos)) { 135 | return; 136 | } 137 | 138 | if (map) { 139 | map.set(pos, true); 140 | } else { 141 | cache.set(node, new Map([[pos, true]])); 142 | } 143 | 144 | if (pos >= str.length) { 145 | // till 'node' all characters have matched 146 | bucket.add(node); 147 | return; 148 | } 149 | 150 | if (str.length - pos > node._depth) { 151 | // there is more characters left than there are nodes 152 | return; 153 | } 154 | 155 | // match & recurse 156 | for (let [ch, child] of node._children) { 157 | if (ch.toLowerCase() === str[pos].toLowerCase()) { 158 | // consume query character if 159 | _query(child, str, pos + 1, skipped, ch); 160 | } 161 | _query(child, str, pos, skipped + 1, ch); 162 | } 163 | }; 164 | 165 | _query(this, str, 0, 0, this.ch); 166 | 167 | for (let item of bucket) { 168 | yield* item; 169 | } 170 | } 171 | 172 | *[Symbol.iterator](): IterableIterator<[string, E]> { 173 | const stack: Trie[] = [this]; 174 | while (stack.length > 0) { 175 | const node = stack.shift()!; 176 | if (node.element) { 177 | yield [node.element.key, node.element.value]; 178 | } 179 | for (let child of node._children.values()) { 180 | stack.push(child); 181 | } 182 | } 183 | } 184 | } 185 | -------------------------------------------------------------------------------- /anycode/server/src/node/main.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | import { createConnection } from 'vscode-languageserver/node'; 7 | import { SymbolInfoStorage } from '../common/features/symbolIndex'; 8 | import { IStorageFactory, startServer } from '../common/server'; 9 | import { FileSymbolStorage } from './storage'; 10 | 11 | process.on('unhandledRejection', (e: any) => { 12 | connection.console.error(`Unhandled exception`); 13 | connection.console.error(e); 14 | }); 15 | 16 | const connection = createConnection(); 17 | 18 | const factory: IStorageFactory = { 19 | async create(name) { 20 | return new FileSymbolStorage(connection); 21 | }, 22 | async destroy(obj: SymbolInfoStorage) { 23 | if (obj instanceof FileSymbolStorage) { 24 | obj.flush(); 25 | } 26 | } 27 | }; 28 | 29 | startServer(connection, factory); 30 | -------------------------------------------------------------------------------- /anycode/server/src/node/storage.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | import { Connection, SymbolKind } from "vscode-languageserver"; 7 | import { SymbolInfoStorage, SymbolInfo } from "../common/features/symbolIndex"; 8 | 9 | export class FileSymbolStorage implements SymbolInfoStorage { 10 | 11 | private readonly _data = new Map>(); 12 | 13 | constructor(private readonly _connection: Connection) { } 14 | 15 | insert(uri: string, info: Map): void { 16 | const flatInfo: Array = []; 17 | for (let [word, i] of info) { 18 | flatInfo.push(word); 19 | flatInfo.push(i.definitions.size); 20 | flatInfo.push(...i.definitions); 21 | flatInfo.push(...i.usages); 22 | } 23 | this._data.set(uri, flatInfo); 24 | this._saveSoon(); 25 | } 26 | 27 | async delete(uris: Set): Promise { 28 | for (const uri of uris) { 29 | this._data.delete(uri); 30 | } 31 | this._saveSoon(); 32 | } 33 | 34 | private _saveTimer: number | undefined | any; 35 | 36 | private _saveSoon() { 37 | clearTimeout(this._saveTimer); 38 | this._saveTimer = setTimeout(() => { this.flush(); }, 50); 39 | } 40 | 41 | flush() { 42 | const raw = JSON.stringify(Array.from(this._data.entries())); 43 | this._connection.sendRequest('persisted/write', raw).catch(err => console.error(err)); 44 | } 45 | 46 | async getAll(): Promise>> { 47 | 48 | this._data.clear(); 49 | 50 | const result = new Map>(); 51 | try { 52 | const raw = await this._connection.sendRequest('persisted/read'); 53 | const data = <[string, Array][]>JSON.parse(raw); 54 | 55 | for (let [uri, flatInfo] of data) { 56 | this._data.set(uri, flatInfo); 57 | const info = new Map(); 58 | result.set(uri, info); 59 | for (let i = 0; i < flatInfo.length;) { 60 | let word = (flatInfo[i]); 61 | let defLen = (flatInfo[++i]); 62 | let kindStart = ++i; 63 | 64 | for (; i < flatInfo.length && typeof flatInfo[i] === 'number'; i++) { ; } 65 | 66 | info.set(word, { 67 | definitions: new Set(flatInfo.slice(kindStart, kindStart + defLen)), 68 | usages: new Set(flatInfo.slice(kindStart + defLen, i)) 69 | }); 70 | } 71 | } 72 | } catch (err) { 73 | console.error(err); 74 | } 75 | return result; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /anycode/server/tsconfig.browser.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.base.json", 3 | "compilerOptions": { 4 | "lib": [ 5 | "ES2020", 6 | "WebWorker" 7 | ] 8 | }, 9 | "include": [ 10 | "src/common/*", 11 | "src/browser/*", 12 | "../shared/common/*" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /anycode/server/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.base.json", 3 | "compilerOptions": { 4 | "lib": [ 5 | "ES2020" 6 | ] 7 | }, 8 | "include": [ 9 | "src/common/*", 10 | "src/node/*", 11 | "../shared/common/*" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /anycode/shared/common/base64.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | 7 | // FROM https://github.com/microsoft/vscode/blob/559e9beea981b47ffd76d90158ccccafef663324/src/vs/base/common/buffer.ts#L288-L289 8 | 9 | const base64Alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; 10 | const base64UrlSafeAlphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'; 11 | 12 | export function encodeBase64(buffer: Uint8Array, padded = true, urlSafe = false) { 13 | const dictionary = urlSafe ? base64UrlSafeAlphabet : base64Alphabet; 14 | let output = ''; 15 | 16 | const remainder = buffer.byteLength % 3; 17 | 18 | let i = 0; 19 | for (; i < buffer.byteLength - remainder; i += 3) { 20 | const a = buffer[i + 0]; 21 | const b = buffer[i + 1]; 22 | const c = buffer[i + 2]; 23 | 24 | output += dictionary[a >>> 2]; 25 | output += dictionary[(a << 4 | b >>> 4) & 0b111111]; 26 | output += dictionary[(b << 2 | c >>> 6) & 0b111111]; 27 | output += dictionary[c & 0b111111]; 28 | } 29 | 30 | if (remainder === 1) { 31 | const a = buffer[i + 0]; 32 | output += dictionary[a >>> 2]; 33 | output += dictionary[(a << 4) & 0b111111]; 34 | if (padded) { output += '=='; } 35 | } else if (remainder === 2) { 36 | const a = buffer[i + 0]; 37 | const b = buffer[i + 1]; 38 | output += dictionary[a >>> 2]; 39 | output += dictionary[(a << 4 | b >>> 4) & 0b111111]; 40 | output += dictionary[(b << 2) & 0b111111]; 41 | if (padded) { output += '='; } 42 | } 43 | 44 | return output; 45 | } 46 | 47 | export function decodeBase64(encoded: string) { 48 | let building = 0; 49 | let remainder = 0; 50 | let bufi = 0; 51 | 52 | // The simpler way to do this is `Uint8Array.from(atob(str), c => c.charCodeAt(0))`, 53 | // but that's about 10-20x slower than this function in current Chromium versions. 54 | 55 | const buffer = new Uint8Array(Math.floor(encoded.length / 4 * 3)); 56 | const append = (value: number) => { 57 | switch (remainder) { 58 | case 3: 59 | buffer[bufi++] = building | value; 60 | remainder = 0; 61 | break; 62 | case 2: 63 | buffer[bufi++] = building | (value >>> 2); 64 | building = value << 6; 65 | remainder = 3; 66 | break; 67 | case 1: 68 | buffer[bufi++] = building | (value >>> 4); 69 | building = value << 4; 70 | remainder = 2; 71 | break; 72 | default: 73 | building = value << 2; 74 | remainder = 1; 75 | } 76 | }; 77 | 78 | for (let i = 0; i < encoded.length; i++) { 79 | const code = encoded.charCodeAt(i); 80 | // See https://datatracker.ietf.org/doc/html/rfc4648#section-4 81 | // This branchy code is about 3x faster than an indexOf on a base64 char string. 82 | if (code >= 65 && code <= 90) { 83 | append(code - 65); // A-Z starts ranges from char code 65 to 90 84 | } else if (code >= 97 && code <= 122) { 85 | append(code - 97 + 26); // a-z starts ranges from char code 97 to 122, starting at byte 26 86 | } else if (code >= 48 && code <= 57) { 87 | append(code - 48 + 52); // 0-9 starts ranges from char code 48 to 58, starting at byte 52 88 | } else if (code === 43 || code === 45) { 89 | append(62); // "+" or "-" for URLS 90 | } else if (code === 47 || code === 95) { 91 | append(63); // "/" or "_" for URLS 92 | } else if (code === 61) { 93 | break; // "=" 94 | } else { 95 | throw new SyntaxError(`Unexpected base64 character ${encoded[i]}`); 96 | } 97 | } 98 | 99 | const unpadded = bufi; 100 | while (remainder > 0) { 101 | append(0); 102 | } 103 | 104 | // slice is needed to account for overestimation due to padding 105 | return buffer.slice(0, unpadded); 106 | } 107 | -------------------------------------------------------------------------------- /anycode/shared/common/env.d.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | declare const performance: { now(): number } 7 | 8 | declare class TextEncoder { 9 | encode(value: string): Uint8Array; 10 | } 11 | declare class TextDecoder { 12 | decode(data: Uint8Array): string; 13 | } 14 | -------------------------------------------------------------------------------- /anycode/shared/common/initOptions.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | 7 | export interface Queries { 8 | readonly comments?: string; 9 | readonly folding?: string; 10 | readonly identifiers?: string; 11 | readonly locals?: string; 12 | readonly outline?: string; 13 | readonly references?: string; 14 | } 15 | 16 | export class LanguageInfo { 17 | constructor( 18 | readonly extensionId: string, 19 | readonly languageId: string, 20 | readonly suffixes: string[], 21 | readonly suppressedBy: string[], 22 | readonly queryInfo: Queries 23 | ) { } 24 | } 25 | 26 | export class Language { 27 | 28 | private _data?: Promise; 29 | 30 | constructor( 31 | readonly info: LanguageInfo, 32 | private readonly _loadData: () => Promise 33 | ) { } 34 | 35 | fetchLanguageData() { 36 | this._data ??= this._loadData(); 37 | return this._data; 38 | } 39 | } 40 | 41 | export class LanguageData { 42 | constructor( 43 | readonly grammarBase64: string, 44 | readonly queries: Queries, 45 | ) { } 46 | } 47 | 48 | export interface FeatureConfig { 49 | completions?: boolean; 50 | definitions?: boolean; 51 | references?: boolean; 52 | highlights?: boolean; 53 | outline?: boolean; 54 | folding?: boolean; 55 | workspaceSymbols?: boolean; 56 | diagnostics?: boolean; 57 | }; 58 | 59 | export type LanguageConfiguration = [LanguageInfo, FeatureConfig][]; 60 | 61 | export type InitOptions = { 62 | treeSitterWasmUri: string; 63 | supportedLanguages: LanguageConfiguration, 64 | databaseName: string; 65 | }; 66 | -------------------------------------------------------------------------------- /anycode/shared/common/messages.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | export const enum CustomMessages { 7 | QueueInit = 'queue/init', 8 | QueueUnleash = 'queue/unleash', 9 | FileRead = 'file/read', 10 | } 11 | -------------------------------------------------------------------------------- /anycode/tsconfig.base.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "noEmit": true, 4 | "target": "ES2020", 5 | "lib": [ 6 | "ES2021", 7 | ], 8 | "esModuleInterop": true, 9 | "module": "commonjs", 10 | "moduleResolution": "node", 11 | "sourceMap": false, 12 | "strict": true, 13 | "skipLibCheck": true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /anycode/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { 5 | "path": "./client/tsconfig.node.json" 6 | }, 7 | { 8 | "path": "./server/tsconfig.node.json" 9 | }, 10 | { 11 | "path": "./client/tsconfig.browser.json" 12 | }, 13 | { 14 | "path": "./server/tsconfig.browser.json" 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /scripts/all-npm.js: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | const fs = require('fs') 7 | const path = require('path') 8 | const cp = require('child_process') 9 | 10 | const newArgv = process.argv.slice(2).join(' ') 11 | 12 | function runNpm(folder) { 13 | console.log(`RUNNING \`npm ${newArgv}\` for ${folder}`) 14 | cp.execSync(`npm ${newArgv}`, { cwd: folder, stdio: 'inherit' }) 15 | } 16 | 17 | const root = path.join(__dirname, '../'); 18 | 19 | runNpm(path.join(root, 'anycode')) 20 | runNpm(path.join(root, 'anycode/client')) 21 | runNpm(path.join(root, 'anycode/server')) 22 | 23 | for (let name of fs.readdirSync(root)) { 24 | if (name.startsWith('anycode-')) { 25 | runNpm(path.join(root, name)) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /scripts/version-tag.js: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | // CREATES A GIT TAG FROM THE CURRENT VERSION FOR A GIVEN FOLDER. THIS SHOULD ON 'MAIN' 7 | 8 | const fs = require('fs') 9 | const path = require('path') 10 | const cp = require('child_process') 11 | 12 | const name = process.argv[2]; 13 | const folder = path.join(__dirname, '..', name); 14 | const packageJsonPath = path.join(folder, 'package.json'); 15 | 16 | const data = JSON.parse(fs.readFileSync(packageJsonPath).toString()) 17 | const { version } = data; 18 | 19 | const tagName = `${name}.v${version}`; 20 | cp.execSync(`git tag ${tagName}`, { cwd: folder, stdio: 'inherit' }); 21 | 22 | console.log(`DONE, tagName: ${tagName}`) 23 | -------------------------------------------------------------------------------- /scripts/version-up.js: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | // BUMPS THE VERSION FOR A GIVEN FOLDER. THIS SHOULD ON A TOPIC BRANCH 7 | 8 | const fs = require('fs') 9 | const path = require('path') 10 | const cp = require('child_process') 11 | 12 | const name = process.argv[2]; 13 | const newVersion = process.argv[3] || 'patch' 14 | const folder = path.join(__dirname, '..', name); 15 | const packageJsonPath = path.join(folder, 'package.json'); 16 | 17 | if (!fs.existsSync(folder) || !fs.existsSync(packageJsonPath)) { 18 | console.log(`INVALID extension name ${name} or no package.json-file`); 19 | process.exit(1); 20 | } 21 | 22 | if (!new Set(['major', 'minor', 'patch']).has(newVersion)) { 23 | console.log(`INVALID version ${newVersion}`); 24 | process.exit(1); 25 | } 26 | 27 | console.log(`TAGGING new version for ${name}`); 28 | cp.execSync(`npm --no-git-tag-version version ${newVersion}`, { cwd: folder, stdio: 'inherit' }) 29 | 30 | const data = JSON.parse(fs.readFileSync(packageJsonPath).toString()) 31 | const { version } = data; 32 | 33 | // const tagName = `${name}.v${version}`; 34 | // cp.execSync(`git tag ${tagName}`, { cwd: folder, stdio: 'inherit' }); 35 | cp.execSync(`git commit -a -m "Update ${name} to ${version}"`, { cwd: folder, stdio: 'inherit' }); 36 | 37 | 38 | console.log(`DONE, version: ${version}`) 39 | --------------------------------------------------------------------------------